パッシブ ビュー アーキテクチャのプレゼンター クラスの依存関係の作成はどこに配置すればよいですか?
-
21-08-2019 - |
質問
プレゼンター クラスから新しいドメイン クラスをリファクタリングしましたが、インスタンス化する場所がわかりません。
これは、メンテナンスが不十分なレガシー プロジェクトで進行中の大規模なリファクタリング作業の一部です。
現在、プレゼンターはビューの OnLoad イベントによって作成されており、ビューはコンストラクターのパラメーターとして渡されます。プレゼンターのすべてのパブリック メソッドはパラメーターなしで、void を返します。これらは、ビューのパブリック プロパティを使用してビューと通信します。
本質的に謙虚な形式であるこのビューは、すべてがプレゼンターに完全に依存します。
これは典型的なパッシブ ビュー パターンであり、今後もこれを遵守していきたいと思います。それが私をジレンマに陥らせます。プレゼンターが使用する新しいドメイン オブジェクトのインスタンスを作成する必要があります。
- コンストラクターを介して渡す場合、ビューはそれを作成する必要があり、不要な依存関係が得られます。
- プレゼンター内の任意の場所に作成した場合、単体テストでモック オブジェクトに置き換えることはできません。
- それをプレゼンターのパブリックプロパティにすると、それが使用されるプレゼンターメソッドに作成順序の依存関係が導入されますが、どの外部クラスがそれを作成する責任を負うのかはまだ解決していません。
現在、依存関係注入フレームワークは使用していません。将来的にこれを使用することに興味はありますが、サードパーティのフレームワークを導入するには、ソース コードがまだ脆弱です。
あらゆる提案を歓迎します。
解決 2
私は、はるかに簡単な解決策を見つけました。ここに私の元のクラスの例があります:
public Presenter(IView view)
{
this.View = view;
}
私は、コンストラクタの引数として私の新しい依存関係を渡したいが、同様に私の見解にこの依存関係を追加したくありませんでした。救助に連鎖するコンストラクタ!
public Presenter(IView view):this(view, new Dependency()){}
public Presenter(IView view, IDependency dependency)
{
this.View = view;
this.Dependency = dependency;
}
次に量産コードは、ユニットテストはビューと依存の両方のためにモックを渡し新しいものを使用しながら、元のインターフェースを使用し続けます。依存関係の数はいくつかのリファクタリングが必要となる成長を続けているが、当面、これは理想的なソリューションである場合。
他のヒント
私はそれがすでに行っています! ここ私のリポジトリの中を見てみましょう。ここでの私の選択は、コンストラクタを使用することです...私はプレゼンターが最大であることを確信しているgreediestを満たします。あなたのケースでは、依存関係のためのビューの特定のimplから提供することができます。
楽しみを持っている:)
私は今のリポジトリや工場のために行くと思います。それはすぐにテスト可能になります。将来的には、あなたはDIライブラリに移動するには、その実装を置き換えることができます。
public class DomainObjectsRepository
{
/// <summary>
/// can not be instantiated, use <see cref="Instance"/> instead.
/// </summary>
protected DomainObjectsRepository()
{
}
static DomainObjectsRepository()
{
Instance = new DomainObjectsRepository();
}
public static DomainObjectsRepository Instance { get; set; }
public virtual ICustomerDao GetCustomerDao()
{
return new CustomerDao();
}
}
public class DomainObjectsRepositoryMock : DomainObjectsRepository
{
public override ICustomerDao GetCustomerDao()
{
return new CustomerDaoMock();
}
}