rahul
rahul

Reputation: 6487

Factory Method: Need of Creator hierarchy

I am new to design patterns. While going through GOF, one way to implement factory pattern is to create a parallel hierarchy of creators (factories) corresponding to each product. Why do we need this hierarchy? Does it not create unnecessary sub classes? Can someone please give me an example where we need this kind of implementation.

Upvotes: 1

Views: 143

Answers (1)

Terry
Terry

Reputation: 14897

You need this pattern if you do not wish to make your decision about what object you want to create in the context where you use them, but want to postpone it. You can use the factory pattern to postpone the decision to runtime.

Here is an example (a little bit oversimplified, but I hope you get the point):

You want to write a program that is creating NumberObjects, and you want to have either a simple kind of them, or a complex one. But you don't want to hardcode the decision which kind of number object to use in your program, but want to make it depending on the command line arguments for you program.

First, you create 2 classes SimpleNumberObject and ComplexNumberObject, both implementing the class NumberObject that has an abstract method print() and obliges the child classes to implement it. Something like:

public class NumberObject {
    protected int number;
    public NumberObject(int number) {
        this.number = number;
    }
    abstract void print();
}

public class SimpleNumberObject extends NumberObject {
    public SimpleNumberObject(int number) {
        super(number);
    }        
    public void print() {
        System.out.println("My number is " + number);
    }
}

public class ComplexNumberObject() extends NumberObject {
    public SimpleNumberObject(int number) {
        super(number);
    }        
    public void print() {
        System.out.println("My number is " + number 
            + " and I can do a lot more complex stuff");
    }
}

Then you create the abstract class NumberFactory, with the method createNumber() and the child classes SimpleNumberFactory and ComplexNumberFactory, that have to implement this method, where they return the respective NumberObject: SimpleNumberFactory a SimpleNumberObject and ComplexNumberFactory a ComplexNumberObject.
(I will skip the implementation here, if you need it for understanding let me know then I can put it too.)

Then, you design your main class, where you deside in the constructor if it's going to use SimpleNumberObject or ComplexNumberObject.

public class MainClass {

    private NumberFactory numberFactory;

    public MainClass(String arg) {
        if (arg != null && arg.equals("complex") {
            numberFactory = new ComplexNumberFactory();
        } else {
            numberFactory = new SimpleNumberFactory();
        }
    }

    public void printSomeNumber() {
        NumberObject number = numberFactory.createNumber();
        number.print();
    }

    public static void main(String[] args) {
        MainClass mainClass = new MainClass(args[0]);
        mainClass.printSomeNumber();
    }
}

So what happens here is that according to what the command line argument is, it will create either SimpleNumberObjects or ComplexNumberObjects. You didn't specify it in the code, so the compiler can't tell what object will be used, just that it implements NumberObject.

With the Factories, you were giving the responsibility away from MainClass how to create a number. They may use a random generator to produce the integer the NumberObject constructor needs, or some iterative number. Fact is, the main class doesn't need to care, and you decoupled it a bit.

About the postponing of the decision what object to create: it doesn't necessarily have to be the command line argument, but can be a different class, some context information, or something else. Basically, you use this pattern if you want to make the decision somewhere else, and of course if you want to delegate the creation of an object to a factory.

You are right that there is a lot of subclassing going on, which makes this pattern kind of class-heavy. In practice you have to decide whether it pays off to use it or not. If you are going to use a factory for object creation anyway, you have different object subclasses anyway, and it is important for you that you do not make the decision about which subclass to create at a certain point in your program, then you might consider using it.

Upvotes: 1

Related Questions