web-dev-qa-db-ja.com

ORMを使用したDDDのビジネスロジックはどこにあるべきですか?

私は過去にMDA(モデル駆動型アーキテクチャ)ツールを使用しましたが、UMLを介してモデル化し、とりわけビジネスエンティティ(ドメインモデル)とORM(マッピングなど)を生成しました。

ドメインで動作するビジネスコードとサービスの多くはモデルの一部であり、リポジトリはビジネスエンティティを返していました(そのため、別のORMに切り替えることはできませんでした(望んでいなかった))。

しかし、今はプロジェクトを始めており、DDDについて考えたいと思います。

これまでのところ、自分のビジネスロジックをドメインモデルに入れ、リポジトリを介してORM(どちらを選択したか)で作業するように感じています。ただし、アプリケーションのORM部分にMDAツールを引き続き使用したい場合、ここで作成されたモデルは非常に貧弱です(つまり、ビジネスロジックが含まれていません)。同様に、ORMにエンティティフレームワーク(.net)またはNHibernateを使用した場合も、貧血モデルになります。 NHibernateをそのまま使用した場合、ビジネスロジックをどこに置くかわかりません。

私はこのように考えるのは正しいですか、つまりDDDではドメイン内のすべてのビジネスロジックを使用し、リポジトリ経由で永続化するためにORMを使用するだけですか?

10
JD01

したがって、別のORMに切り替えることは不可能でした(私たちが望んでいたことではありません))。

それは間違っているようです。リポジトリパターンの主な利点は、データアクセスロジックを非表示にし、簡単に交換できることです。

これまでのところ、自分のビジネスロジックをドメインモデルに入れ、リポジトリを介してORM(どちらを選択したか)で作業するように感じています。ただし、アプリケーションのORM部分にMDAツールを引き続き使用したい場合、ここで作成されたモデルは非常に貧弱です(つまり、ビジネスロジックが含まれていません)。同様に、ORMにエンティティフレームワーク(.net)またはNHibernateを使用した場合も、貧血モデルになります。 NHibernateをそのまま使用した場合、ビジネスロジックをどこに置くかわかりません。

貧血ドメインモデルは、マーティンファウラーなど、多くの人にとって悪い習慣と見なされています。このようなモデルは、オブジェクト指向の優れたデザインではなく、手続き型のデザイン手法につながるため、このようなデザインは避けてください。次に、データクラスとマネージャー/処理クラスがあり、状態と動作を分離します。しかし、オブジェクトは実際には「状態and動作」でなければなりません。

NHibernateは永続性の無知で素晴らしい仕事をします。 XMLまたはFluentNHibernateを使用してマッピングの詳細を非表示にして、単純なPOCOを記述することができます。 NHibernateを使用してリッチドメインモデルを作成するのは非常に簡単です。エンティティフレームワークとMDAツールでもそれができると思います。このツールが部分クラスを生成する限り、新しい世代がユーザー作成コードを破壊することを心配する必要なく、生成されたコードをかなり簡単に拡張できます。

この長い話を短くするために。 NHibernateを使用する場合、何もしませんnothingを繰り返すと、リッチドメインモデルを採用できなくなります。 FluentNHibernateで使用し、手動でマッピングすることをお勧めします。マッピングコードは、書き込みに5〜10分しかかかりません。エンティティフレームワークについても同じことが当てはまり、そのツールは少なくとも簡単に拡張できる部分クラスを作成すると思います。

私はこのように考えるのは正しいですか、つまりDDDではドメイン内のすべてのビジネスロジックを使用し、リポジトリ経由で永続化するためにORMを使用するだけですか?

ほとんどの場合、あなたは正しいです。リッチドメインモデルが必要です。特に、物事がますます複雑になると、適切に設計すると、保守や拡張が容易になります。ただし、DDDはビジネスロジックを実装する(ドメインレイヤーとアプリケーションレイヤー)サービス、および作成ロジックをカプセル化するファクトリーも認識していることに注意してください。

また、ビジネスロジックをドメインロジックと実際のアプリケーションビジネスロジックに区別する傾向があります。ドメインロジックは、ドメインがどのように相互作用して動作するかであり、アプリケーションロジックは完全に異なるレイヤーであり、特定のユースケース/アプリケーションでのドメインの使用方法をカプセル化します。多くの場合、特定のユースケースをサポートし、より強力にするために、ドメインモデルを更新する必要があります。

12
Falcon

ただし、アプリケーションのORM部分にMDAツールを引き続き使用したい場合、ここで作成されたモデルは非常に貧弱です(つまり、ビジネスロジックが含まれていません)。

使用しているMDAツールはわかりませんが、これまで使用したMDAツールでは常に部分クラスが作成されるため、必要なだけのビジネスロジックで自由に完了することができます。

ただし、MDAツールはORDよりもDDDコンテキストでは少し適切ではないと思います。コード生成は、期待される合理化された明確に表現されたドメインエンティティではなく、ツール固有のノイズで混乱したクラスを生成する傾向があるためです。実際、よく得られるのは、ドメインデータ、永続性ロジック、制約検証ロジックの組み合わせです...そして、ほとんどのMDAツールでこれらの懸念を分離する方法があるかどうかはわかりません。

そしてもちろん、部分クラスを除いて、生成されたコードを変更することはできません。つまり、統合される可能性のあるアンチDDD動作を排除することはできません。これは、アグリゲート間に厳密なバリアを適用し、エンティティ間の関係を完全に調整したいというアプローチでは問題になります。継続的インテグレーション環境でのビルド時間も、追加のコード生成ステップの影響を受ける可能性があります。

それとは別に、Falconはほとんどすべてを言っていると思います-ORMまたはMDAツールでは絶対に、リッチドメインエンティティを作成できません。

3
guillaume31

私のチームでは、オブジェクトとドメインをモデル化し、同時にビジネスロジックを追加しています。モデルからコードを生成するModel Driven Developmentは使用していませんが、アノテーションアプローチを好みます。つまり、クラス図内のオブジェクトレベルでORMステレオタイプを追加します。これにより、EJB3/hibernateと互換性のある永続アノテーションがコードに直接追加されます。データベースの作成はHibernateによって行われ、UMLテンプレートでは行われません。コードが変更され、追加されたアノテーションがHibernateスペシャリストのものと完全に一致しない場合、彼/彼女はそれを変更できますが、モデルは依然として良好であるため、これははるかに優れています。要件を変更することもできますが、ドメインモデルはまだ問題ありません。

開発者は各メソッド内にビジネスロジックを追加してコメントを追加できます。また、制約をモデル化して追加することもできます。たとえば、売上高は50k以上でなければならないなどです。コード化する必要はありませんが、モデルに書き込むだけで、この情報は開発者チームに表示されます。本当にクールで柔軟なUML。

1
UML_GURU