1

設計しているアプリをより汎用的にし、コマンドパターンを実装して、マネージャークラスを使用して、インターフェイスによって公開されているメソッドを呼び出そうとしています。

GetItem()GetList()メソッドを含むクラスがいくつかあり、一部はオーバーロードされています。私が依存性注入を使おうとしていたので、それらは異なるパラメーターを受け入れ、異なるタイプを返します。次にいくつかの例を示します。

 class DatastoreHelper
    {
        public Datastore GetItem(string DatastoreName)
        {
            // return new Datastore(); from somewhere
        }
        public Datastore GetItem(int DatastoreID)
        {
            // return new Datastore(); from somewhere
        }
        public List<Datastore> GetList()
        {
           // return List<Datastore>(); from somewhere
        }
        public List<Datastore> GetList(HostSystem myHostSystem)
        {
           // return List<Datastore>(); from somewhere
        }

    }
    class HostSystemHelper
    {
        public HostSystem GetItem(int HostSystemID)
        {
          //  return new HostSystem(); from somewhere
        }
        public List<HostSystem> GetList(string ClusterName)
        {
            //return new List<HostSystem>(); from somewhere
        }
    }

これらの2つのメソッドにジェネリックインターフェイスを使用できるかどうか、および実質的にコントローラーとなるマネージャークラスを使用できるかどうかを調べています。これを行うと、マネージャークラスの再利用能力が向上します。

  interface IGetObjects
    {
        public object GetItem();
        public object GetList();
    }

class GetObjectsManager
{
    private IGetObjects mGetObject;
    public GetObjectsManager(IGetObjects GetObject)
    {
        this.mGetObject = GetObject;
    }
    public object GetItem()
    {
        return this.mGetObject.GetItem();
    }
    public object GetList()
    {
        return this.GetList();
    }
}

パラメータをメソッド自体に渡すのをやめ、代わりにクラスプロパティを使用する必要があることはわかっていますが、依存性の注入は失われます。呼び出し元のコードで返されるオブジェクトを、本来あるべきものにキャストする必要があることはわかっています。したがって、私のヘルパークラスは次のようになります。

class DatastoreHelper
{
    public string DatastoreName { get; set; }
    public string DatastoreID { get; set; }
    public object GetItem()
    {
        // return new Datastore(); from somewhere
    }
    public List<object> GetList()
    {
       // return List<Datastore>(); from somewhere
    }

}
class HostSystemHelper
{
    public int HostSystemID { get; set; }
    public string ClusterName {get; set;}
    public object GetItem()
    {
      //  return new HostSystem(); from somewhere
    }
    public List<object> GetList()
    {
        //return new List<HostSystem>(); from somewhere
    }
}

しかし、上記は良い考えですか、それとも私はそれが属していない場所にパターンを適合させようとしていますか?

編集:クラスが複雑で多くのメソッドが含まれていることを示すために、いくつかのオーバーロードされたメソッドを追加しました。いくつかは、さまざまな入力パラメーターに従って何度もオーバーロードされています。

4

3 に答える 3

2

コンセプトを正しく理解していれば、このようなデザインは本当に悪い考えです。

class DatastoreHelper
{
    public string DatastoreName { get; set; }
    public string DatastoreID { get; set; }
    public object GetItem()
    {
        // return new Datastore(); from somewhere
    }
    public List<object> GetList()
    {
       // return List<Datastore>(); from somewhere
    }
}

その理由は、結果の取得が2段階のプロセスになるためです。最初にプロパティを設定し、次にメソッドを呼び出します。これには、さまざまな問題があります。

  • 直感的ではない(誰もがメソッド呼び出しの一部としてパラメーターを提供することに慣れています)
  • パラメータバインディングを呼び出しサイトから移動します(許可されています。これはおそらく「前のLOCに移動する」ことを意味しますが、それでも)
  • どのメソッドがどのプロパティ値を使用するかはもはや明らかではありません
  • このオブジェクトのインスタンスを取得し、すぐに楽しめるようにいくつかのスレッドを追加するだけです

提案:

  1. 型の安全性を失わないように、IGetObjectsと汎用の両方を作成します。GetObjectsManagerこれにより、さまざまなマネージャーを多形的に扱うことができなくなりますが、そのポイントは何ですか?各マネージャーは、最終的に特定のタイプのオブジェクトに特化することになり、そのタイプが何であるかを知らない限り、getterメソッドの戻り値を実際に使用することはできません。では、マネージャーを「未知のマネージャー」として扱うことができることで、何を得ることができるでしょうか。
  2. ベア値GetXの代わりに受け入れるようにメソッドを書き直すことを検討してください。Expression<Func<T, bool>>このようにして、ラムダ述語を使用できます。これにより、実際には何も失うことなく、コードが大幅に柔軟になります。例えば:

    helper.GetItem(i => i.DataStoreID == 42);
    helper.GetList(i => i.DataStoreName.Contains("Foo"));
    
于 2012-04-06T11:29:49.703 に答える
1

それは良い考えではありません。これらの例に基づいて、GetItem/GetListのさまざまな戻り値のタイプとパラメーター用の汎用インターフェースを使用する方がよいでしょう。正直なところ、マネージャーの普及率ですが、複数の場所でGetItemとして漠然としたものを使用し、(パターンの観点からソリューションを定義するのではなく)ソリューションをデザインパターンに適合させようとすることは、より広いソリューションにとって大きなコードの臭いです。

于 2012-04-06T11:37:37.413 に答える
1

最初のコードサンプルは、リポジトリパターンと非常によく似ています。これがあなたが適用しようとしていることだと思います。最後のサンプルは良くありません、そしてジョンはあなたに理由を話しました。ただし、車輪の再発明を行う代わりに、リポジトリについて少し読んでください(SOに関する多くの質問)。私が正しく理解していれば、これが本当に必要なことだからです。

再利用に関しては、多くのもの、特に永続性インターフェースは再利用可能ではありません。それを実現しようとする汎用リポジトリパターン(アンチパターンだと思います)がありますが、実際には、すべてのアプリケーションに同じ永続性インターフェイスが必要ですか?

一般的なガイドラインとして、オブジェクトを設計するときは、特定のアプリケーションのニーズを満たすように設計します。再利用された場合、それはボーナスですが、それはオブジェクトの主な目的ではありません。

于 2012-04-06T17:28:24.440 に答える