Continuing the series of posts about design patterns, we will talk about builder pattern in this post. Builder pattern is of type creational design pattern. One of the major uses of Builder pattern is when there are too many constructor parameters to handle.
In my previous post, I showed how to use factory pattern.
When to use Builder Pattern?
Builder pattern enforces a step-by-step approach to create a complex object. The object can not be used till it’s a finished product. It helps to encapsulate complex creation logic. One of the examples from real time is file creation with a format. If you are creating a file in certain format (example xml, csv), you can use builder pattern to create a simple logical approach to creating the file.
How to use Builder Pattern?
Lately working on a project to build an EDI file to transfer between customer, I have to create a file of format 834. So 834 file format varies according to different health insurance carrier. This file format contains headers, records and trailers. Headers indicate different paradigm about the file and the customer and who is sending it. To show example of this pattern, I will use one of the headers of this file format and how it can be created using builder pattern.
One of the headers is called the Transactional Group Header. This header looks like below in a real file
ST*834*5432853*005010X220A1~
First field “ST” indicates that it is a transactional group. All the records for one customer can lie between ST and SE. 834 is a transaction code for file format. Since this is 834 file format, code is 834. 5432853 is a unique transaction control number, this can be anything between 4 digits in length to a maximum 9 digits in length. 005010X220A1 is an implementation reference number.
Our implementation of the class with have fields for each of these fields from a header, a private constructor and a static builder class. This is shown below:
public class TransactionalHeader implements Serializable { private static final long serialVersionUID = 7517644545656169045L; private String st; private String transactioncode; private String transactioncontrolnumber; private String implementationreference; public static class Builder { private String st; private String transactioncode; private String transactioncontrolnumber; private String implementationreference; public Builder st(String st) { this.st = st; return this; } public Builder transactioncode(String transactioncode) { this.transactioncode = transactioncode; return this; } public Builder transactioncontrolnumber(String transactioncontrolnumber) { this.transactioncontrolnumber = transactioncontrolnumber; return this; } public Builder implementationreference(String implementationreference) { this.implementationreference = implementationreference; return this; } public TransactionalHeader build() { return new TransactionalHeader(this); } } private TransactionalHeader(Builder builder) { this.st = builder.st; this.transactioncode = builder.transactioncode; this.transactioncontrolnumber = builder.transactioncontrolnumber; this.implementationreference = builder.implementationreference; } public String toString() { String result = ""; StringBuffer sb = new StringBuffer(); sb.append(st); sb.append(FileUtil.FIELD_SPLITTER); sb.append(transactioncode); sb.append(FileUtil.FIELD_SPLITTER); sb.append(transactioncontrolnumber); sb.append(FileUtil.FIELD_SPLITTER); sb.append(implementationreference); sb.append("~"); result = sb.toString(); return result; } }
This was our builder class. Let’s create a demo class that will use this builder class to build an object that will give us a transactional header in the file. This will look like below:
public String getTransactionalHeader() { String result = ""; TransactionalHeader th = new TransactionalHeader.Builder() .st("ST") .transactioncode(TRANSACTION_IDENTIFIER_CODE) .transactioncontrolnumber(FileUtil.getTransactionControlNumber()) .implementationreference("005010X220A1").build(); result = th.toString(); return result; }
Conclusion
In this way, we can use builder design patterns to construct complex objects. One of the easy ways to identify when to use this design pattern is when you have more than 4 or more parameters in your constructor.
The code for this post is available to download here.
Pingback: Design Pattern – Prototype Pattern – Part VI | Code Complete