I am learning design patterns newly & I am trying to understand the difference between Simple Factory & Factory Method Pattern. First I want to clear that , I tried reading lot of articles from Stack-overflow and other sites regarding the same but that doesn't helped me.
Here is my question:
Lets consider I have a product hierarchy as shown below:
I have written a simple Factory class as shown below
public class SimpleItemFactory {
static Item getItem(String type) {
if(type.equals("Cake")) {
return new Cake();
}else if(type.equals("Chocolate")) {
return new Chocolate();
}else {
return null;
}
}
}
so now I have all the object creation in one place , so if tomorrow any changes occurs[Like constructor needs one parameter] we need to change in only one place. But it breaks OPEN CLOSED principle as if tomorrow we add more item we need to change getItem() methods if condition. So we go for Factory Method Pattern
We create Factory class as shown below:
public abstract class ItemFactory {
abstract Item getItem();
}
class CakeFactory extends ItemFactory {
@Override
Item getItem() {
return new Cake();
}
}
class ChocolateFactory extends ItemFactory {
@Override
Item getItem() {
return new Chocolate();
}
}
class Client{
public static void main(String[] args) {
Item chocolate = new ChocolateFactory().getItem();
System.out.println(chocolate);
}
}
Now when the client want to add new Item called IceCream, they just create new Factory called IceCreamFactory and create IceCream from that as shown below:
class IceCreamFactory extends ItemFactory{
@Override
Item getItem() {
return new IceCream();
}
}
class Client{
public static void main(String[] args) {
Item iceCream = new IceCreamFactory().getItem();
System.out.println(iceCream);
}
}
Is my understanding correct? We satisfied Open closed principle here, but for each product(Item) we need one Factory class, does not it become manageable nightmare?
NOTE: Article I was referring https://www.codeproject.com/Articles/1135918/Factory-Patterns-Factory-Method-Pattern?msg=5380215#xx5380215xx
Your understanding actually is correct, just you need to note that every design pattern is made to solve at least one single issue, sometimes it could bring with it some other complexities or side effects, which means there is no perfect design pattern that could solve every problems.
For learning purposes you apply design patterns one by one (that makes the real power of design patterns sames to be shy or hiding), however in a real world context design patterns are mixed together (or even you can invent a new one :p) for the purpose of creating something that satisfy most your needs and becomes near to ideal, you can meet for example the Builder pattern mixed with Factory pattern or Factory pattern with Strategy pattern, or even the three of them mixed together...
For your case here I propose for example to use Factory Method Pattern together with Simple Factory Pattern combined with Dependency Injection Pattern to create something totally beautiful and at the same time satisfying the Open closed principal.
class ItemFactoryContainer() {
private Map<String, ItemFactory> factories = new HashMap<>();
public void register(String name, ItemFactory factory) {
factories.put(name, factory);
}
public ItemFactory getFactory(String name) {
return factories.get(name);
}
}
public class ItemFactoryTest {
public static void main(String...args) {
ItemFactoryContainer factoryContainer = new ItemFactoryContainer();
factoryContainer.register("choclate", new ChocolateFactory ());
factoryContainer.register("cake", new CakeFactory ());
factoryContainer.register("iceCream", new IceCreamFactory ());
Chocolate choclate = factoryContainer.getFactory("choclate").getItem();
Cake cake = factoryContainer.getFactory("cake").getItem();
}
}