4

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.

Pinchy
  • 1,506
  • 8
  • 28
  • 49

5 Answers5

4

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();
}
Mia Clarke
  • 8,134
  • 3
  • 49
  • 62
Carlo V. Dango
  • 13,322
  • 16
  • 71
  • 114
  • -1 Strictly speaking this is not the Design Pattern Builder. It is only a helper class to construct a string! A builder is used to construct a graph of objects having different types (not just strings). However the usage of the "builder" in your example is very similar to the pattern. (I did not mod you down, though) – Angel O'Sphere Jun 03 '11 at 13:18
  • 1
    @Angel O'Sphere: +1 This is a good example. Now, this implementation constructs a string. But who said if another implementation cannot construct an expression tree that can be combined with another, simplified etc. And this -- different possible results from different builders with the same interface -- is the most important benefit of clasic builder pattern. – Tomek Szpakowicz Jul 06 '11 at 09:21
1

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.

Oded
  • 489,969
  • 99
  • 883
  • 1,009
1

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.

Johnny
  • 14,397
  • 15
  • 77
  • 118
0

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.

jaamit
  • 393
  • 3
  • 11
0

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
Jörg W Mittag
  • 363,080
  • 75
  • 446
  • 653
  • Like the previous answer ... this is not the "Design Pattern Builder". It is only a class with "Builder" in it's name. The pattern is used to construct complex object graphs, not simply strings. – Angel O'Sphere Jun 03 '11 at 13:19