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?
Use the Factory method when you want to make a Framework where you want to take a control from the creation of the Object to the management of that Object. That's unlike the Simple factory, where you only care about the creation of a product, not how to create and manage it.
The factory method is a creational design pattern, i.e., related to object creation. In the Factory pattern, we create objects without exposing the creation logic to the client and the client uses the same common interface to create a new type of object.
There are 3 types of factory design pattern. Basically, Simple factory is not a design pattern. So, we will not talk about this rather we will cover its relevance while studying the factory method and in this post, I will only be explaining the factory method.
Factory: A factory that creates objects that derive from a particular base class. Abstract factory: A factory that creates other factories, and these factories in turn create objects derived from base classes.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With