2

より大きなプロジェクトで使用するため、リポジトリとファクトリメソッドのパターンを一緒に理解するためのサンプル、アプリケーションを作成しています。

私が達成したいのは、Web サイトをさまざまな ORM ツールで動作させることができるようにすることです。

たとえば、Web サイトには LINQ to SQL および Ado エンティティ フレーム ワーク クラスが実装されており、ファクトリ メソッドを使用すると、これらの ORM の 1 つを「構成値を使用して」使用してリポジトリ オブジェクトにデータをロードします。

私が今まで得たものは次のようなものです

interface IRepository : IDisposable
{
  IQueryable GetAll();  
}

interface ICustomer : IRepository
{
}

public class CustomerLINQRepository : ICustomer
{
    public IQueryable GetAll()
    {
       // get all implementation using linqToSql
    }
    public void Dispose()
    {
      throw;
    }
    public IRepository GetObject()
    {
        return this;
    }
}


public class CustomerADORepository : ICustomer
{
    public IQueryable GetAll()
    {
       // get all implementation using ADO
    }
    public void Dispose()
    {
      throw new NotImplementedException();
    }
    public IRepository GetObject()
    {
        return this;
    }
}


// Filling a grid with data in a page
IRepository customers = GetCustomerObject();
this.GridView1.DataSource = customers.GetAll();
this.GridView1.DataBind();
////

public IRepository GetCustomerObject()
{
    return new CustomerLINQRepository(); // this will return object based on a config value later
}

しかし、デザインの間違いがたくさんあると感じています。より良いデザインを得るために、それを理解するのを手伝ってくれることを願っています.

4

3 に答える 3

4

私の2セント:

A. 一般的なベース リポジトリ クラスを追加します。タイプが何であれ、多くのリポジトリ アクションは同じです。多くの入力を節約できます。

B. リポジトリが ICustomer インターフェイスを実装している理由がわかりません。Data Objects のインターフェイスは良い方法ですが、リポジトリで実装する必要はないと思います。

C. データ オブジェクトに共通の実装がある場合、それらの基本クラスを作成し、リポジトリがその型の派生クラスでのみ機能するように制限します。

私はそのようなことをします:

public interface IEntity
{
     // Common to all Data Objects
}

public interface ICustomer : IEntity
{
     // Specific data for a customer
}


public interface IRepository<T, TID> : IDisposable where T : IEntity
{
     T Get(TID key);
     IList<T> GetAll();
     void Save (T entity);
     T Update (T entity);

     // Common data will be added here
}

public class Repository<T, TID> : IRepository<T, TID>
{
     // Implementation of the generic repository
}

public interface ICustomerRepository
{
     // Specific operations for the customers repository
}

public class CustomerRepository : Repository<ICustomer, int>, ICustomerRepository
{
     // Implementation of the specific customers repository
}

使用法:

CustomerRepository repository = new CustomerRepository();
IList<ICustomer> customers = repository.GetAll();
// Do whatever you want with the list of customers

これが、NHibernate を使用して DAL を実装した方法です。「NHibernate in Action」では、その使い方のひねりを見つけることができます。

Matt が提案したように、ある種の IOC コントローラーを使用することもお勧めします。

于 2009-09-29T05:21:01.340 に答える
1

ほとんどの部分でよさそうだ。私は2つのコメントがあります:

  1. 私はあなたの顧客リポジトリをICustomerとは呼びません。私はそれをICustomerRepositoryと呼びます。これはより簡単で、インターフェイスのリポジトリベースの責任を明確にします。ICustomerは、顧客データをカプセル化するDataObjectのように聞こえます。
  2. ファクトリメソッドを使用する代わりに、IOCコンテナ(Google構造マップ、Castle Windsor、またはUnity)の使用を検討してください。混乱を招く可能性のあるファクトリメソッドがたくさんあることになりかねません。代わりに、IOCがすべてのリポジトリを接続する場所をコード内に1つ配置する方がクリーンな場合があります。
于 2009-09-29T03:51:03.057 に答える
1

のネーミングについてはよくわかりませんGetWanted。あなたが得ていることは正確に何を望んでいますか?名前はもっとわかりやすいはずGetCustomerRepositoryですよね?

GetCustomerObjectと同じですかGetWanted

は何のthrowためですか?

于 2009-09-29T03:38:04.900 に答える