C# 工厂模式能解决我的问题吗?

C# 工厂模式能解决我的问题吗?,c#,design-patterns,C#,Design Patterns,我需要创建一些实现给定接口的对象,其中创建的具体实现类型基于枚举值 当不同的具体实现在运行时需要不同的参数时,我遇到了麻烦 这个例子(C#)很好: 但是,如果具体实现具有不同的构造函数参数,会发生什么情况?我无法将所有值传递给SerialNumberValidatorFactory.CreateValidator()方法,因此如何继续 我听说抽象工厂模式应该可以解决这个问题,但我不确定如何正确实现它。您始终可以创建一个设置容器来传递给CreateValidator方法。从基本IValidator

我需要创建一些实现给定接口的对象,其中创建的具体实现类型基于枚举值

当不同的具体实现在运行时需要不同的参数时,我遇到了麻烦

这个例子(C#)很好:

但是,如果具体实现具有不同的构造函数参数,会发生什么情况?我无法将所有值传递给
SerialNumberValidatorFactory.CreateValidator()
方法,因此如何继续


我听说
抽象工厂
模式应该可以解决这个问题,但我不确定如何正确实现它。

您始终可以创建一个设置容器来传递给
CreateValidator
方法。从基本
IValidatorSettings
开始,然后创建
IModemSerialNumberValidatorSettings
等,
CreateValidator
然后可以使用
ProductType
IValidatorSettings
参数

然后,验证器的具体类将其
IXXXValidatorSettings
接口作为唯一的构造函数参数

除此之外,您还可以创建一个
IValidatorSettings
工厂


我认为抽象工厂是一个创建工厂来处理给定类型集的工厂-不确定它是否适用于您的场景。

您使用的是工厂方法模式,您应该使用的是抽象工厂

在抽象工厂中,为每个具体实现提供一个工厂类:

所以你的代码变成:(原谅代码,但原理是一样的)


您可以将构造函数参数聚合到接口上的初始化方法中吗?这将为您留下一个无参数构造函数。定义构造函数参数意味着调用方必须提供参数(除非工厂可以提供参数),这打破了使用接口的关键,因为调用方现在提供的是特定于实现的内容。@Adam是的,我已经考虑过了。唯一的事情就是对
Initialise()
的调用进行监控。至少对于ctor args,它们是必需的值,您无法避免传入。您始终可以再添加一层接口—一个包含给定类型参数的
设置
类。然后,您可以为每个请求设置的验证器公开一个
ISettings
,并将其传递给类工厂
CreateValidator
。这意味着您正在将类型化值传递给另一个接口-因此我假设您与该接口绑定,但即使传递
ProductType
您的代码已经需要某个类型,因此传递某个接口也不会再造成任何伤害。@Adam好的,我来看看。值得指出的是,ProductType是一个
Enum
而不是
类型
@Neil是的,对不起,我更想说的是,代码逻辑已经在要求某个验证器,因此让它提供一个特定于验证器的设置容器不会对依赖项进行太多的变形(如果有的话)。
public enum ProductCategory
{
    Modem,
    Keyboard,
    Monitor
}

public class SerialNumberValidatorFactory()
{
    public ISerialNumberValidator CreateValidator(ProductCategory productCategory)
    {
        switch (productCategory)
        {
            case ProductCategory.Modem:
                return new ModemSerialNumberValidator();
            case ProductCategory.Keyboard:
                return new KeyboardSerialNumberValidator();
            case ProductCategory.Monitor:
                return new MonitorSerialNumberValidator();
            default:
                throw new ArgumentException("productType", string.Format("Product category not supported for serial number validation: {0}", productCategory))
        }
    }
}
public class SerialNumberValidatorFactory
{
    public static SerialNumberValidatorFactory newInstance(
           ProductCategory productCategory)
    {
        switch (productCategory)
        {
            case ProductCategory.Modem:
                return new ModemValidatorFactory();
            ....
        }
    }

    public abstract ISerialNumberValidator createValidator();
}

public class ModemValidatorFactory extends SerialNumberValidatorFactory
{
   public ISerialNumberValidator createValidator() 
   {
      return new ModemSerialNumberValidator("model", "number");
   }
}

ISerialNumberValidator = SerialNumberValidatorFactory.newInstance(productCategory).createValidator()