Builder pattern

From Wikipedia, the free encyclopedia
Jump to: navigation, search

The builder pattern is a software design pattern. The intention is to abstract steps of construction of objects so that different implementations of these steps can construct different representations of objects. Often, the builder pattern is used to build products in accordance to the composite pattern, a structural pattern.

Contents

[edit] Class diagram

Builder Structure

Builder
Abstract interface for creating objects (product).
Concrete Builder
Provides implementation for Builder. It is an object able to construct other objects. Constructs and assembles parts to build the objects.
Director
The Director class is responsible for managing the correct sequence of object creation. It receives a Concrete Builder as a parameter and executes the necessary operations on it.
Product
The final object that will be created by the Director using Builder.

[edit] Useful tips

[edit] Examples

[edit] Java

/** "Product" */
class Pizza {
	private String dough = "";
	private String sauce = "";
	private String topping = "";
 
	public void setDough(String dough) {
		this.dough = dough;
	}
 
	public void setSauce(String sauce) {
		this.sauce = sauce;
	}
 
	public void setTopping(String topping) {
		this.topping = topping;
	}
}
 
/** "Abstract Builder" */
abstract class PizzaBuilder {
	protected Pizza pizza;
 
	public Pizza getPizza() {
		return pizza;
	}
 
	public void createNewPizzaProduct() {
		pizza = new Pizza();
	}
 
	public abstract void buildDough();
 
	public abstract void buildSauce();
 
	public abstract void buildTopping();
}
/** "ConcreteBuilder" */
class HawaiianPizzaBuilder extends PizzaBuilder {
	public void buildDough() {
		pizza.setDough("cross");
	}
 
	public void buildSauce() {
		pizza.setSauce("mild");
	}
 
	public void buildTopping() {
		pizza.setTopping("ham+pineapple");
	}
}
 
/** "ConcreteBuilder" */
class SpicyPizzaBuilder extends PizzaBuilder {
	public void buildDough() {
		pizza.setDough("pan baked");
	}
 
	public void buildSauce() {
		pizza.setSauce("hot");
	}
 
	public void buildTopping() {
		pizza.setTopping("pepperoni+salami");
	}
}
/** "Director" */
class Cook {
	private PizzaBuilder pizzaBuilder;
 
	public void setPizzaBuilder(PizzaBuilder pb) {
		pizzaBuilder = pb;
	}
 
	public Pizza getPizza() {
		return pizzaBuilder.getPizza();
	}
 
	public void constructPizza() {
		pizzaBuilder.createNewPizzaProduct();
		pizzaBuilder.buildDough();
		pizzaBuilder.buildSauce();
		pizzaBuilder.buildTopping();
	}
}
 
/** A given type of pizza being constructed. */
public class BuilderExample {
	public static void main(String[] args) {
		Cook cook = new Cook();
		PizzaBuilder hawaiianPizzaBuilder = new HawaiianPizzaBuilder();
		PizzaBuilder spicyPizzaBuilder = new SpicyPizzaBuilder();
 
		cook.setPizzaBuilder(hawaiianPizzaBuilder);
		cook.constructPizza();
 
		Pizza hawaiian = cook.getPizza();
 
		cook.setPizzaBuilder(spicyPizzaBuilder);
		cook.constructPizza();
 
		Pizza spicy = cook.getPizza();
	}
}

[edit] A more object oriented version of the Builder in Java

This is an implementation of the Builder pattern using inner classes in Java. The advantage here is that the Product being built does not have to expose setters for its individual components. This gives a better encapsulated Builder.

package builder.innerclass;
 
import builder.innerclass.Pizza.Builder;
 
class Pizza {
 
	private String dough = "";
	private String sauce = "";
	private String topping = "";
 
	public static abstract class Builder {
 
		private Pizza pizza;
 
		public Builder() {
			pizza = new Pizza();
		}
 
		public abstract Builder buildDough();
 
		public abstract Builder buildSauce();
 
		public abstract Builder buildTopping();
 
		public Pizza getPizza() {
			return pizza;
		}
 
		protected void addTopping(String topping) {
			pizza.topping = topping;
		}
 
		protected void addSauce(String sauce) {
			pizza.sauce = sauce;
		}
 
		protected void addDough(String dough) {
			pizza.dough = dough;
		}
	}
}
 
class SpicyPizzaBuilder extends Pizza.Builder {
 
	@Override
	public SpicyPizzaBuilder buildDough() {
		super.addDough("Pan Baked");
		return this;
	}
 
	@Override
	public SpicyPizzaBuilder buildSauce() {
		super.addSauce("hot");
		return this;
	}
 
	@Override
	public SpicyPizzaBuilder buildTopping() {
		super.addTopping("pepperoni+salami");
		return this;
	}
 
}
 
class HawaiianPizzaBuilder extends Pizza.Builder {
 
	@Override
	public Builder buildDough() {
		super.addDough("cross");
		return this;
	}
 
	@Override
	public Builder buildSauce() {
		super.addSauce("mild");
		return this;
	}
 
	@Override
	public Builder buildTopping() {
		super.addTopping("ham+pineapple");
		return this;
	}
 
}
 
class Cook {
 
	private Pizza.Builder pizzaBuilder;
 
	public void constructPizza() {
		pizzaBuilder.buildDough().buildSauce().buildTopping();
	}
 
	public Pizza getPizza() {
		return pizzaBuilder.getPizza();
	}
 
	public void setPizzaBuilder(Builder builder) {
		pizzaBuilder = builder;
 
	}
}
 
public class BuilderExample {
 
	public static void main(String[] args) {
		Pizza.Builder hawaiianPizzaBuilder = new HawaiianPizzaBuilder();
		Pizza.Builder spicyPizzaBuilder = new SpicyPizzaBuilder();
 
		Cook cook = new Cook();
		cook.setPizzaBuilder(hawaiianPizzaBuilder);
 
		cook.constructPizza();
 
		Pizza hawaiian = cook.getPizza();
 
		cook.setPizzaBuilder(spicyPizzaBuilder);
		cook.constructPizza();
 
		Pizza spicy = cook.getPizza();
	}
 
}

[edit] C#

/** "Product" */
class Pizza
{
    public string Dough { get; set; }
    public string Sauce { get; set; }
    public string Topping { get; set; }
}
 
 
/** "Abstract Builder" */
abstract class PizzaBuilder
{
    public Pizza pizza { get; protected set; }
 
    public void CreatePizza()
    {
        pizza = new Pizza();
    }
 
    public abstract void BuildDough();
    public abstract void BuildSauce();
    public abstract void BuildTopping();
}
 
 
/** "ConcreteBuilder" */
class HawaiianPizzaBuilder : PizzaBuilder
{
    public override void BuildDough()
    {
        pizza.Dough = "Cross";
    }
 
    public override void BuildSauce()
    {
        pizza.Sauce = "Mild";
    }
 
    public override void BuildTopping()
    {
        pizza.Topping = "Ham+Pineapple";
    }
}
 
 
/** "ConcreteBuilder" */
class SpicyPizzaBuilder : PizzaBuilder
{
    public override void BuildDough()
    {
        pizza.Dough = "Pan Baked";
    }
 
    public override void BuildSauce()
    {
        pizza.Sauce = "Hot";
    }
 
    public override void BuildTopping()
    {
        pizza.Topping = "Pepperoni+Salami";
    }
}
 
/** "Director" */
class Cook
{
    public PizzaBuilder PizzaBuilder { get; set; }
 
    public Pizza Pizza { get { return PizzaBuilder.pizza; } }
 
    public void MakePizza()
    {
        PizzaBuilder.CreatePizza();
        PizzaBuilder.BuildDough();
        PizzaBuilder.BuildSauce();
        PizzaBuilder.BuildTopping();
    }
}
 
/** A given type of pizza being constructed. */
static void Main(string[] args)
{
    Cook cook = new Cook();
    cook.PizzaBuilder = new SpicyPizzaBuilder();
    cook.MakePizza();
    cook.PizzaBuilder = new HawaiianPizzaBuilder();
    cook.MakePizza();
}

[edit] Python

# Product
class Pizza(object):
    def __init__(self):
        self.dough = None
        self.sauce = None
        self.topping = None
 
# Abstract Builder
class PizzaBuilder(object):
    def __init__(self):
        self.pizza = None
 
    def create_new_pizza_product(self):
        self.pizza = Pizza()
 
# ConcreteBuilder
class HawaiianPizzaBuilder(PizzaBuilder):
    def build_dough(self):
        self.pizza.dough = "cross"
 
    def build_sauce(self):
        self.pizza.sauce = "mild"
 
    def build_topping(self):
        self.pizza.topping = "ham+pineapple"
 
# Director
class Cook(object):
    def __init__(self):
        self.pizza_builder = None
 
    @property
    def pizza(self):
        return self.pizza_builder.pizza
 
    def construct_pizza(self):
        self.pizza_builder.create_new_pizza_product()
        self.pizza_builder.build_dough()
        self.pizza_builder.build_sauce()
        self.pizza_builder.build_topping()
 
# A given type of pizza being constructed.
if __name__ == '__main__':
    cook = Cook()
    cook.pizza_builder = HawaiianPizzaBuilder()
    cook.construct_pizza()
    pizza = cook.pizza

[edit] Delphi

program BuilderPatternExample;
 
{$APPTYPE CONSOLE}
 
uses
  SysUtils;
 
type
  // Product
  TPizza = class(TObject)
  strict private
  	FDough, FSauce, FTopping: string;
  public
    property Dough: string write FDough;
    property Sauce: string write FSauce;
    property Topping: string write FTopping;
    procedure Show();
  end;
 
  // Abstract Builder
  TPizzaBuilder = class(TObject)
  strict protected
    FPizza: TPizza;
  public
    property Pizza: TPizza read FPizza;
 
    constructor Create();
    destructor Destroy(); override;
 
    procedure CreateNewPizzaProduct();
    procedure BuildDough(); virtual; abstract;
    procedure BuildSauce(); virtual; abstract;
    procedure BuildTopping(); virtual; abstract;
  end;
 
  // Concrete Builder A
  THawaiianPizzaBuilder = class(TPizzaBuilder)
  public
    procedure BuildDough(); override;
    procedure BuildSauce(); override;
    procedure BuildTopping(); override;
  end;
 
  // Concrete Builder B
  TSpicyPizzaBuilder = class(TPizzaBuilder)
  public
    procedure BuildDough(); override;
    procedure BuildSauce(); override;
    procedure BuildTopping(); override;
  end;
 
  // Director
  TWaiter = class(TObject)
  strict private
    FPizzaBuilder: TPizzaBuilder;
  public
    property PizzaBuilder: TPizzaBuilder write FPizzaBuilder;
 
    constructor Create();
    destructor Destroy(); override;
    procedure ConstructPizza();
    function GetPizza(): TPizza;
  end;
 
{ TPizza }
 
procedure TPizza.Show();
begin
  WriteLn('Pizza with Dough as ' + FDough + ', sauce as ' + FSauce + ' and Topping as ' + FTopping + '!');
end;
 
{ TPizzaBuilder }
 
constructor TPizzaBuilder.Create();
begin
  FPizza := nil;
end;
 
destructor TPizzaBuilder.Destroy();
begin
  if FPizza <> nil then
    FPizza.Free();
  inherited Destroy();
end;
 
procedure TPizzaBuilder.CreateNewPizzaProduct();
begin
  if FPizza <> nil then
    FPizza.Free();
  FPizza := TPizza.Create();
end;
 
{ THawaiianPizzaBuilder }
 
procedure THawaiianPizzaBuilder.BuildDough();
begin
  if FPizza <> nil then
    FPizza.Dough := 'cross';
end;
 
procedure THawaiianPizzaBuilder.BuildSauce();
begin
  if FPizza <> nil then
    FPizza.Sauce := 'mild';
end;
 
procedure THawaiianPizzaBuilder.BuildTopping();
begin
  if FPizza <> nil then
    FPizza.Topping := 'ham and pineapple';
end;
 
{ TSpicyPizzaBuilder }
 
procedure TSpicyPizzaBuilder.BuildDough();
begin
  if FPizza <> nil then
    FPizza.Dough := 'pan baked';
end;
 
procedure TSpicyPizzaBuilder.BuildSauce();
begin
  if FPizza <> nil then
    FPizza.Sauce := 'hot';
end;
 
procedure TSpicyPizzaBuilder.BuildTopping();
begin
  if FPizza <> nil then
    FPizza.Topping := 'pepperoni and salami';
end;
 
{ TWaiter }
 
constructor TWaiter.Create();
begin
  FPizzaBuilder := nil;
end;
 
destructor TWaiter.Destroy();
begin
  FPizzaBuilder := nil;
  inherited Destroy();
end;
 
procedure TWaiter.ConstructPizza();
begin
  if FPizzaBuilder <> nil then
  begin
    FPizzaBuilder.CreateNewPizzaProduct();
    FPizzaBuilder.BuildDough();
    FPizzaBuilder.BuildSauce();
    FPizzaBuilder.BuildTopping();
  end;
end;
 
function TWaiter.GetPizza(): TPizza;
begin
  if FPizzaBuilder <> nil then
    Result := FPizzaBuilder.Pizza
  else
    Result := nil;
end;
 
var
  Waiter: TWaiter;
  HawaiianPizzaBuilder: THawaiianPizzaBuilder;
  SpicyPizzaBuilder: TSpicyPizzaBuilder;
  Pizza: TPizza;
 
begin
  HawaiianPizzaBuilder := THawaiianPizzaBuilder.Create();
  SpicyPizzaBuilder := TSpicyPizzaBuilder.Create();
  Waiter := TWaiter.Create();
 
  // Client has ordered two pizzas
  // Pizza "A"
  Waiter.PizzaBuilder := HawaiianPizzaBuilder;
  Waiter.ConstructPizza();
  Pizza := Waiter.GetPizza();
  Pizza.Show();
  Pizza.Free();
  //Pizza "B"
  Waiter.PizzaBuilder := SpicyPizzaBuilder;
  Waiter.ConstructPizza();
  Pizza := Waiter.GetPizza();
  Pizza.Show();
  Pizza.Free();
  ReadLn;
 
  Waiter.Free();
  HawaiianPizzaBuilder.Free();
  SpicyPizzaBuilder.Free();
end.

[edit] External links

Personal tools
Namespaces
Variants
Actions
Navigation
Interaction
Toolbox
Print/export
Languages