may*_*lle 5 design-patterns factory factory-pattern open-closed-principle solid-principles
据我所知,Factory Method比Simple Factory的主要优点之一是它不违反Open-Closed SOLID原则.也就是说,前者不需要在添加新类型时修改switch语句.
有一件我希望得到澄清.如果我要使用一个简单的工厂,我会有一个像这样的工厂(简化):
public class ObjectFactory {
public static IObject CreateObject(ObjectTypeEnum objectType) {
switch (objectType) {
case TypeA:
return ObjectA;
break;
case TypeB:
return ObjectB;
break;
case TypeC:
return ObjectC;
break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
并且客户端会这样称呼它:
IObject myObject = ObjectFactory.CreateObject(objectType);
Run Code Online (Sandbox Code Playgroud)
文献中的缺点是在添加新对象类型时需要修改CreateObject.
但是使用Factory方法,我们不会将此修改从工厂移动到客户端,就像这样(客户端代码):
IObject myObject;
switch (objectType) {
case TypeA:
myObject = ObjectAFactory.CreateObject();
break;
case TypeB:
myObject = ObjectBFactory.CreateObject();
break;
case TypeC:
myObject = ObjectCFactory.CreateObject();
break;
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,每次添加新类型时都需要修改客户端,而在之前的情况下需要修改工厂.那么一个优于另一个的优势是什么?请不要将此标记为重复,我已经查看了很多关于工厂的SO帖子,没有一个解决这个特定的区别.
是否有更好的解决方案不会违反客户或工厂方面的开放/封闭原则?
标准Abstract Factory设计模式没有帮助吗?
简化的Java代码:
public interface IFactory {
IObject createObject();
}
public class FactoryA implements IFactory {
public IObject createObject() {
return new ObjectA();
}
}
public class FactoryB implements IFactory {
public IObject createObject() {
return new ObjectB();
}
}
Client is configured (injected) with the needed Factory at run-time
IFactory myFactory = ... // new FactoryA();
...
IObject myObject = myFactory.createObject();
...
Run Code Online (Sandbox Code Playgroud)
另请参阅http://w3sdesign.com上的 GoF 设计模式内存/抽象工厂。
VARIANT 2
不要使用枚举对象类型,而是使用多态性定义对象类型(以避免 switch 语句)。简化的Java代码:
public interface IObjectType {
int getObjectType();
IObject createObject();
}
public class ObjectTypeA implements IObjectType {
...
public IObject createObject() {
return new ObjectA();
}
}
public class ObjectTypeB implements IObjectType {
...
public IObject createObject() {
return new ObjectB();
}
}
Client determines object type
IObjectType myObjectType = ... // new ObjectTypeA();
...
IObject myObject = myObjectType.createObject();
...
Run Code Online (Sandbox Code Playgroud)
我的结论:
我认为,更好的解决方案是使用多态性来设计类型,而不是使用枚举常量。这将避免 switch 语句,并且不会违反客户端或工厂端的开放/关闭原则。