The blog for Design Patterns, Linux, HA and Myself!
From this tutorial we will look into Factory Method Design Pattern. This tutorial expects that you’ve already gone through Simple Factory Pattern.
In the Simple Factory Pattern(or an Idiom?) we tried to delegate the task of creating and instantiating objects, i.e. MilkShakes, to a different object and we called it a Simple Factory.
Well, there’s one more way to deal with it by delegating the task to creating objects to the sub classes.
Let’s imagine a scenario in which there are multiple franchisees that require the Milk Cake Shop. These franchisees have no idea about how to create the Milk Shakes but they know the customers from their area and they know what to sell.
To solve this problem we’ve two possible solutions:
We can ask them to send the types of Milk Shakes that they would want and then we can add them to our factory. This requires us to update the MilkShakeFactory class by adding the code to create the specific types of Milk shakes.
This looks easy but there are some problems here.
We can convert MilkShakeShop class to an abstract class by making the method createMilkShake
abstract.
The franchisees can then override it and create the Milk Shakes that they require. This way Milk shake types will
remain private for the franchisees and we won’t have to keep on releasing newer libraries.
In the code below there are two franchisees DelhiMilkShakeShop
and MumbaiMilkShakeShop
that extend MilkCakeShop
.
The DelhiMilkShakeShop
only wants to sell the StrawBerryMilkShake
and the MumbaiMilkShakeShop
doesn’t sell the
StrawberryMilkShake
but sells the ChocolateMilkShake
and BananaMilkShake
.
/**
* This new milk cake shop is delegating the object creation process to its concrete classes.
*/
abstract class MilkShakeShop {
/**
* The classes {@link DelhiMilkShakeShop} and {@link MumbaiMilkShakeShop} will implement this method.
*
* @param type type of the milk shake
* @return a concrete Milk Shake
*/
abstract MilkShake createMilkShake(String type);
MilkShake orderShake(String type) {
MilkShake milkShake;
milkShake = createMilkShake(type);
milkShake.addMilk();
milkShake.addIngredients();
milkShake.blend();
return milkShake;
}
}
class DelhiMilkShakeShop extends MilkShakeShop {
/**
* Delhi Milkshake shop only serves Strawberry Milkshakes
*
* @param type type of the milk shake
* @return Milkshake
*/
MilkShake createMilkShake(String type) {
MilkShake milkShake;
if (StrawBerryMilkShake.name().equals(type)) {
milkShake = new StrawBerryMilkShake();
} else {
throw new RuntimeException("the passed milk shake type is not available with us.");
}
return milkShake;
}
}
class MumbaiMilkShakeShop extends MilkShakeShop {
/**
* Mumbai Milkshake shop serves Banana MilkShake and Chocolate Milkshake
*
* @param type type of the milk shake
* @return Milkshake
*/
MilkShake createMilkShake(String type) {
MilkShake milkShake;
if (ChocolateMilkShake.name().equals(type)) {
milkShake = new ChocolateMilkShake();
} else if (BananaMilkShake.name().equals(type)) {
milkShake = new BananaMilkShake();
} else {
throw new RuntimeException("the passed milk shake type is not available with us.");
}
return milkShake;
}
}
Finally the definition from Wikipedia
The factory method pattern is a creational pattern that uses factory methods to deal with the problem of creating objects without having to specify the exact class of the object that will be created. This is done by creating objects by calling a factory method—either specified in an interface and implemented by child classes, or implemented in a base class and optionally overridden by derived classes—rather than by calling a constructor.
I’ve created these tutorials after learning Design Patterns from this book Head First Design Patterns (A Brain Friendly Guide).