Creational Design Patterns


Creational design patterns are design patterns that deal with object creation mechanisms - defining ways of creating objects in a manner suitable to the situation. The basic form of object creation could result in design problems or added complexity to the design. Creational design patterns solve this problem by controlling this object creation.

Factory


This is the most fundamental creational pattern. All others are extensions of this pattern.

Most object oriented programming languages provide a new operator (or its equivalent) that is used to instantiate an object of the given class. This is the simplest way of creating instances (the Java reflection API can be used to create instances - but that is certainly not simple)

But there are occasions when it is important to control the instantiation. We might want to ensure instantiation in groups, or we want to limit the number of objects, we want to simplify the API . . There are many different scenarios when we need to do this. In such a case, the new operator gives away the control to the caller and then it is very difficult to ensure that we live up to the constraints.

The Factory Method is meant to take care of such scenarios. Essentially, Factory method is a method that takes care of instantiating the object. It contains the complexity of instantiation and any other functionality that goes along with it.

Factory method or any creational pattern does not mean that we have a good design. The Factory Method is not necessarily the best way of creating instances. The "new" operator is usually the best way of doing the job - that is why languages provide it. It is important to understand when and which creational pattern is required.

Let us now look at how the Factory Method pattern in implemented in code:

public interface Product { … }

public abstract class Creator {
	public void anOperation() 	{
		Product product = factoryMethod();
	}
	
	protected abstract Product factoryMethod();
}

public class ConcreteProduct implements Product { … }

public class ConcreteCreator extends Creator {
	protected Product factoryMethod() {
		return new ConcreteProduct();
	}
}

public class Client {
	public static void main( String arg[] ) {
		Creator creator = new ConcreteCreator();
		creator.anOperation();
	}
}

Abstract Factory


The Abstract Factory pattern is another level of abstraction above the Factory pattern. The Factory pattern provides for a Factory object that can be used to instantiate product objects based on the parameters. The Factory Method returns objects that are instances of the abstract product class.

But Abstract Factory takes this a level further. Here, the Factory itself is an instance of an abstract factory class - contained in it.

The client invokes factory method in the container abstract factory. Based on the parameter, this in turn invokes the factory method in one of the concrete factory classes. This generates the object that is returned to the client

Let us now look at how the Abstract Factor pattern in implemented in code:

abstract class AbstractProductA {
	public abstract void operationA1();
	public abstract void operationA2();
}

class ProductA1 extends AbstractProductA {
	ProductA1(String arg){
		System.out.println("Hello "+arg);
	} // Implement the code here
	public void operationA1() { };
	public void operationA2() { };
}

class ProductA2 extends AbstractProductA {
	ProductA2(String arg) {
		System.out.println("Hello "+arg);
	} // Implement the code here
	public void operationA1() { };
	public void operationA2() { };
}

abstract class AbstractProductB {
	public abstract void operationB1();
	public abstract void operationB2();
}

class ProductB1 extends AbstractProductB {
	ProductB1(String arg){
		// Implement the code here
		System.out.println("Hello "+arg);
	} 
}

class ProductB2 extends AbstractProductB {
	ProductB2(String arg){
		// Implement the code here
		System.out.println("Hello "+arg);
	} 
}

abstract class AbstractFactory {
	abstract AbstractProductA createProductA();
	abstract AbstractProductB createProductB();
}

class ConcreteFactory1 extends AbstractFactory {
	AbstractProductA createProductA() {
		return new ProductA1("ProductA1");
	}
	AbstractProductB createProductB() {
		return new ProductB1("ProductB1");
	}
}

class ConcreteFactory2 extends AbstractFactory {
	AbstractProductA createProductA() {
		return new ProductA2("ProductA2");
	}
	AbstractProductB createProductB() {
		return new ProductB2("ProductB2");
	}
}

//Factory creator - an indirect way of instantiating the factories
class FactoryMaker {
	private static AbstractFactory pf=null;
	static AbstractFactory getFactory(String choice) {
		if (choice.equals("a")) {
			pf=new ConcreteFactory1();
		} else if (choice.equals("b")) {
				pf=new ConcreteFactory2();
		} return pf;
	}
}

// Client
public class Client{
	public static void main(String args[]) {
		AbstractFactory pf=FactoryMaker.getFactory("a");
		AbstractProductA product=pf.createProductA();
		//more function calls on product
	}
}

Singleton


This is one of the simplest of the Creation Patterns. Singleton is a class that has only one instance - and cannot have more instances. This is useful when we want to contain a consistent functionality for the entire application.

Most programming languages do not provide a direct support for this functionality. Any code with visibility to a class can instantiate it to get an object - using the new operator. For ensuring that a class has only one instance, we have to ensure that nobody can invoke the constructor. To ensure this, the constructor has to be a private member of the class.

With this in place, we can provide a method that helps a caller with the instance of the class. This method has to make sure that it allows only one instance and returns the same instance if there are multiple calls to the method. Often this needs to be thread safe.

Thus, the getInstance() is a public static method that returns the only object of the class. Now the question is, when is this single object created? Typically there are two implementations for this - eager and lazy. The eager implementation instantiates the object much before it is required - perhaps in a static block. The lazy implementation does this only on the first call to the getInstance() method.

Let us now look at how the Singleton pattern in implemented in code:

class Singleton {
	private static Singleton instance = new Singleton();

	private Singleton() {
		System.out.println("Singleton(): Initializing Instance");
	}

	public static Singleton getInstance() {    
		return instance;
	}

	public void doSomething() {
		System.out.println("doSomething(): Singleton does something!");
	}
}

Builder Pattern


One of the principles of good design is that we do not crunch too much complexity into a single unit of the code, and any unit of the code is always focused on a consistent isolated part of the functionality. This is the core inspiration behind the Builder pattern.

If we want a class to be extremely configurable, the process of construction gets complicated too. There are two ways of doing this - either have a complex constructor that takes in a parameter and interprets it into the various configuration parameters. Or we have the invoking code use setters to configure each part.

Both approaches are bad. When the class itself has intense functionality, the constructor should not be so complex. And having the process of configuration spread all over the code makes it impossible to maintain.

The builder pattern is the best way of handling such a scenario. Here, we implement another "Builder" class that takes care of instantiating and configuring the objects of the given class. The Builder class provides a Factory method that takes returns a configured object based on the input parameter. That separates the complexity of construction from the complexity of functionality. Also, it ensures that the complexity of configuration is localized and easy to maintain.

Let us now look at how the Builder pattern in implemented in code:

//Abstract Builder
class abstract class TextConverter {
	abstract void convertCharacter(char c);
	abstract void convertParagraph();
}

// Product
class ASCIIText {
	public void append(char c){ //Implement the code here }
}

//Concrete Builder
class ASCIIConverter extends TextConverter {
	ASCIIText asciiTextObj;//resulting product

	/*converts a character to target representation and appends to the resulting*/
	object void convertCharacter(char c){
		char asciiChar = new Character(c).charValue();
			//gets the ascii character
		asciiTextObj.append(asciiChar);
	}
	void convertParagraph(){}
	ASCIIText getResult(){
		return asciiTextObj;
	}
}

//This class abstracts the document object
class Document {
	static int value;
	char token;
	public char getNextToken(){
		//Get the next token
		return token;
	}
}

//Director
class RTFReader {
	private static final char EOF='0'; //Delimitor for End of File
	final char CHAR='c';
	final char PARA='p';
	char t;
	TextConverter builder;
	RTFReader(TextConverter obj) {
		builder=obj;
	}
	void parseRTF(Document doc) {
		while ((t=doc.getNextToken())!= EOF){
			switch (t){
				case CHAR: builder.convertCharacter(t);
				case PARA: builder.convertParagraph();
			}
		}
	}
}

//Client
public class Client {
	void createASCIIText(Document doc) {
		ASCIIConverter asciiBuilder = new ASCIIConverter();
		RTFReader rtfReader = new RTFReader(asciiBuilder);
		rtfReader.parseRTF(doc);
		ASCIIText asciiText = asciiBuilder.getResult();
	}
	public static void main(String args[]) {
		Client client=new Client();
		Document doc=new Document();
		client.createASCIIText(doc);
		system.out.println("This is an example of Builder Pattern");
	}
}

Prototype Pattern


This creational pattern addresses another design problem. There are times when instantiating an object is a very costly operation. It is not possible to go through the entire process again and again. At the same time, we do need many instances of the class. The Prototype pattern is used to address such constraints.

Prototype is based on cloning. The Factory class contains individual instances of the different configurations of the product class. Based on the parameters passed to the factory method, it clones the particular object and passes on an instance.

Now here is the catch. How deep should we clone it? We chose cloning because we wanted it to be easier and faster. But if the cloning itself gets complicated, then we are defeating the purpose. On the other hand, if we make a very shallow clone, then we defeat the purpose of cloning itself!

That depends upon the required functionality. Prototype is very useful when the actual object is trivially simple, but it requires extreme processing to instantiate. We can avoid that processing by using a prototype pattern.

Consider for example, if we are working on implementing an image processing algorithm. If we want to an object that contains the convolution matrix built out of these images. We want to use this matrix to perform a lot more processing. It is a meaningless effort to rework the convolutions again and again. Also, it is not possible to do all the processing on one instance of this matrix - because the processing will destroy the current data. The Prototype pattern can help us solve such a problem.

The Prototype holder can evaluate the matrices for once and hold them within it. On every call to the factory method, it can return a cloned copy of this matrix. The caller can then mess with this copy without disrupting what is contained in the container. Next time we need the matrix, we can just invoke the factory method once again.

Let us now look at how the Prototype pattern in implemented in code:

public interface Prototype {
	public abstract Object clone ( );
}

public class ConcretePrototype implements Prototype {
	public Object clone() {
		return super.clone();
	}
}

public class Client {
	public static void main( String arg[] ) {
		ConcretePrototype obj1= new ConcretePrototype ();
		ConcretePrototype obj2 = ConcretePrototype)obj1.clone();
	}
}