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.

Implementation


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");
	}
}