I have been studying design patterns lately. I am struggling with finding a scenario that I can implement builder pattern for that scenario. Has anyone got any example?
Any answer will be much appreciated.
I have been studying design patterns lately. I am struggling with finding a scenario that I can implement builder pattern for that scenario. Has anyone got any example?
Any answer will be much appreciated.
SQLOrm serves as a nice example of combining the builder pattern with a proper set of methodnames making the construction of SQL feel like working with a DSL.
eg
private String getPersonAndmaybePet_JavaStr(boolean personName, boolean isAdult, int[] petTypes) {
StringBuilder sb = new StringBuilder();
// do SELECT
sb.append("SELECT ");
if(personName)
sb.append("person.name,");
if(petTypes != null)
sb.append("pet.*,");
// do FROM
sb.delete(sb.length() - 1, sb.length()); // remove last comma
sb.append(" FROM person,");
if(petTypes != null)
sb.append(" Pet,");
// do WHERE
sb.delete(sb.length() - 1, sb.length()); // remove last comma
sb.append(" WHERE ");
if(isAdult)
sb.append(" person.age >= 18");
else
sb.append(" person.age < 18");
if(petTypes != null) {
StringBuilder commaList = new StringBuilder();
for(int id : petTypes) {
commaList.append(id);
commaList.append(",");
}
commaList.delete(commaList.length() - 1, commaList.length());
sb.append(" AND person.pet_id = pet.id AND pet.pettype IN (" + commaList.toString() + ")");
}
return sb.toString();
}
becomes
private String getPersonAndmaybePet(boolean personName, boolean isAdult, int[] petTypes) {
SelectBuilder qry = new SelectBuilder();
if(personName)
qry.select("person.name").from("person");
if(isAdult)
qry.from("person").where().and("person.age >= 18");
else
qry.from("person").where().and("person.age < 18");
if(petTypes != null) {
qry.select("pet.*").from("Pet") //
.where() //
.and("person.pet_id = pet.id") //
.and("pet.pettype IN (#)", QueryBuilderHelper.numbers(petTypes));
}
return qry.toSql();
}
If you have a very complex object (say something that requires 3, 4 or more different other objects in order to operate), you would use a Builder
to construct this object correctly.
I love to refer here Joshua Bloch and his book Effective Java
.
The builder pattern is a good choice when designing classes whose constructors or static factories would have more than a handful of parameters.
You surely encounter telescopic
constructors such as this one:
Pizza(int size) { ... }
Pizza(int size, boolean cheese) { ... }
Pizza(int size, boolean cheese, boolean pepperoni) { ... }
Pizza(int size, boolean cheese, boolean pepperoni, boolean bacon) { ... }
The problem with it is that at some point, it's hard to remember the right order of the arguments you need and what the relation between all the constructors.
As an alternative (not yet a builder), you can do a classic POJO here:
Pizza pizza = new Pizza(10);
pizza.setCheese(true);
pizza.setPepperoni(true);
pizza.setBacon(true);
But, it's not considered thread safe.
How to solve it? Yes, builder pattern. Consider this:
public class Pizza {
private int size;
private boolean cheese;
private boolean pepperoni;
private boolean bacon;
public static class Builder {
//required
private final int size;
//optional
private boolean cheese = false;
private boolean pepperoni = false;
private boolean bacon = false;
public Builder(int size) {
this.size = size;
}
public Builder cheese(boolean value) {
cheese = value;
return this;
}
public Builder pepperoni(boolean value) {
pepperoni = value;
return this;
}
public Builder bacon(boolean value) {
bacon = value;
return this;
}
public Pizza build() {
return new Pizza(this);
}
}
private Pizza(Builder builder) {
size = builder.size;
cheese = builder.cheese;
pepperoni = builder.pepperoni;
bacon = builder.bacon;
}
}
The instance of Pizza you will create now will be immutable and the constructing of it would be easy and concise.
Pizza pizza = new Pizza.Builder(12)
.cheese(true)
.pepperoni(true)
.bacon(true)
.build();
Check it out for more Java Builder pattern examples.
Consider a builder when faced with many constructor parameters. The following link explains in good detail will clear all doubts as well.
http://www.drdobbs.com/jvm/creating-and-destroying-java-objects-par/208403883?pgno=2
In a nutshell when there are many constructor parameters instead of remembering the order and the meaning of each parameter; builder pattern can be used to simplify parameter passing thereby simplifying programming, improved readability, increased confidence that parameters are passed as intended.
The Builder Pattern is often used to construct HTML and XML documents. Example:
require 'markaby' # Markaby is an HTML builder library for Ruby
builder = Markaby::Builder.new
builder.html {
head {
title 'Sample Title'
link href: 'style.css', rel: 'stylesheet'
}
body {
h1 'Sample Title'
ul {
li 'Item 1'
li 'Item 2'
}
}
}
print builder