Let's have a look at the Simple Factory
The intention for the Simple Factory
is straightforward: It produces instances of concrete classes. Sticking to your example: you have a Pizzeria
with methods like order()
:
public enum Pizzas {
QUADDROSTAGGIONI, SALMONE, ROMANA
}
public class Pizzeria {
public static Pizza order(Pizzas type){
switch(type){
case ROMANA: return new Romana();
case SALMONE: return new Salmone();
case QUADDROSTAGGIONI: return new Quaddrostaggioni();
default: throw new NoRecipeException();
}
}
}
This is really a simple case of a factory.
If you decide, that you wanted a Salmone-Pizza, you simply order an instance like this:
Pizza salmone=Pizzeria.order(Pizzas.SALMONE);
The advantage: you separated the use of Pizzas from its creation. You only want Pizza, independend of its creation process. You could enjoy Pizza without baking one yourself.
The downside: If you have several subtypes of the given flavours of Pizza (e.g. ROMANABerlinStyle, ROMANAHamburgStyle) you have two choices.
1) to add the new kind to the existing Pizzeria. That clutters your Pizzeria and you have to deal with several flavours, which aren't that different (e.g. ROMANABerlinStyle adds garlic and ROMANAHamburgStyle adds wild garlic) in one Pizzeria. Besides: it is of no advantage knowing, that you consume a berlinstyle or hamburgstyle pizza. You only wanted some well defined kind of Pizza from the Pizzeria.
2) you abstract one step further: you separate the individual flavours of the given kinds QUADDROSTAGGIONI, SALMONE, ROMANA
into independend factories. That means, the BerlinPizzeria
knows its recipe and so does the HamburgPizzeria
.
You are now allowed to have many different Pizzerias which could have their own recipes:
The traditional Pizzeria from above
public class PizzeriaImpl implements Pizzeria {
public Pizza order(Pizzas type){
switch(type){
case ROMANA: return new Romana();
case SALMONE: return new Salmone();
case QUADDROSTAGGIONI: return new Quaddrostaggioni();
default: throw new NoRecipeException();
}
}
}
and a berlinstyle one
public class BerlinPizzeriaImpl implements Pizzeria{
public Pizza order(Pizzas type){
switch(type){
case ROMANA: return new BerlinRomana();
case SALMONE: return new BerlinSalmone();
case QUADDROSTAGGIONI: return new Quaddrostaggioni();
default: throw new NoRecipeException();
}
}
}
Now you are able to start out your franchise:
public class PizzaFranchiseImpl implements Pizzeria{
Pizzeria p;
public Pizza order(Pizzas type){
return p.order(type);
}
public PizzaFranchiseImpl(Pizzeria p){
this.p=p;
};
}
If you are in Berlin you simply inject your BerlinPizzeriaImpl
.
The advantage: you are free to decide which flavour you support in each city (BerlinRomana, BerlinSalmone, traditional Quadrostaggioni). And this is completely transparent to your customer/consumer.
This follows the OpenClosed-principle: Your Pizzeria is closed, as you have a fixed set of pizzas, which you deliver (QUADDROSTAGGIONI, SALMONE, ROMANA), but you are open for new flavours, e.g. berlinstyle.
Further: each pizzeria itself is devoted to one style of pizza. The BerlinPizzeriaImpl
doesn't care how to do a traditional Romana (Single Responsibilty Principle).
Last but not least, you decouple different pizza styles from the franchise. The franchise needs only to know how to handle orders.
EDIT: I substituted the dead body with a delicious but dead fish :D
Best Answer
In short
Yes, a factory class may create only one kind of objects. It is fully ok to use a
Factory
prefix or suffix in the name of such classes.Some more arguments
According to GoF (still the reference textbook about design patterns), the factory method pattern:
In the structural description of the pattern, GoF use
Creator
for naming the interfaces or classes that define a factory method. But their examples use several naming conventions, their recommendation in that matter being:Your choice is completely in line with that recommendation and perfectly ok.
Moreover, the fact that your concrete factory implementations create only one kind of
Link
is not an issue either. GoF explain that a parameterized factory method is a factory that is able to create different kind of objects depending on some parameters. But this is only one of the many implementation possibilities described and not a requirement for a factory.Note: another pattern, the abstract factory aims to use the principle of the factory for creating objects belonging to a family of related classes. This is one particular kind of factory, and althought it's commonly used, it doesn't hold a monopoly on the
Factory
pre-/sufix