2012-04-11 12 views
27

MorphiaやHibernateなどの永続性フレームワークは、ドメインオブジェクトのアノテーションに依存して魔法を実行することに気付きました。あるレベルでは、これは、永続性の懸念を、私たちが避けようとしているものであるドメイン層に挿入しているようです。ドメインオブジェクトの永続アノテーションは悪い習慣ですか?

これは、おそらく外部設定ファイルを使用して回避するか、ドメインモデルからDTOを分離する必要がありますか?または、一般的に許容可能と見なされるパーシスタンス層とドメイン層の間にこのわずかなリークがありますか?

+2

このプレゼンテーションを参照してください。http://www.infoq.com/presentations/Clean-Model-Tim-McCarthy – MikeSW

+0

ありがとう、これは素晴らしいプレゼンテーションになります!今すぐ見る... – HolySamosa

答えて

12

SpringとHibernateを使用している既存のシステムでの私の最新の反復で、私は同様の問題で動いてきました。最初にHibernateモデルを実装するとき、私はサービスクラスのアプリケーションロジックをデータアクセスオブジェクトを介して永続ロジックから分離するように努めました。昨年、新しいシステムを構築するとき、永続オブジェクトのほとんどがドメインオブジェクトとして機能することができました。これは、それが便宜的な解決策だったからです。

しかし、私はビジネス要件の変化に鑑みて、この同じシステムを再設計していますが、私は再びこれらの懸念事項を分離する方向に傾いています。私は新しいデザインに数日しかかかりませんが、インメモリの懸念オブジェクトを表す1つのオブジェクトと、別のパーシスタンスベースのオブジェクトを使用してその状態の変更をデータベースに保存することを好みました。たとえば、私は永続性のためにLeadを持っていて、トランザクションにまたがって並列のActiveLeadを持っています。

私はまだこれが最善の方法であるとは確信していませんが、腸のレベルでは意味があります。私は永続性にとらわれないコレクションを持てることを切望していました - 永続性 - 無知 - 標準のCRUDの簡素化に関係なく、データベーストランザクション全体にわたってメモリ常駐のオブジェクトのセット。しかし、私は最終的にすべてのデータベース操作がCRUDとして実装されていることを理解しています。 2つの世界は衝突しなければならず、そのトリックは彼らを調和させて踊っている。

ドメインオブジェクトのHibernate注釈?これは、実装の容易さとメンテナンスの容易さとの間の優れた妥協点です。

+2

これはまた、あなたの永続化オブジェクトの状態とメモリ内の状態の厳密さが厳しく/厳しくなくなる機会を与えます。私はインターフェイスからの入力と出力を非常によく理解して、このような問題をこのように分離しようとしています。 – alexwen

4

私の意見では、ドメインオブジェクトを複製してパーシスタンスレイヤーから分離する必要はありません。これは、手元で重複したコードを動作させ、DTOと同じオブジェクトを使用することによって完全に実行可能です。必要に応じて、必要に応じて別のクラスを使用することもできますが、私はそれを経験則にはしません。時間がかかり、時間が貴重です。

+3

私は同意しません。ドメインオブジェクトはその性質上、パーシスタンスモデルオブジェクトとは異なり、目的が異なります。時にはドメインが本当にあまりdominではなく、永続エンティティを直接使用することができれば、それは簡単な偶然の実装の詳細です。アイデアは、永続性をすべて無視して、ドメインのモデリングを開始することです。最近、私はこの状況について正確にブログしました。http://www.sapiensworks.com/blog/post/2012/04/07/Just-Stop-It!-The-Domain-Model-Is-Not-The-Persistence-Model。 aspx – MikeSW

+0

@MikeSW私の経験上、ドメインオブジェクトとテーブルはそれほど違いはありません。表示される相違点は、ORMのカスタマイズオプションを使用して翻訳するだけの簡単なものでなければなりません。私の意見では、良いORMはこれを簡単にするのに役立つはずです。 – Timo

+0

@MikeSWと彼のブログ記事に完全に同意します。たとえば、ORMのニーズを満たすためにドメインモデルで醜いgetters/setterを使用するよう強制されたくありません。永続化の世界の制約を受けずに私のドメインモデルを恥ずかしがるようにしたい。 – Mik378

7

私は最近、別々のパーシスタンスレイヤーを持っている合理的に複雑なシステムで作業しました。それはお尻に大きな痛みをもたらし、メンテナンス性には非常に悪いものでした。基本的にはYAGNIの原則と単一責任の原則の間に矛盾があります。私の意見では、YAGNIはより重要なものです(悲しいかな、無視されることも多い)。

あなたは異なった構造化するために永続性エンティティを強制具体的な要件(もし彼らが持っていない限り、私は、あなたがORMを使用している場合はほとんどの場合で、それが直接のドメインオブジェクトを永続化するためにはるかに良いかなと思いますまったく同じ構造を持っていますが、象牙の塔の議論以外にはそれらを分ける理由はありません)。

常には、別個のサービス/ DAO層で実際の永続性のもの(呼び出し元のORM関数)を実行します。そうすることで、必要になった場合に後で永続レイヤを導入するのは簡単です。

+1

同じオブジェクトを使用して問題が発生するケースは、複数のスレッド/サーバーからの楽観的なロックです。たとえば、 'firstName'への変更を保存しようとしたときに、他の誰かがオブジェクトを変更したことが判明した場合は、オブジェクトをリロードして変更を加える必要があります。新しく読み込まれ、変更されたオブジェクトをドメインオブジェクトのツリーにどのように戻すのですか? –

+2

投票した、私は同意しない。あまりにも多くの注釈を参照すると、多くの場合、クラス構造を異なる方向に強制する傾向があり、行動に加えて、クラスを読み込みや維持が難しくなりすぎる懸念が多すぎます。 – dalvarezmartinez1

+0

@dalvarezmartinez - 注釈がデータの永続性の問題だけでなく、ドメインの懸念事項に使用される場合はどうなりますか?例:ドメインオブジェクトの 'Name'プロパティを' [Required] 'とマークすると、フィールドが必須であることが明確になりますが、ヌル値を受け入れるべきでないことをバリデーション層のDB層に通知します。 – Sam

3

短い答え:私は、永続的で豊かなドメインオブジェクトが好きです。

長い答え:

私は春と休止状態を使用して〜500K LOCかなり大規模なシステムに取り組んで10年近く。当初、私たちはHibernateをあまり信頼していなかったため、「トランザクションスクリプト」(Fowler参照)アプローチから始めました。しかし、短期間で私たちはHibernateを信頼するようになりました。私はずっと前のOOでの以前のトレーニングのために、ドメイン駆動設計と組み合わせた一時的な永続性を大いに信じていました。我々は基本的に私たちのシステムをODBMS(小さな漏れがたくさんあります:-)で支えられていると考えるようになりました。

DDDという本はまだ書かれていないので私は私たちのアーキテクチャを「ドメインカーネル」と呼んだ。これはHibernateの初期の段階であったため、ドメインモデルはアノテーションで汚染されていませんでした。永続性の別個の懸念は、XMLマッピングでは別々に保たれました。

もう一度、時間の経過とともに、動作をドメインレイヤーにプッシュすることができました。私たちは、コンパイル時の依存関係で強制されていた、かなり伝統的なコントローラ - >サービス - >ドメイン - ドメイン階層化スキームを持っていました。私が時間をかけて観測したのは、このモデルが計画セットアップ、取引、会計、コンプライアンステスト、販売、ブランディングなど、401(k)計画管理の非常に複雑な領域のあらゆる側面を代表するシステムにとって非常にうまく機能していたことです。 (比較的)透明な「魔法の」持続性を持つ豊富なドメインモデルは、ドメインモデルの既存の機能に関して新しい機能を構築する上で重要でした。

私たちのサービス層は、テクニカルサービス(電子メール、ファイルI/O、キューイングなど)間のやりとりだけを調整し、必要に応じてドメインパッケージを拡張するのに役立ちました。サービス層はまた、(Springを介して)トランザクション境界を定義しました。サービスは受信したDTOまたはプリミティブのみを受信または送信しました。 DRYの中断として、多くの人がそれを嫌いますが、サービスインターフェイスとそれらを使用するコードを定義する際には正直な気がします。後で遠隔のものにも非常に簡単になりました。

このアプローチによって、かなり小さなチーム(私たちはスクラムチームでした)で高品質のソフトウェアを構築することができました。

私は永続的なドメインオブジェクトを信じていると考えています。私の話が助けてくれるかどうかわからないが、分かち合いたい。

9

ドメインオブジェクトのパーシスタンス注釈は悪い習慣ですか?

はいです。 NoSQLが登場すれば、単一永続化戦略に頼ることはできません。

例えば、今日私はMongoDBに私のドメインオブジェクトを固定しています。 明日明日ドメインオブジェクトをNeo4jに保存したいのですが?

または、ドメインオブジェクトをリレーショナル(Postgres/MySQL)、MongoDB(ドキュメントストア)、Neo4J(グラフデータベース)のような3種類のデータベースに永続させて評価することができます。役立つかもしれない戦略パターンとして永続戦略を渡す:すべてのこれらのケースでは

、より良いだけのドメインに依存すること

ベストプラクティスオブジェクトではなく、別の永続化戦略を持っています。しかし、クラス/オブジェクトを設計する際は注意が必要です。

+0

私はあまりにも多くの "何の場合..."の質問があると思います。私はデータベースを変更したり、単一のモジュールで3つの異なるdb技術を使用して、追加の戦略/マッパーなどを維持するコストを犠牲にする可能性のあるプロジェクトは見ていませんでした。私の経験上、プロジェクトには簡単に注釈を付ける代わりに、ドメイン層 – thilko

+0

@thilko私は、あなたが公正に言えば、実質的に言えば、と思う。それでも、これは、リポジトリパターン**との関連で永続性フレームワークを適用することを容易にする必要があると結論づけます**特にDDDおよび/またはTDDに関して。 – Timo

0

注釈が付いたリッチドメインオブジェクトが好きです。Evansでもこのアプローチを彼のsample appに使用しています。彼はAnnotationsの代わりにXMlを使うが、彼はまだ同じオブジェクトを残している。

ドメインと永続性を分離するのがよりクリーンかもしれませんが、将来的には異なるデータベーステクノロジを選択する可能性はありません。それは複雑さの地獄への道のりであり、ミスター・イーグニはあなたを噛むだろう。

4

私が使用する永続性フレームワークで既に決定されている場合は、私のドメインで注釈を使用すると思いますが、HexagonalアーキテクチャとTDDに従うとXMLがより便利になります。特定のフレームワークを先取りしてドメインに注釈を付けると、永続性の統合と結びつき、テクノロジ/フレームワークにとらわれないことを目指してコア機能をテストすることができなくなります。

関連する問題