-->

Simple Factory vs Factory Method: Switch statement

2019-04-08 17:07发布

问题:

I understand that one of the main advantages of the Factory Method over Simple Factory is that it doesn't violate the Open-Closed SOLID Principle. That is, the former doesn't require modifying the switch statement when new types are added.

There is one piece on which I am hoping to get clarification. If I were to use a simple factory, I would have a factory like this (simplified):

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;
        }
    }
}

and the client would call it like this:

IObject myObject = ObjectFactory.CreateObject(objectType);

The disadvantage in the literature is that CreateObject will need to be modified when new object types are added.

But with the Factory Method, wouldn't we just be moving this modification from the factory to the client, like this (client code):

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

In this case the client will need to be modified each time a new type is added, versus in the previous case the factory would need to be modified. So what is the advantage then of one over the other? Please don't mark this as duplicate, I have looked at many SO posts about factories and none address this specific distinction.

Is there a better solution that doesn't violate the Open/Closed Principle on either the client or factory side?

回答1:

The standard Abstract Factory design pattern doesn't help?
Simplified Java code:

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

See also the GoF Design Patterns Memory / Abstract Factory at http://w3sdesign.com.

VARIANT 2
Instead of using enum object types, define your object types with polymorphism (to avoid switch statements). Simplified Java code:

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

My conclusion:
I think, a better solution would be to design your types with polymorphism instead of using enum constans. This would avoid switch statements and wouldn't violate the Open/Closed Principle on either the client or factory side.