在工厂中保存信息而不是通过调用代码传递它是否有意义?

时间:2017-08-26 04:53:35

标签: c# design-patterns

我有一个工厂,可以创建通过我的应用程序广泛使用的对象。工厂创建的一些对象需要另一个依赖项。此可选依赖项是具有本地设置文件设置的接口/类。目前,工厂界面和设置界面都注入了20个类。尽管如果应用程序继承树的深度不是6-7级,那么类的数量会更少(意味着IFactory和ISettings通过6个构造函数传递,最后到达将它们分配给字段的基类)。 / p>

深度继承不会很快改变,但我认为我可以通过从它们中删除ISettings并将其放入IFactory实现本身来减轻这些构造函数的负载。 ISettings将通过构造函数注入到具体工厂,然后它不是将ISettings作为Create()方法的一部分传递,而是使用工厂ISettings readonly属性。一旦程序启动,这些设置将保证不可变。

这是否以任何方式令人不满,是否有更好的方法来解决这个问题?一些同事认为工厂几乎从不会持有国家......但他们并不完全确定原因。

这些是我发现的类似问题,给出了答案,但如果可能的话,我仍然在寻找更加充实的答案。

Adding Properties to Abstract Factory

Abstract Factory Pattern and Properties

简单示例:

interface IObjValidator
{
    bool Validate();
}

interface IObjValidatorFactory
{
    IObjValidator Create();
}

class ObjValidatorFactory : IObjValidatorFactory
{
    // Is it OK for the factory to hold this field?
    private readonly ISettings settings;    

    public IObjValidator(ISettings settings)
    {
        this.settings = settings;
    }    

    IObjValidator Create(ObjValidatorMode mode)
    {
        switch(mode)
        {
             case ObjValidatorMode.One:
                 return ObjValidator1();

             case ObjValidatorMode.Two:
                 return ObjValidator2(this.settings);
        }
    }
}

class ObjValidator1: IObjValidator
{
    public bool Validate()
    {
        // Do stuff.
    }
}

class ObjValidator2: IObjValidator
{
    private readonly ISettings settings;

    public ObjValidator2(ISettings settings)
    {
        this.settings = settings;
    }

    public bool Validate()
    {
        // Use ISettings field data here.            
    }
}

3 个答案:

答案 0 :(得分:1)

如果ObjValidator2以某种方式替换为不同的验证器(例如ObjValidator2a),我宁可避免,如果可以的话,其他一切都是平等的,

A。)您现在必须更改构造函数以接受objValidator2a的设置对象 B.)从构造函数中删除它,因为objValidator2a不需要objValidator2的设置 C.)保持构造函数,因为知道传递的设置永远不会被使用。

YMMV

答案 1 :(得分:1)

  

这是否以任何方式令人不满,是否有更好的方法来解决这个问题?

解决此问题的不正确的方法是使用{em> Singlteon 设置类,验证程序使用Settings.getInstance进行访问。这是令人不悦的。问题中提到的方法实际上解决了单例设置类所引入的所有问题,因此是正确的前进方法。

那就是说,我要改变的一件事是我会让ObjValidatorFactory类依赖于ISettingsFactory接口,而不是直接依赖ISettings。这会将创建ISettings实现的责任从客户端类重定向到ObjValidatorFactory

class ObjValidatorFactory: IObjValidatorFactory
{
    private ISettingsFactory settingsFactory;

    public ObjValidatorFactory(ISettingsFactory settingsFactory)
    {
        this.settingsFactory = settingsFactory;
    }

    IObjValidator Create(ObjValidatorMode mode)
    {
        //source could be the file name for example
        ISettings settings = settingsFactory.Create(source);
        switch(mode)
        {
             case ObjValidatorMode.One:
                 return ObjValidator1();

             case ObjValidatorMode.Two:
                 return ObjValidator2(settings);
        }
    }


}

工厂可以实例化如下:

ISettingsFactory fileSettingsFactory = new FileSettingsFactory();
IObjValidatorFactory objectValidatorFactory = new ObjValidatorFactory(fileSettingsFactory);
objectValidatorFactory.Create(ObjValidatorMode.STRICT);

答案 2 :(得分:0)

很少有观察到: - 并非所有验证器都需要ISettings - 基于模式

创建对象

在这种情况下,我认为抽象工厂更适合,将责任委托给子类。

在Factory类中有字段可以负责分析同一个对象,可以考虑饼干工厂总是创建一个相同的饼干。

方式,你已经定义了工厂类,可以导致内容耦合。将来,您将开始注入越来越多的无法维护的依赖项。

另一种方法是将预先构建的验证器作为映射注入工厂和create(),从地图中获取一个条目。