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

时间:2015-02-17 17:52:58

标签: design-patterns factory factory-pattern solid-principles open-closed-principle

据我所知,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;
        }
    }
}

并且客户端会这样称呼它:

IObject myObject = ObjectFactory.CreateObject(objectType);

文献中的缺点是在添加新对象类型时需要修改CreateObject。

但是使用Factory方法,我们不会将此修改从工厂移动到客户端,就像这样(客户端代码):

IObject myObject;
switch (objectType) {
            case TypeA:
                myObject = ObjectAFactory.CreateObject();
                break;
            case TypeB:
                myObject = ObjectBFactory.CreateObject();
                break;
            case TypeC:
                myObject = ObjectCFactory.CreateObject();
                break;
}

在这种情况下,每次添加新类型时都需要修改客户端,而在之前的情况下需要修改工厂。那么一个优于另一个的优势是什么?请不要将其标记为重复,我已经查看了很多关于工厂的SO帖子,但没有一个解决这个特定的区别。

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

1 个答案:

答案 0 :(得分: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();
...

另见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();
...

我的结论:
我认为,更好的解决方案是使用多态而不是使用枚举常量来设计类型。 这样可以避免转换语句,也不会违反客户端或工厂方面的开放/封闭原则。