web-dev-qa-db-ja.com

リポジトリパターンとDAL

それらは同じものですか? Rob ConneryのStorefrontチュートリアル を視聴し終えたところ、それらは同様の技術のようです。つまり、DALオブジェクトを実装するとき、GetStuff、Add/Deleteなどのメソッドがあり、後でdbを切り替えることができるように、常に最初にインターフェイスを記述します。

私は物事を混乱させていますか?

91
Mike

あなたは間違いなく物事を混乱させる人ではありません。 :-)

質問に対する答えは、あなたがどれだけ純粋主義者になりたいかによって決まると思います。

厳密なDDDの視点が必要な場合は、1つの道を進みます。リポジトリを、サービスとデータベースを分離するレイヤーのインターフェースを標準化するのに役立ったパターンとして見ると、別のものをダウンさせるでしょう。

私の観点から見たリポジトリは、データへのアクセスの明確に指定されたレイヤーにすぎません。つまり、データアクセスレイヤーを実装する標準的な方法です。異なるリポジトリの実装にはいくつかの違いがありますが、概念は同じです。

リポジトリにより多くのDDD制約を課す人もいれば、データベースとサービス層の間の便利なメディエータとしてリポジトリを使用する人もいます。 DALのようなリポジトリは、サービスレイヤーをデータアクセスの詳細から分離します。

それらを異なっているように思われる1つの実装の問題は、仕様をとるメソッドでリポジトリがしばしば作成されることです。リポジトリは、その仕様を満たすデータを返します。私が見たほとんどの従来のDALには、メソッドが任意の数のパラメーターを受け取るメソッドの大きなセットがあります。これは小さな違いのように聞こえるかもしれませんが、LinqとExpressionsの領域に入ると大きな問題になります。デフォルトのリポジトリインターフェイスは次のようになります。

public interface IRepository : IDisposable
{
    T[] GetAll<T>();
    T[] GetAll<T>(Expression<Func<T, bool>> filter);
    T GetSingle<T>(Expression<Func<T, bool>> filter);
    T GetSingle<T>(Expression<Func<T, bool>> filter, List<Expression<Func<T, object>>> subSelectors);
    void Delete<T>(T entity);
    void Add<T>(T entity);
    int SaveChanges();
    DbTransaction BeginTransaction();
}

これはDALまたはリポジトリですか?この場合、私はその両方を推測します。

キム

86
Kim Major

リポジトリはさまざまな方法で適用できるパターンですが、データアクセス層には非常に明確な責任があります。DALはデータストレージに接続してCRUD操作を実行する方法を知っている必要があります。

リポジトリcanはDALですが、DALの前に置かれ、ビジネスオブジェクトレイヤーとデータレイヤー間のブリッジとして機能することもできます。どの実装が使用されるかは、プロジェクトごとに異なります。

41
Jeromy Irvine

大きな違いの1つは、DAOがドメイン内のエンティティの永続性を処理する一般的な方法であることです。一方、リポジトリは集約ルートのみを扱います。

23
pondermatic

私は同様の質問への答えを探していて、2つの最高ランクの答えに同意しました。これを自分で明確にしようとして、ifリポジトリパターンと連動する仕様がファーストクラスメンバとして実装されていることがわかりました。ドメインモデルの

  • reuse異なるパラメーターを使用した仕様定義、
  • manipulate既存の仕様インスタンスのパラメーター(特殊化など)、
  • combineそれら、
  • データベースにアクセスすることなくビジネスロジックを実行します
  • そして、もちろん、unit-testそれらは実際のリポジトリ実装とは無関係です。

私はこれまでのところ、nless RepositoryパターンがSpecificationパターンと一緒に使用されていると述べることもできます。これは実際には「Repository」ではなく、DALです。疑似コードの不自然な例:

specification100 = new AccountHasMoreOrdersThan(100)
specification200 = new AccountHasMoreOrdersThan(200)

assert that specification200.isSpecialCaseOf(specification100)

specificationAge = new AccountIsOlderThan('2000-01-01')

combinedSpec = new CompositeSpecification(
    SpecificationOperator.And, specification200, specificationAge)

for each account in Repository<Account>.GetAllSatisfying(combinedSpec)
    assert that account.Created < '2000-01-01'
    assert that account.Orders.Count > 200

詳細については、 Fowler's Specification Essay を参照してください(これが上記の根拠です)。

DALには、次のような特殊なメソッドがあります

IoCManager.InstanceFor<IAccountDAO>()
    .GetAccountsWithAtLeastOrdersAndCreatedBefore(200, '2000-01-01')

特にこのアプローチで各DAL/DAOインターフェースを定義する必要があるため、これがどのようにすぐに厄介になるかを見ることができますand DALクエリメソッドを実装します。

.NETでは、LINQクエリcanは仕様を実装する方法の1つですが、仕様(式)の組み合わせは自社開発のソリューションほどスムーズではありません。そのためのいくつかのアイデアは this SO Question で説明されています。

12
Thomas Jung

私の意見では、それはすべてマッピングに関するものです。 http://www.martinfowler.com/eaaCatalog/repository.html を参照してください。そのため、リポジトリからの出力/入力はドメインオブジェクトであり、DALでは何でもかまいません。私にとって、これは重要な追加/制限です。異なるレイアウトのデータベース/サービス/何でもリポジトリ実装を追加でき、マッピングを行うことに集中する明確な場所があります。その制限を使用せず、マッピングを別の場所に配置する場合、データを表すさまざまな方法があると、変更すべきではない場所のコードに影響を与える可能性があります。

2
eglasius

それはすべて解釈と文脈に関するものです。それらは非常に似ている場合も実際には非常に異なる場合もありますが、解決策が機能する限り、その名のとおりです!

1
c00ke

リポジトリパターンを使用する利点は、データアクセスレイヤーをモックすることです。これにより、DALコードを呼び出さずにビジネスレイヤーコードをテストできます。他にも大きな利点がありますが、これは私にとって非常に重要なことのようです。

1
Shailesh

リポジトリはパターンです。これは、できる限りコードを再利用するために標準化された方法で実装する方法です。

0
Xulfee

外部の世界(クライアントコード)では、リポジトリはDALと同じですが、次の点が異なります。

(1)insert/update/deleteメソッドは、パラメーターとしてデータコンテナーオブジェクトを持つように制限されています。

(2)読み取​​り操作には、DAL(たとえばGetByPK)などの単純な仕様または高度な仕様が必要になる場合があります。

内部的には、データマッパーレイヤー(たとえば、エンティティフレームワークコンテキストなど)と連携して、実際のCRUD操作を実行します。

リポジトリパターンが意味しないもの:-

また、挿入/更新/削除メソッドによって実行されたすべてのメモリ内の変更をデータベースにコミットする挿入/更新/削除メソッドに加えて、リポジトリパターンのサンプル実装として別のSaveメソッドがあると混乱することがよくあります。リポジトリにSaveメソッドを確実に含めることができますが、メモリ内のCUD(作成、更新、削除)および永続化メソッド(データベースで実際の書き込み/変更操作を実行する)を分離するのはリポジトリの責任ではありませんが、作業単位パターンの責任。

お役に立てれば!

0
Ashraf Alam

だから、ほとんどの(単純な)ケースでは、DAOはリポジトリの実装ですか?

私の知る限り、DAOはデータベースアクセス(CRUD-選択なし?)を正確に処理しているように見えますが、リポジトリを使用すると、データアクセス全体を抽象化できます。

私は正しい道にいますか?

0
Mike

私が理解していることから、それらは基本的に同じことを意味することができます-しかし、ネーミングはコンテキストに基づいて異なります。

たとえば、IRepositoryインターフェイスを実装するDal/Daoクラスがあるとします。

Dal/Daoはデータレイヤーの用語です。アプリケーションの上位層はリポジトリの観点から考えます。

0
remotefacade