简单工厂与工厂方法:在工厂与客户端中切换语句

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帖子,没有一个解决这个特定的区别.

是否有更好的解决方案不会违反客户或工厂方面的开放/封闭原则?

GFr*_*nke 1

标准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 语句,并且不会违反客户端或工厂端的开放/关闭原则。