4

我正在努力创造以下情况:

首先,有几个 Linq to SQL Table 对象做几乎相同的事情。我们称它们为 products_something、products_somethingElse 等。

其次,有一个接口可以执行 Products DAO 的所有常用方法。首先,我尝试为所有产品只创建一个 DAO,因为我可以处理它在另一层(DAL)上的差异。但由于 Linq to SQL 需要强类型引用,我最终为每种类型的产品使用了一个 DAO。我真的不知道是否可以做我之前提到的事情。

最后,我有一个 ProductsDaoFactory,它根据客户端(用户视图)选择​​实例化正确的 ProductDao。因为我不知道在运行时会选择哪种类型的产品,所以我创建了一个通用工厂来处理它。

这是代码:

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 回答