问题是关于工厂模式的GoF
解释。
我有Tree<SqlRestriction>
其中
public interface SqlRestriction{
public String getSql();
}
现在,我需要创建一个名为Container的接口对象:
public interface Container{
//methods
}
以下是其实施之一:
public class SimpleSqlListContainer implements Container{
private Integer rate;
private String relation;
//GET, SET, CTORs, other methods
}
所以,我倾向于将对象创建包装到工厂
public class ContainerFactory{
public Container create(Tree<SqlRestriction> restrinctions){
//impl
}
}
实际创建以及 正确初始化 将通过遍历作为参数传递的Tree
来执行。
问题: 如果我初始化在工厂方法中创建的对象,它会被认为是好的。或者它会误导其他开发者?因此,在工厂方法中,我们应该避免任何类型的初始化,只是执行对象创建,将初始化留给客户端。
答案 0 :(得分:2)
GoF模式没有说明对象初始化(我重新阅读本章只是为了确保)。该模式的唯一目的是隐藏工厂实现中的类型选择。
也就是说,如果你构建了一些特定类型的对象,并且每个对象都有相同的初始化序列,例如:
public IFoo createFoo(){
ConcreteFoo foo = new ConcreteFoo();
foo.setField1("a");
foo.setField2("b");
....
foo.setFieldN("z");
return foo;
}
任何在代码中重复多次的初始化序列都应该封装在某处以避免代码重复。只有在应用于该类的每个可能实例时,此初始化才能进入构造函数。我在谈论默认值。现在,如果初始化序列不适用于某个类的每个实例,而是为了特定目的而进行的,那么它应该从构造函数中取出。
只要初始化用例在您的应用程序中足够通用,工厂实现就是一个很好的选择。 Factory界面如下所示:
public interface IFooFactory {
public IFoo createFooForThis();
public IFoo createFooForThat();
...
}
实际上,如果我们需要在属于ConcreteFoo
类的foo实例上调用setter并且不在IFoo
接口中,那么这是唯一可以执行此操作的地方,因为客户端代码无法调用IFoo
接口之外的方法。
答案 1 :(得分:1)
工厂模式的关注点是根据提供的参数做出决定要返回的对象类型。它封装了这种逻辑。如果Container类的其他实现适合特定类型的SqlRestriction,那么工厂会为您做出决定。
初始化Container的问题,在我看来属于Container本身。因为它知道如何遍历树,所以它被传递以包含对象。