web-dev-qa-db-ja.com

永続性の無知の利点は何ですか?

私はDDD + TDDの世界の初心者です。しかし、私はプログラミングに9年近く携わっています。

誰かが私に永続性の無知の利点を説明できますか?典型的なnHibernateアプリケーションは、クラスとデータベース間の依存関係をマッピングファイルにプッシュするだけです。

クラスファイルまたはデータベースを変更する場合は、マッピングファイルを変更する必要があります。では、抽象化レイヤーをもう1つ追加して、依存関係をプッシュするだけではありませんか?これまでの私の意見では、それは革命的なものではないと思います。しかし、何かが足りないのかどうかはわかりません。

最後に、マッピングファイルをテストするにはどうすればよいですか?マッピングファイルからバグが発生する可能性がありますが、どうすればテストできますか?

38
cbrcoder

これを例を挙げて説明しましょう。従来のSQLアプローチを使用してアプリケーションを実装していると仮定しましょう。レコードセットを開き、データを変更してコミットします。

擬似コード:

trx = connection.CreateTransaction();
query = connection.CreateQuery("Select * from Employee where id = empid");
resultset = query.Run();
resultset.SetValue("Address_Street", "Bahnhofstrasse");
resultset.SetValue("Address_City", "Zürich");
trx.Commit();

NHibernateを使用すると、次のようになります。

emp = session.Get<Employee>(empid);

// persistence ignorant 'logic'
emp.Address.Street = "Bahnhofstrasse";
emp.Address.City = "Zürich";

session.Commit();

永続性の無視とは、ビジネスロジック自体が永続性を認識しないことを意味します。つまり、永続性はロジックから分離されます。これにより、再利用性が大幅に向上します。

'logic'を再利用可能なメソッドに移動します。

void MoveToZuerichBahnhofstrasse(Employee emp)
{
  // doesn't have anything to do with persistence
  emp.Address.Street = "Bahnhofstrasse";
  emp.Address.City = "Zürich";
}

結果セットを使用してそのようなメソッドを書いてみてください。そうすれば、永続性の無知が何であるかがわかります。

確信が持てない場合は、永続性に関連するものへの依存関係がないため、単体テストがいかに簡単であるかを確認してください。

Employee emp = new Employee();
MovingService.MoveToZuerichBahnhofstreasse(emp);
Assert.AreEqual("Bahnhofstrasse", emp.Address.Street);
Assert.AreEqual("Zürich", emp.Address.City);

DDDは何か違うものです。そこで、最初にドメインモデル(クラスモデル)を構築し、それに応じてデータベース設計を作成します。 NHを使用すると、これは非常に簡単です。なぜなら、永続性の無知のおかげで、(決定的な)データベースモデルを作成する前に、モデルとロジックを記述して単体テストできるからです。


テスト:エンティティのインスタンスを作成し、データベースに保存し、取得して比較することにより、マッピングをテストしています。これは、多くの反射を伴って自動的に行われます。しかし、ここまで行く必要はありません。エンティティを保存しようとすると、一般的なエラーのほとんどが表示されます。

クエリでも同じことができます。複雑なクエリはテストに値します。クエリがコンパイルされると最も興味深いです。このためのデータも必要ありません。

データベース統合テストでは、 Sqlite を使用しています。これはかなり速いです。 NHは、SchemaExportを使用して(各テストの前に)その場でインメモリデータベースを作成します。

49

私は常にドメインの観点から考えてきました。以前はストアドプロシージャであるADO.NETを使用していましたが、永続化メカニズムに満足したのは、ついにNHibernateに移行したときだけです。

ドメイン駆動設計(DDD)は、ドメインモデルに真っ向から重点を置いています。これは、主な焦点が、ユーザーとプログラマーの両方に共通の言語を形成する概念モデルを作成することであることを意味します。ユーザーは、あなたがどのように情報を保持しているかにほとんど関心がありません。 NHibernateは、ビジネスルールをキャプチャし、ユーザーがシステムに本当に求めているものを理解することの二次的な懸念事項として永続性を作成することにより、この考え方を実現するのに役立ちます。

Fluent NHibernate ドメインモデルへの変更が基になるマッピングファイルに与える影響を軽減します。 自動マッピング もあります。システムの永続性を完全に無視することはできませんが、Fluent NHibernateを使用したNHibernateを使用すると、ドメインモデルに集中できます。リッチドメインモデルの使用に集中していない場合、NHibernateにはほとんどメリットがありません。

マッピングのテストに関しては、永続性を実装するためにどの方法を使用するかに関係なく、テストを作成することになります(または作成する必要があります)。これは、NHibernateを使用しているという理由だけで表示される余分な作業ではありません。マッピングのテストは、永続性が正しく機能することのテストと考えてください。

繰り返しますが、 Fluent NHibernate は非常に貴重です。 永続性仕様テスト があり、ほとんどの場合、非常に簡単に使用できます。

7
Praveen Angyan

PIはNHibernateを使用することではありません。 PIは、ドメインモデルの開発中にデータがどのように保存されるかを無視することを意味します。そして、はい、それはもう1つの抽象化レイヤーを追加することによって依存関係を推進しています。 DDDは革新的ではありません。それはアイデアのようなものであり、すでに馴染みのあるパターンを使用してコーディングする方法です(ほとんどはそうです)。つまり-ファクトリパターンまたはモジュールパターンも新しいものではありませんが、DDDの非常に重要な部分です。

私もごく最近NHibernateを使い始めたので、それについて多くの詳細を提供することはできません。しかし、私はあなたに役立つかもしれない1つのヒントを得ました-あなたがまだそれをしていないなら Fluent NHibernate を試してください。

2
Arnis Lapsa