3

依存性注入のガイドラインを自分で定義しようとしています。コンストラクターまたはセッター注入のいずれかを介して注入されるクラスの依存関係を定義する際に、適切な粒度はどうあるべきですか? クラスは、サービス、リポジトリなどである可能性があります。次のようなリポジトリ クラスがあるとします。

public class ProductRepository 
{
    //Option-A
    public ProductRepository(DataSource dataSource)
    {
    }

    //Option-B      
    public ProductRepository(SqlSession sqlSession)
    {
    }

    //Option-C
    public ProductRepository(SqlSessionTemplate sqlSessionTemplate)
    {
    }
}

上記のクラスに必要な最小限の依存関係は、DataSource インターフェイスです。リポジトリ クラスは、内部的に SqlSessionTemplate (SqlSession インターフェイスの実装) を使用します。コードに示されているように、コンストラクター インジェクションを実行するためのコンストラクターには 3 つの選択肢があります。以下は私の理解です:

Option-A (DataSource 依存関係) これは、リポジトリ クラスの最小の依存関係です。コンシューマーの観点からは、このコンストラクターは正しい選択ですが、リポジトリ実装の SqlSessionTemplate によって DataSource が内部的に消費されるため、単体テストの観点からは適切ではありません。

Options-B (SqlSession 依存) これは単体テストの観点からは正しい選択ですが、消費者の観点からはそうではありません。さらに、リポジトリの実装は、SqlSessionTemplate であるインターフェイスの特定の実装と密接に結合されています。したがって、コンシューマーが SqlSessionTemplate 以外の別の SqlSession インターフェイスを渡すと機能しません。

Options-C (SqlSessionTemplate の依存関係) SqlSessionTemplate が実装であり、インターフェイスではないことは、単体テストには適していないようです。また、SqlSessionTemplate のインスタンス化は DataSource と比較してより複雑であるため、消費者にとっては良くありません。したがって、このオプションを破棄します。

Option-A と Option-B が利用可能な選択肢のようです。ただし、消費者の視点と単体テストの視点の間にはトレードオフがあり、その逆もあります。

依存性注入は初めてです。DIの専門家にアドバイスを求めます。正しい解決策は何ですか(もしあれば)?上記の状況であなたはどうしますか?

ありがとう。

4

2 に答える 2

0

これは、リポジトリ クラスの最小の依存関係です。

これが適切な結合量を把握するための出発点だと思います。要件を満たすために必要な量を超えて注入する必要はありません。

これは非常に一般的なガイドラインであり、「依存する」とほぼ同じですが、それについて考え始めるには良い方法です。コンテキストで答えるには、DataSource、SqlSession、または SqlSessionTemplate について十分に知りません。

リポジトリ クラスは、内部で SqlSessionTemplate を使用します (SqlSession インターフェイスの実装)。

リポジトリがインターフェイスを依存関係として単純に使用できないのはなぜですか? インターフェイスは、実装のすべてのパブリック メソッドをカバーしていませんか? そうでない場合、インターフェイスは有用な抽象化でさえありますか?

あなたがやろうとしていることと依存関係がどのように機能するかを完全にまとめることはできませんが、私の最善の推測は次のいずれかです。

  1. コンストラクターを介して注入された SqlSession と DataSource の両方が必要です。
  2. リポジトリのコンストラクターを介して注入された SqlSession と、SqlSessionTemplate のコンストラクターに注入された DataSource が必要です。
于 2013-03-18T18:28:23.810 に答える
0

リポジトリの単体テストについて話していますが、リポジトリはデータベースへのゲートウェイであり、データベースと強力に結合しているため、通常はあまり役に立ちません。単体テストは分離して行う必要がありますが、リポジトリはデータベースでのみテストできます。したがって、統合テスト。

リポジトリからデータベース固有のロジックを抽象化できた場合 (あなたが行っているように)、リポジトリの責任はデータベースと通信することであるため、テストする必要はありません。そして、テストすることがまだたくさん残っている場合は、まあ...その場合、リポジトリクラスはおそらく単一責任の原則に違反しているため、リポジトリの保守が難しくなります。

したがって、通常はデータベースを使用してリポジトリ自体をテストするため、テストの観点からは、何を注入するかは問題ではありません。とにかくデータベースに接続できるようにリポジトリを構築する必要があるからです。

于 2013-03-19T09:12:28.690 に答える