参数化抽象工厂/工厂方法/其他创建模式

时间:2017-04-12 14:33:51

标签: c# design-patterns abstract-factory factory-method creation-pattern

我想要一些工厂(如果抽象工厂模式或工厂方法无关紧要 - 看起来第二个是第一个的特定形式。在我的情况下,只应创建一个对象)。问题在于虽然创建的产品相似,但它们依赖于一些参数。

如何根据设计模式准备此架构?

目前的方法

public abstract class Product {}

public class MyProduct : Product
{
    public bool Abc { get; set; }
}

public class YourProduct : Product {}

public abstract class ProductFactory
{
    //in some cases parameter not in use
    public abstract Product Create(HelpData additionalData);
}

public class MyProductFactory : ProductFactory
{
    public override Product Create(HelpData additionalData)
    {
        return new MyProduct {Abc = additionalData.SomethingImportantForMyProduct};
    }
}

public class YourProductFactory : ProductFactory
{
    //unused parameter
    public override Product Create(HelpData additionalData)
    {
        return new YourProduct();
    }
}

public class HelpData
{
    public bool SomethingImportantForMyProduct { get; set; }
}

修改

我看到它不清楚所以会重复。

通常我只是因为使用它而不使用模式。但这个问题似乎不是边界情况。看起来相当频繁。更进一步,我相信有适合的设计模式,但我不确定是哪一个。现在看起来像抽象工厂不是正确的选择。

2 个答案:

答案 0 :(得分:1)

不要使用设计模式,因为您使用的是设计模式。总之要记住何时使用,何时不使用。在你的情况下,至少抽象工厂模式是错误的,因为它假设所有工厂都使用相同的参数。因此,如果你有不同的参数,你肯定需要不同的工厂。但是,抽象工厂无法猜测如何在某些情况下获取HelpData的实例而在另一种情况下不能获取实例,因此要么将其传递给每个抽象工具,要么完全传递给它省略这种进一步的抽象并留在两个独立的工厂:

public abstract class Product {}

public class MyProduct : Product
{
    public bool Abc { get; set; }
}

public class YourProduct : Product {}

public class MyProductFactory
{
    public Product Create(HelpData additionalData)
    {
        return new MyProduct {Abc = additionalData.SomethingImportantForMyProduct};
    }
}

public class YourProductFactory
{
    //unused parameter
    public Product Create()
    {
        return new YourProduct();
    }
}

public class HelpData
{
    public bool SomethingImportantForMyProduct { get; set; }
}

一个工厂中使用的参数公开给所有工厂不是一个好主意。

除此之外,您可以想象您没有工厂,但任何其他类都有Create - 方法,其中一个需要参数,而另一个则不需要。为什么这两个类来自同一个基类(在你的情况下是抽象工厂),当没有任何共同的成员时?显然没有理由这样做,所以不要仅仅因为使用不适合的模式而使事情过于复杂。

答案 1 :(得分:0)

根据您检索其他数据的位置和方式,您可以将数据注入工厂,并使用它来构建对象:

public abstract class ProductFactory
{
    public abstract Product Create();
}

public class MyProductFactory : ProductFactory
{
    private HelpData additionalData;

    public MyProductFactory(HelpData additionalData)
    {
         this.additionalData = additionalData;
    }

    public override Product Create()
    {
        return new MyProduct {Abc = additionalData.SomethingImportantForMyProduct};
    }
}

public class YourProductFactory : ProductFactory
{
    public override Product Create()
    {
        return new YourProduct();
    }
}

您可以注入一个知道如何检索特定于正在创建的对象的HelpData的服务,而不是将HelpData传递给工厂的构造函数。如果它用于两个工厂,您可以将其他参数传递给Create方法。

我也搜索了一下,找到了解释为什么不是https://stackoverflow.com/a/6241219/2138959的好答案。传递字典或具有字典类型属性的类型也是选项,但在这种方法中,客户端对要创建的类型有太多的了解以使用抽象工厂。