3

I am reading the book »Head First Design Patterns« from O'Reilly. Before explaining the Factory Method Pattern, they introduce a Simple Factory first.

They are using the example of a pizzeria. In a first step they show the problem:

Pizza orderPizza(string type) {
  Pizza pizza;
  if (type.equals("Pepperoni") { pizza = new PepperoniPizza(); }
  else if (type.equals("Salmon") { pizza = new SalmonPizza(); }
  // ... and so on

  pizza.Prepare();
  pizza.Bake();
  pizza.Cut();
  pizza.Pack();
  return pizza;
}

The obvious problem is that you had to change Pizzeria whenever you add or remove a Pizza.
Hence they introduce a "Simple Factory Idiom" first. They move the creating part into a class "SimplePizzaFactory". Now you don't need to modify Pizzeria anymore when adding or removing a Pizza.

Then they say that this approach isn't that good, when you have more than one pizzeria (in several towns).
I don't really understand their reasoning. They give the following example code and then they say that each pizzeria wouldn't be using the procedure as implemented above but were using different methods in order to "bake", "cut" and "pack" the pizza.

BerlinPizzaFactory berlinFactory = new BerlinPizzaFactory();
Pizzeria berlinPizzeria = new Pizzeria(berlinFactory);
berlinPizza.Order("Pepperoni");

Instead of using the Simple Factory, they suggest using the Factory Method Pattern.

First, I don't see why the BerlinPizzeria is supposed to not using the procedure. It's still a Pizzeria and when you call Order, you're using the same procedure.

My best guess is that they are implying that you are able to implement, let's say, a cafeteria (I'm deliberately using something entirely different to make my point) and use the factory (as it is independent of the pizzeria) and prepare the pizza in a way you want to.

But even when using the Factory Method Pattern, nobody forces you to use the default procedure. It's even simpler to "hide" that you're doing it differently. Their code examples are given in Java and Java methods are virtual by default. So I would be able to implement BerlinPizzeria and override Order (or had to explicitly declare the method as final). The client, however, wouldn't notice that my BerlinPizzeria is doing things differently.

In conclusion I don't see any significant difference between a Simple Factory and the Factory Method Pattern. The only advantage of the Factory Method Pattern I'm seeing is that you would save a few classes (namely, the 'outsourced' factories).

So, what is really the disadvantages of a Simple Factory and why isn't is a good idea to 'outsource' the creating part?
Or what is really the advantage of the Factory Method pattern and why is it a good idea to force the creating part being implemented in the subclass?

  • Can you post the client code for both examples to show how they are called? You may find the Simple method would require changing this code for each new pizzeria. – JeffO Aug 31 '14 at 9:42
  • @JeffO I don't think they really show the client code in their book; but when I implemented it myself (in C# though), the client looked almost identically, except I hadn't to create an instance of the pizza factory (as it is part of the pizzeria itself). Having said that, it may be possible that I implemented it incorrectly based on a misunderstanding. – Em1 Aug 31 '14 at 10:27
  • 3
    Strikes me as a piss poor example. In the real world you would have one factory (a Pizzeria) which used recipes. The Factory pattern is one of the most over used and misused idioms. Most times it makes something simple complex, and, solves a problem that only exists in an OO purists mind. – James Anderson Sep 2 '14 at 9:20
  • codeproject.com/Articles/492900/… provides a nice explanation – narayan Apr 7 '19 at 7:58
3

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

| improve this answer | |
  • So, what's the difference? Perhaps I'm not seeing it but the Simple Factory follows the OpenClosed-principle, too. I mean, whenever I add or remove a Pizza I must change some code some place. Either in my Simple Factory or in my Factory Method. In both cases my actual pizzeria isn't affected. And in case of Simple Factory my BerlinPizzeria doesn't care about traditional pizzas either. – Em1 Aug 31 '14 at 10:24
  • No. The simple factory (Pizzeria from above) doesn't follow the OpenClosedPrinciple: If you have to deal with several flavours of the same pizzatype, you can't without breaking the class and the enum. Another flavour requires a different implementation. Therefore it is reasonable to use another factory. – Thomas Junk Aug 31 '14 at 11:22
  • 4
    I hope nobody ever give me a salme pizzas since salme means corpses in italian :) – Fabio Marcolini Aug 31 '14 at 13:51
  • @FabioMarcolini my bad: it should read salmone 😄. – Thomas Junk Aug 31 '14 at 14:21
0

First of all, I've read that book and I love it.

The classic implementation of the Simple Factory is just a bunch of "static create" methods encapsulated into one class.

You can argue that you separate the implementation of the class from its creation, but that's it. There is no further advantage and even that statement is questionable. In my point of view, you're just separating some creation static methods into a different file.

In most real cases, you end up with a huge "file" which produces not only Pizzas, but also many other unrelated objects like Burguers, Icecreams, ... so you break the single responsibility principle. This is because at the beginning, you just have a couple of create methods of most things, so the "natural" thing is to group them so they don't feel alone in one small Simple Factory class.

Therefore, the main disadvantages are cluttering. In most cases you end up with huge files or with many small files.

However, the main thing is that the Simple Factory is not a design pattern, is just a convention which can be useful is some cases (e.g. unit testing). In most cases you just need a couple of create methods which can be included in the same class (you don't need an external class for that).

If you have lots of create methods for one single class, you've got a big problem: either this class is doing too much, you think that passing parameters is a bad thing or any other random reason.

The Factory Method, unlike the Simple Factory, uses inheritance to solve the problem of creating objects without specifying their exact classes.

Wait for the Proxy chapter. A Proxy (in brief) is an object that "stands for" another. In this case the Factory Method can be useful because you create an instance which can be the Proxy or the real Object itself.

| improve this answer | |
  • So, except for the 'cluttering' and that the simple factory is just considered an 'idiom', you don't see any reason why the simple factory would have some severe issues that the factory method wouldn't have? (Like the one they are claiming in the book, i.e. you could circumvent the default procedure for a simple factory but not for a factory method.) – Em1 Sep 2 '14 at 12:44
  • @Em1 Quite the opposite. I just think that cluttering is probably the first problem that the Simple Factory leads to. Depending of how you implement it, some other issues might also arise. However, as you state, this is just an 'idiom' and so there is no formal definition for it apart from some vague idea about encapsulating static create methods into a class. Anyways, I don't think the Simple Factory is a bad thing, it can be useful in some cases like testing or proof of concepts developments. – FranMowinckel Sep 2 '14 at 13:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.