The motivation behind Factory Method Design Pattern

Viewed 124

I'm learning about the Factory Method Desing Pattern and I'm having a hard time to understand exactly what it tries to solve and how.

Let's first introduce the example that Wikipedia uses to have a basis for the discussion.

enter image description here

So basically the products are MagicRoom and OrdinaryRoom, both derive from Room. And for the creators we have the base class/interface MazeGame which defines the method makeRoom, and the subclasses are MagicMazeGame and OrdinaryMazeGame. Now the client may either:

MazeGame game = new OrdinaryMazeGame()
or
MazeGame game = new MagicMazeGame()

Ok this is so we can talk about some example.

Now, Wikipedia describes the motivation as such:

to deal with the problem of creating objects without having to specify the exact class of the object that will be created.

And later on:

Creating an object often requires complex processes not appropriate to include within a composing object. The object's creation may lead to a significant duplication of code, may require information not accessible to the composing object, may not provide a sufficient level of abstraction, or may otherwise not be part of the composing object's concerns. The factory method design pattern handles these problems by defining a separate method for creating the objects, which subclasses can then override to specify the derived type of product that will be created.

Ok my assumptions are as follows: I'm writing code, and in my code I want to use the "products" - either a MagicRoom or an OrdinaryRoom. Now, instead of instantiating those in my client code, the Factory pattern says: don't do this! Rather, create another tree of classes which defines a createRoom method which will create the appropriate room. Now, instantiate this object and use createRoom. So I don't understand - if in my client code I don't want to "have to specify the exact class of the object that will be created" - how does this pattern helps me? I still need to specify which "creator" class I want to instantiate?

And as for the second quote about "require information not accessible to the composing object". I also don't understand - what kind of information will be in the creator class (e.g. OrdinaryMazeGame) which is not accessible in the client code?

The only thing I could think of being useful is if in my client code I have a lot of instantiations, and I want to be able to quickly change to another class, then instead of having a lot of room = new MagicRoom which I'll need to change to room = new OrdinaryRoom - I will have a single object with the makeRoom so I'll only need to change the type of this object from MagicMazeGame to OrdinaryMazeGame. Is this the core benefit of this design pattern?

It seems that all the examples out there about Factory Method pattern are so simple that the point of using just doesn't appear in these examples. Can someone give a good example

1 Answers

Imagine you are writing an application for both Windows and MacOS and you want to instantiate a different button based on the OS your user is working on. In your code you would use an if to determine the OS and instantiate the right button afterwards.

Button b;

if (os.isWindows()) {
    b = new WindowsButton();
}
else {
    b = new MacButton();
}

However, if you use this code over and over, and suddenly, you want to support a LinuxButton answell, you would have to find all occurences of this code in your application and extend them.

This is where a factory becomes handy:

public class ButtonFactory {
    public static Button createButton() {
         if (os.isWindows())
             return new WindowsButton();
         else if (os.isMac())
             return new MacButton();
         else
             return new LinuxButton();
    }
}

In your code you would just write

Button b = ButtonFactory.createButton();

Extending this is much simpler and you don't copy any code in this way.

Related