4

次の状況を作成するのに苦労しています。

まず、ほとんど同じことを行う Linq to SQL テーブル オブジェクトがいくつかあります。それらをproducts_something、products_somethingElseなどと呼びましょう.

次に、Products DAO のすべての一般的なメソッドを実行するインターフェイスがあります。最初に、すべての製品に対して 1 つの DAO のみを作成しようとしました。これは、別のレイヤー (DAL) で違いを処理できるためです。しかし、Linq to SQL は強く型付けされた参照を必要とするため、製品の種類ごとに 1 つの DAO を使用することになります。私が前に述べたことを行うことが可能かどうかはよくわかりません。

最後に、クライアント側 (ユーザー ビュー) の選択に基づいて正しい ProductDao をインスタンス化する ProductsDaoFactory があります。実行時にどのタイプの製品が選択されるかわからないため、それを処理する汎用ファクトリを作成しました。

コードは次のとおりです。

public enum ProductEnum
    {
        SimpleProduct, ComplexProduct, RevisedProduct, BrokenProduct
    }

    public interface IProducts<T>
    {
        T GetProductById(int id);
        IQueryable<T> GetAllProducts(string product_name, DateTime product_age);
        //Several other common methods
    }



public static class ProductFactory
    {
      //This won't compile because i have to set what's the type of the DAO i want
        public static IProducts<T> GetProductDAO(ProductEnum product)
        {
            switch (product)
            {
                case ProductEnum.SimpleProduct:
                    return new SimpleProductDAO();
                case ProductEnum.ComplexProduct:
                    return new ComplexProductDAO();
                case ProductEnum.RevisedProduct:
                    return new RevisedProductDAO();
                case ProductEnum.BrokenProduct:
                    return new BrokenProductDAO();
                default:
                    break;
            }

            return null;
        }
    }

    public class SimpleProductDAO : IProducts<SimpleProductDAO>
    {

        public SimpleProductDAO GetProductById(int id)
        {
            //Implementation
        }

        public IQueryable<SimpleProductDAO> GetAllProducts(string product_name, DateTime product_age)
        {
            //Implementation
        }
    }

問題は次のとおりです。ファクトリ メソッドの戻り値の型はジェネリックであるため、定義できません。そのタイプをファクトリに渡す必要があり、それは単にファクトリのアイデアを壊します。では、インターフェイスのジェネリック型をインスタンス化するファクトリ メソッドを作成するにはどうすればよいでしょうか。

4

1 に答える 1

1

あなたの問題は、ジェネリックが実際にはジェネリックではないことです。だから私は言うことができないので、あなたのメソッドはまったく一般的であってはなりません:

GetProductDAO<int>(someEnum);

ファクトリからジェネリックを削除すると、問題が解決するだけでなく、API のユーザーにとってより明確で一貫性のあるものになると思います。そうは言っても、ジェネリックはより優れたインテリセンスを可能にします。

私のお気に入りの解決策は、列挙型を削除してジェネリック型を渡すだけで、メソッドに制限を追加することです。

public static IProducts<T> GetProductDAO<T>() where T: ISomeMarkerInterface, new()

したがって、単なる空のインターフェースであるSimpleProductDAO実装は次のとおりです。ISomeMarkerInterface

public interface ISomeMarkerInterface
{

}

そして工場は小さくなります:

public static class ProductFactory
{
    public static IProducts<T> GetProductDAO<T>() where T : ISomeMarkerInterface, IProducts<T>, new()
    {
        return new T();
    }
}

あるいは

ファクトリを次のように定義します。

public static IProducts<T> GetProductDAO<T>(ProductEnum product)
{
    ...

制限なしで悪用される可能性があるため、これは私のお気に入りのソリューションではありません

于 2012-04-05T14:40:26.817 に答える