我有一个工厂,可以创建通过我的应用程序广泛使用的对象。工厂创建的一些对象需要另一个依赖项。此可选依赖项是具有本地设置文件设置的接口/类。目前,工厂界面和设置界面都注入了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.
}
}
答案 0 :(得分:1)
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(),从地图中获取一个条目。