質問

この投稿 Greg Youngが、Microsoftがダムデータ転送オブジェクトを使用したパターンを推奨することについて話している。彼は、Javaコミュニティでは、物事は他の方向に向かっていると暗示しました。

私の質問は、エンティティオブジェクトにどのくらいのロジックが必要かということです。私が働いている私たちの哲学(C#ショップ)は、シリアル化できない場合はエンティティに入れないことです。

役に立ちましたか?

解決

マット、

あなたの店は手続きコードを書いていると思います。手続き型コードを使用して記述された多くの大規模システム(私が取り組んできた多くのシステムを含む)に問題はないことを明確にしたい時間と場所があります。

現在、手続き型コードはドメインモデル内に場所を持ちません。より良い手続き型のスタイルを使用したいが、Table ModuleやActive Recordパターンのようなもので使用したい場合。 OOが不足しているからといって、ガイダンスを破壊することを検討しているのではなく、手続き型ロジックを使用したドメインモデルの使用を検討しています。

これにより、ドメインレイヤー(通常は保守性)がもたらすメリットを享受することなく、ドメインレイヤーを構築するために大量のリソース(インピーダンスの不一致、集合体を構築するための思考プロセス時間、分離、ユビキタス言語など)を費やすことになります提供します。言い換えれば、機能的な要件を十分に満たすことができても、最終的にはほとんど収益を出さずに大量の予算を費やすことになります。

ここで<!> quot; is behavior <!> quot;に戻ります。 <!> quot; Domain Driven Design <!> quotではなく、Object Orientedからの質問に焦点を当てたいと思います。観点。通常、オブジェクトはいくつかの状態をカプセル化し、通常はいくつかの動作を公開します。

クイック反復:状態をカプセル化し、動作を公開します

では、オブジェクトにはどのような動作が必要ですか?簡単に言えば、カプセル化されている状態で動作する動作でなければなりません。理想的なビヘイビアOOの世界では、オブジェクトのみのビヘイビアから状態が公開されることはありません。次のようなコードが表示されるようになったら、コードに戦術を入れます。

Customer c = GetCustomerFromRepository();
c.Status = CustomerStatuses.Deleted;
c.LastUpdated = DateTime.Now;
c.UpdatedBy = GetCurrentUser();
CustomerRepository.Save(c);

SRP違反があります...このコードは、<!> quot; Responsibility <!> quot;顧客オブジェクトの

顧客に関する状態をカプセル化し、行動を公開します。

このように、Customer.Delete()メソッドを用意した方が良いことがわかります。 (はい、これは私が知っている悪い例です...)

ここで、TDDを使用してこれに到達します。すべての状態が公開されている継ぎ目よりも、ビヘイビアが提供する継ぎ目でテストを処理する方がはるかに簡単です。これは、テストでロジックを複製する必要がないためです。クライアントコードは、削除がどのように機能するかを気にしません ...顧客が動作を公開することだけを気にします。テストでは、c.State == CustomerStates.Deletedおよびc.UpdatedBy == GetCurrentUser()などをアサートする代わりに、モックを使用して顧客の継ぎ目でdeleteメソッドが呼び出されたことをアサートします。

タイトルに戻りましょう。ビジネスオブジェクト内にあるべきロジックの量は、その状態をカプセル化する責任に該当するロジックの量です。時々これは多く、時々そうではありません。サービスを使用したい場所もあります...良い例は、特定の動作のために多くのドメインオブジェクト間の相互作用を調整することですが、ここでもサービスはドメインオブジェクトの behaviors を呼び出す必要があります。

これは物事を少し明確にするのに役立ちますか?

グレッグ

他のヒント

それらを<!> quot;ドメインモデルオブジェクト<!> quot;と呼ぶ場合次に、ファウラーのドメインモデルパターンを参照していると仮定します。 http://martinfowler.com/eaaCatalog/domainModel.html

その仮定を考えると、質問に対する答えは<!> quot;すべてのビジネスロジック<!> quot;です。それは本質的にパターンの定義だからです。

残念ながら、<!> quot;ドメインモデル<!> quot;最近、行動のないデータのオブジェクトモデルのみを意味するように骨抜きにされたようです。

まだ行っていない場合は、PoEAAを読んで、ドメインロジックがあなたの状況に属すると思う場所を決めることをお勧めします。ドメインモデルを決定する場合は、EvanのDDDの本を読んで、エンティティ、値オブジェクト、サービスの違いについて学ぶことをお勧めします。

役立つことを願っています!

最近、私は特定の動作の拡張メソッドを使用して、構造とそのモデルに普遍的な動作(つまり、複数の境界のあるコンテキストで使用できる動作)のみを持つドメインモデルを作成するというアイデアをいじりました。制限されたコンテキスト。これにより、ドメインモデルをDTOの近くに保持し(そのようなモデルの場合)、そのドメインモデルの使用を制限されたコンテキスト内で許可された動作のみに制限します。したがって、これは道の途中の応答のオプションになる可能性があります。 :)

主なポイントは、ロジックの定義方法です。例を挙げます:

  1. Personエンティティ内の関数getFullName()を分類しません。これは、ロジックとして文字列を連結するだけです。
  2. 注文項目の値を計算すると、ロジックである可能性が高くなります。
  3. いくつかの予約取引を行うことは間違いなくロジックだと思います。

ポイント1と多分2がエンティティになります。ポイント3ではありません。そこで、ロジックを次のように定義します。

  • 永続性に関連することを行う操作(読み取り/書き込み)
  • 他の(直接関連していない、たとえばマスター詳細)エンティティを含む操作

IMO、これらの操作はいずれもエンティティに属しません。

今、なぜ/いつポイント1および2タイプの操作もエンティティに入れないのですか?かなりまれな状況ですが、エンティティに格納されたデータをアプリケーションで使用する前に何らかの方法で解釈する必要があるとすぐには、それを行いません(たとえば、現在のユーザー、フィールドXのコンテンツ意味が異なります)、つまりエンティティのデータ自体が何らかのロジックを生成することを意味します。

私が理解している限り、エンティティに関連するすべてのビジネスロジックはそのエンティティに入る必要があります。これは、システムのビジネスルールに基づいてエンティティの動作または内部構造を定義するロジックで構成されます。これには、プレゼンテーションロジックや永続化ロジック(Active Recordのデザインパターンに関する明白な例外)を含めるべきではありませんが、データ検証、エンティティリレーションシップ、ステートマシンなど、エンティティの実際の動作を定義するその他のものを含める必要があります。モデリングしようとしている世界的なもの。

私が見ようとする方法は、モデルを可能な限り再利用可能にすることです。クライアントコード(またはエンティティを使用するコード)が異なる可能性のある別のシステムに移植する場合、モデルの使用方法を常に考えてください。機能がエンティティの一部ではない場合、同じビジネスルールに従って同じように動作しますか?答えが「いいえ」の場合、機能はエンティティに組み込まれます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top