1

アプリケーションモデルを論理部分「データ」、「コマンド」、「エンジン」で分割したいと思います。アプリケーションの外部にいるすべての人は、データへの読み取り専用アクセスとコマンドへのアクセスを取得する必要があります。これらのコマンドを使用して、データを操作できます。

このうち、私は自分のアプリケーションをパッケージにまとめました。

myapp.model.data
myapp.model.commands
myapp.model.engines

エンジンとコマンドの両方に、データへの書き込みアクセスが必要です。したがって、パブリックインターフェイスの形式で書き込みアクセスを公開する必要があります。これにより、外部クライアントも私のデータへの書き込みアクセス権を持っているという問題が発生しますが、これは許可されません。これに伴う問題は、コマンドがイベントを使用してエンジンを呼び出し、データの整合性をチェックすることです。クライアントはエンジンを呼び出さずにデータを操作するため、データの一貫性が失われます。

この問題の一般的な慣習はありますか?今すぐアプリケーションを作成したいので、Java8まで待たなければならないことを提案しないでください。アプリケーションの概要が失われるため、すべてのクラスを1つのパッケージに入れることもできません。

編集

木やグラフの不変性についていくつかのサイトを読みました。私はジッパーと呼ばれる素晴らしいアイデアを見てきました:http ://scienceblogs.com/goodmath/2010/01/13/zippers-making-functional-upda/ 。残念ながら、これは私の場合はうまくいかないようです。

思い出してください、私は時間の経過とともに操作される複雑なオブジェクトグラフ構造を持っています。目標は、クライアントが私のコマンドだけでデータを操作するように制限することでした。したがって、私の場合、不変性の利点はわかりません。

このために、データクラスに2つのパブリックインターフェイスを読み取り専用と書き込み可能にします。クライアントが読み取り専用インスタンスでコマンドを呼び出すときはいつでも、書き込み可能インスタンスにキャストする必要があります。このアプローチは私の問題を解決しますが、2つの大きな欠点があります。まず、すべての読み取り専用インスタンスが同時に書き込み可能なインスタンスであると想定します。これにより、いくつかの醜いバグが発生する可能性があります。次に、クライアントは同じことを行い、書き込みアクセス権を持つことができます。しかし、私が言うことができるよりも、彼ら自身のせいです。

誰かより良いアイデアがありますか?

4

2 に答える 2

1

これはフォルダ(ツリーのような構造)の一般的な制限だと思います。ソリューション:

  1. ドキュメントデータにアクセスしないようにしてください(JavaDoc)。
  2. 極端に行きたい場合は、電話がどこから来ているかを確認し、それを拒否することができます(少しやり過ぎ)

ここに補足として、この主題に関するブログ投稿があります:パッケージ構造を根本的に改善するための簡単な提案

于 2013-02-27T09:54:53.060 に答える
1

このタイプの問題のために私が引っ張る3つのパターンがあります。私がそれらを試してみるおおよその順序で:

1)不変/副作用をなくします。関数型プログラミング言語で強く推奨されている手法であり、java.lang.Stringはその一例です。ここでは、単一のインスタンスは変更できず、mutateを呼び出すと新しいインスタンスが作成されます。コマンドやエンジンへのインターフェイスを設計した方法では機能しない場合がありますが、インターフェイスを再設計するエネルギーがある場合、これは非常に強力なアプローチであり、行数を減らす傾向があります。

2)ロック可能なオブジェクトパターン。オブジェクトは最初に作成されたときは変更可能ですが、共有される前に「ロック」されます。ロックされた後、ミューティングメソッドの呼び出しエラーが発生します。オブジェクトのロックを解除するには、オブジェクトの新しいコピーを作成する必要があります。

3)可変インスタンスの読み取り専用ラッパーを作成します。これにより、誰が変異できるのか、誰が読み取り専用になるのかを制御できます。java.util.Collections#unmodizableList(List list)は、このデコレータスタイルパターンのJavaランタイムの例であり、共有インターフェイスでセッターメソッドを保持します。セッターメソッドがまったくオンになっていない別のインターフェイスを使用できます。

私の好みは常に1です。これにより、コードが単純になり、スケーリングが容易になります。ただし、問題が発生した場合は、アプローチ間のバランスが取れており、別のスレッドが別のスレッドの背後にあるインスタンスを変更している可能性がないため、2にフォールバックする傾向があります。また、それほど多くの余分なコードは必要ありませんが、オブジェクトが正しくロックされていることを確認し、ロックのセマンティクスを適用するための規律が必要です。そのため、実際にはあまり一般的なパターンではありません。

于 2013-02-27T09:56:55.510 に答える