1

たとえば、Foo と Bar という 2 つのクラスがあります。このクラスはいくつかのテーブルにマップされます。

今のところ、クラスごとに静的メソッドがあります: Add、Update、Delete、Get。

E.g.: 

public class Foo
{
   private Guid _id;
   private string _someProperty;

   static Foo Get(Guid id);
   static void Add(Foo foo);
   static void Update(Foo foo);
   static void Delete(Foo foo);
}

したがって、オブジェクトをうまく処理する必要がある場合は、次のように言います。

Foo foo = Foo.Get(id);

Foo newfoo = new Foo();
Foo.Add(newfoo);

Foo.Update(newfoo);

Foo.Delete(newfoo);

それは良いアプローチですか?そうでない場合、データにアクセスするにはどのような方法を使用すればよいですか?

ありがとう

4

3 に答える 3

8

あなたがしていることは、基本的にActive Recordパターンの実装です。多くの人が使用しており、完全に有効なアプローチです。ただし、アプリケーションが非常に複雑な場合、または懸念事項の分離にこだわりがある場合は、次の情報が役立つことがあります。

DDD (ドメイン駆動設計) アプローチをお勧めします。DDD は、いわゆるリポジトリ パターンを使用します。DDD は、アプリケーションとその関連事項を「モデル/ドメイン」、「インフラストラクチャ」、「サービス」という異なるレイヤーに分離します。

リポジトリは、インフラストラクチャ レイヤー内に属するパターンです。CustomerまたはEmployer(またはMonsterおよび)のようなビジネス オブジェクトWeaponはモデル レイヤー内にあり、(モデル化しようとしている) 「ドメイン」のコアを表し、ビジネス ロジックも担当します。サービス レイヤーを使用して、複数のモデルにまたがるアクティビティを簡素化し、調整することができます。

各ドメイン モデル (たとえば、クラス Foo と Bar) には、データベース アクセスを処理するリポジトリがあります。これにより、データベース呼び出しとモデルが分離されます。

public interface IFooRepository
{
     Foo Get(Guid guid);
}

public class FooRepository : IFooRepository
{
     public Foo Get(Guid guid)
     {
         //... DB voodoo magic happening
         return foo;
     }
}

IRepository<T>リポジトリのボイラーコードを常に書くのにうんざりしている場合は、ジェネリックを作成することもできます。

このアプローチは非常にうまく機能するため、依存性注入/制御の反転も検討する必要があります。

このアプローチの利点は、IFooRepository から派生した新しいクラスを簡単に実装できることです。これにより、データベース インフラストラクチャの変更にすばやく適応できます。たとえば、XML ファイルからデータを読み取る FooRepository や、NHibernate を使用して Postgres db から読み取る FooRepository を作成できます。

DDD に関するthisthis、およびthis の記事も読むことができます。

于 2009-08-18T07:10:55.757 に答える
1

それは常に、作成しているソフトウェアの種類によって異なります。

個人的には、エンティティ自体がデータ アクセスを行うのは好きではありません。エンティティは、そのフィールドとプロパティを管理する責任があるだけであり、それ以上のことを行うべきではありません。

私が取り組んでいる非常に大規模なエンタープライズ ソフトウェアでは、すべての NH アクセスを別のアセンブリに入れています。HQL やその他の特定のものは、ビジネス ロジックに属しません。これにより、単体テストも容易になります。CodeProject で説明されている同様のアーキテクチャがあり、読む価値があります。

NH を使用すると非常に簡単で、同じコードを何度も記述する必要がないため、任意のエンティティを挿入、削除、および更新できる一般的なメソッドがいくつかあるのが好きです。例えば:

void Store(object entity);
void Delete(object entity);
T Get<T>(object id);
IList<T> GetAll<T>();
void Lock(object entity);

特定のインターフェイスの追加の特定のメソッド。たとえば、次のとおりです。

IList<Product> GetProductsWithAttribute(string attributeName, string attributeValue);
于 2009-08-18T07:10:39.580 に答える
0

大規模なアプリケーションを作成している場合は、Kitsune の言うことが最善の方法です。

それがクラスの小さなセット (たとえば 5 つ未満) であり、巨大なエンタープライズ アプリケーションにならない場合は、このNHibernate クエリ ヘルパー(shameless plug)または Codesmith がNHibernate クラスを生成する方法を見ることができます。

最初のリンクでは、オブジェクトがデータを保持し、ビジネス ルールの検証を実行するだけです。たとえば、 というメソッドがありIsValidEmail()ます。次に、クエリ マネージャを使用して、作成、読み取り、更新、削除のタスクを実行します次に示します

NHibernateManager<User> manager = new NHibernateManager<User>();
User name = manager.ReadFirst();

// All items filtered (using OR)
IList<User> list = manager.OrList("@Name", "12345", "@Name", "54321");

// Paged
list = manager.Page(1,10);

CodeSmith テンプレートはこれよりも高度ですが、同様の原理で機能します。彼らはあなたをNHibernateセッションにさらします。

あなたが行った ActiveRecord パターンも完全に優れており、ドメイン駆動の純粋主義者だけが軽蔑するでしょう。唯一の問題は、User、Contact などのオブジェクトが NHibernate のクエリとセッションを担当することですが、逆に言えば、オブジェクトはうまく自己完結しています。

2 つ (リポジトリ パターンを含める場合は 3 つ) の方法のうち、どれを使用したいですか? 最終的に、どれが最も速く、プロジェクトに最も適しているでしょうか?

于 2009-08-18T09:00:38.810 に答える