Home

planets

Objects are generally in charge of their own initialisation. Is there another way? Here are a few alternative creation patterns, which are sometimes superior.

Factory and Abstract Factory

The Factory Pattern is extremely simple – it has a class called Factory with a method that returns brand new Parts:

class Client {
    Client() {
        Factory f = new Factory();
        Part p = getNewPart();
    }
}

class Factory {

    Part getNewPart() {
        Part p = new Part();
        // (Lots of complex initialisation here)

        return p;
    }
}

class Part {}

There are many reasons for doing this:

  • The creation of one object follows on in some way from another
  • The creation process itself requires expensive initialisation, which does not need to happen for each object created
  • The creation process requires access to objects that ought to be out of scope for the object created
  • It is important to keep track of all objects created of the given type
  • The instantiation is highly complex and would make the class too big

Sometimes the factory will have several methods to produce different subclasses of Part.

There is a slightly more complicated version called the Abstract Factory Pattern:

class Client {
    Client(Factory f) {
        Part p = f.getNewPart();
    }
}

// Interfaces
interface Part {}

interface Factory {
    Part getNewPart();
}

// Implementations of the interfaces
class ConcretePart implements Part {}

class ConcreteFactory implements Factory {
    Part getNewPart() {
        ConcretePart p = new ConcretePart();
        // (Lots of complex initialisation here)

        return p;
    }
}

This has the advantage that the client class doesn’t need to know what implementation of Part it’s using.

Builder

If your Factory’s construction process is complicated and the sections that vary from part to part are modular, it might be worth bringing in the Builder Pattern. This is often the case with the Composite Pattern.

There are three classes in the Builder Pattern. The Director (which is a standard part to coordinate the building), the Builder (which is an interchangeable part depending on what you want to produce) and the Part that is produced.

class Client {
    Client(PartBuilder builder) {
        Director d = new Director();

        // Make a single part
        d.setPartBuilder(new ConcretePartBuilder());
        d.construct();
        Part p = d.getPart();
    }
}

class Director
    PartBuilder builder;

    void setPartBuilder(PartBuilder builder) {
        this.builder = builder;
    }

    void construct() {
        builder.buildPartA();
        // (Some other initialisation)
        builder.buildPartB();
        // (Some other initialisation)
    }

    Part getPart() {
        return builder.getPart();
    }
}

abstract class PartBuilder {
    Part p;
    abstract void buildSubPartA();
    abstract void buildSubPartB();
}
class ConcretePartBuilder {
    void buildPartA() {
        p.subPartA = new Integer(3);
        // (Further initialisation for partA)
    }

    void buildPartB() {
        p.partB = new Float(4.5f);
        // (Further initialisation for partB)
    }
}

class Part {
    Object PartA;
    Object PartB;
}

Singleton

The Singleton Pattern insists that there is only ever one object of this type in memory.

public enum Singleton {
    INSTANCE;

    private Object exampleField;

    public Object getField() {
        return exampleField;
    }
}

Java guarantees that an enum is instantiated only once, and enums are globally available. The method is called through Singleton.INSTANCE.getField().

It has to be said that having global state is rarely a good thing. It makes testing difficult as any class might be interfering. The Singleton Pattern is essentially an example of global state, as you might infer from its use of static variables. It is criticised for being an anti pattern, often enforcing a single copy of objects for no good reason. I am a pragmatic programmer and, if you feel you know what you’re doing, knock yourself out with Singletons. Just be wary of how much global state you’re accumulating since this basically goes against every fibre of my being.

Prototype

If the initialisation of an object is expensive, there’s no reason to do it more than once. In this pattern, a new object is simply a clone of the prototype.

class Prototype implements Cloneable {
    Prototype() {
        // (Expensive initialisation)
    }

    void methodA() {}

    @Override
    Prototype clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

This probably calls for a side note on cloning. If you were to make a clone of a Car object with four Tyre members, you would, of course, also need to clone each of the Tyres. On the other hand, you would probably not want to clone the World object that the car also happens to have a reference to (especially as the World object also happens to have the Car object as a member). Cloning therefore has to be very carefully implemented for objects of any complexity.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s