Строител (шаблон)

Строител (Builder) е създаващ шаблон за дизайн, който се използва в обектно-ориентираното програмиране.

Целта е да се раздели създаването на сложен обект от неговото представяне (интерфейс), за да може с един и същ процес да се създават обекти с различно представяне.

UML диаграма на шаблона Строител
// Реализация на C++.

#include <iostream>
#include <memory>
#include <string>

// Product
class Pizza
{
private:
 std::string dough;
 std::string sauce;
 std::string topping;

public:
 Pizza() { }
 ~Pizza() { }

 void SetDough(const std::string& d) { dough = d; };
 void SetSauce(const std::string& s) { sauce = s; };
 void SetTopping(const std::string& t) { topping = t; }

 void ShowPizza()
 {
 std::cout << " Yummy !!!" << std::endl
 << "Pizza with Dough as " << dough
 << ", Sauce as " << sauce
 << " and Topping as " << topping
 << " !!! " << std::endl;
 }
};

// Abstract Builder
class PizzaBuilder
{
protected:
 std::auto_ptr<Pizza> pizza;
public:
 PizzaBuilder() {}
 virtual ~PizzaBuilder() {}
 std::auto_ptr<Pizza> GetPizza() { return pizza; }

 void createNewPizzaProduct() { pizza.reset (new Pizza); }

 virtual void buildDough()=0;
 virtual void buildSauce()=0;
 virtual void buildTopping()=0;

};

// ConcreteBuilder
class HawaiianPizzaBuilder : public PizzaBuilder
{
public:
 HawaiianPizzaBuilder() : PizzaBuilder() {}
 ~HawaiianPizzaBuilder(){}

 void buildDough() { pizza->SetDough("cross"); }
 void buildSauce() { pizza->SetSauce("mild"); }
 void buildTopping() { pizza->SetTopping("ham and pineapple"); }
};

// ConcreteBuilder
class SpicyPizzaBuilder : public PizzaBuilder
{
public:
 SpicyPizzaBuilder() : PizzaBuilder() {}
 ~SpicyPizzaBuilder() {}

 void buildDough() { pizza->SetDough("pan baked"); }
 void buildSauce() { pizza->SetSauce("hot"); }
 void buildTopping() { pizza->SetTopping("pepperoni and salami"); }
};

// Director
class Waiter
{
private:
 PizzaBuilder* pizzaBuilder;
public:
 Waiter() : pizzaBuilder(NULL) {}
 ~Waiter() { }

 void SetPizzaBuilder(PizzaBuilder* b) { pizzaBuilder = b; }
 std::auto_ptr<Pizza> GetPizza() { return pizzaBuilder->GetPizza(); }
 void ConstructPizza()
 {
 pizzaBuilder->createNewPizzaProduct();
 pizzaBuilder->buildDough();
 pizzaBuilder->buildSauce();
 pizzaBuilder->buildTopping();
 }
};

// Клиент поръчва 2 пици
int main()
{
 Waiter waiter;

 HawaiianPizzaBuilder hawaiianPizzaBuilder;
 waiter.SetPizzaBuilder (&hawaiianPizzaBuilder);
 waiter.ConstructPizza();
 std::auto_ptr<Pizza> pizza = waiter.GetPizza();
 pizza->ShowPizza();

 SpicyPizzaBuilder spicyPizzaBuilder;
 waiter.SetPizzaBuilder(&spicyPizzaBuilder);
 waiter.ConstructPizza();
 pizza = waiter.GetPizza();
 pizza->ShowPizza();

 return EXIT_SUCCESS;
}
 using System;
 using System.Collections;

 namespace Builder
 {

 public class MainApp
 {
 public static void Main()
 {
 // Create director and builders
 Director director = new Director();

 Builder b1 = new ConcreteBuilder1();
 Builder b2 = new ConcreteBuilder2();

 // Construct two products
 director.Construct(b1);
 Product p1 = b1.GetResult();
 p1.Show();

 director.Construct(b2);
 Product p2 = b2.GetResult();
 p2.Show();

 // Wait for user
 Console.Read();
 }
 }

 // "Director"

 class Director
 {
 // Builder uses a complex series of steps
 public void Construct(Builder builder)
 {
 builder.BuildPartA();
 builder.BuildPartB();
 }
 }

 // "Builder"

 abstract class Builder
 {
 public abstract void BuildPartA();
 public abstract void BuildPartB();
 public abstract Product GetResult();
 }

 // "ConcreteBuilder1"

 class ConcreteBuilder1 : Builder
 {
 private readonly Product product = new Product();

 public override void BuildPartA()
 {
 product.Add("PartA");
 }

 public override void BuildPartB()
 {
 product.Add("PartB");
 }

 public override Product GetResult()
 {
 return product;
 }
 }

 // "ConcreteBuilder2"

 class ConcreteBuilder2 : Builder
 {
 private readonly Product product = new Product();

 public override void BuildPartA()
 {
 product.Add("PartX");
 }

 public override void BuildPartB()
 {
 product.Add("PartY");
 }

 public override Product GetResult()
 {
 return product;
 }
 }

 // "Product"

 class Product
 {
 private readonly ArrayList parts = new ArrayList();

 public void Add(string part)
 {
 parts.Add(part);
 }

 public void Show()
 {
 Console.WriteLine("\nProduct Parts -------");
 foreach (string part in parts)
 Console.WriteLine(part);
 }
 }
 }
 /** "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 Waiter {
 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();
 }
 }

 /** Клиент поръчва пица. */
 class BuilderExample {
 public static void main(String[] args) {
 Waiter waiter = new Waiter();
 PizzaBuilder hawaiian_pizzabuilder = new HawaiianPizzaBuilder();
 PizzaBuilder spicy_pizzabuilder = new SpicyPizzaBuilder();

 waiter.setPizzaBuilder(hawaiian_pizzabuilder);
 waiter.constructPizza();

 Pizza pizza = waiter.getPizza();
 }
 }
/* Produit */
class Pizza {
 private $_pate = "";
 private $_sauce = "";
 private $_garniture = "";

 public function setPate($pate) { $this->_pate = $pate; }
 public function setSauce($sauce) { $this->_sauce = $sauce; }
 public function setGarniture($garniture) { $this->_garniture = $garniture; }
}

/* Monteur */
abstract class MonteurPizza {
 protected $_pizza;

 public function getPizza() { return $this->_pizza; }
 public function creerNouvellePizza() { $this->_pizza = new Pizza(); }

 abstract public function monterPate();
 abstract public function monterSauce();
 abstract public function monterGarniture();
}

/* MonteurConcret */
class MonteurPizzaHawaii extends MonteurPizza {
 public function monterPate() { $this->_pizza.setPate("croisée"); }
 public function monterSauce() { $this->_pizza.setSauce("douce"); }
 public function monterGarniture() { $this->_pizza.setGarniture("jambon+ananas"); }
}

/* MonteurConcret */
class MonteurPizzaPiquante extends MonteurPizza {
 public function monterPate() { $this->_pizza.setPate("feuilletée"); }
 public function monterSauce() { $this->_pizza.setSauce("piquante"); }
 public function monterGarniture() { $this->_pizza.setGarniture("pepperoni+salami"); }
}

/* Directeur */
class Serveur {
 private $_monteurPizza;

 public function setMonteurPizza(MonteurPizza $mp) { $this->_monteurPizza = $mp; }
 public function getPizza() { return $this->_monteurPizza->getPizza(); }

 public void construirePizza() {
 $this->_monteurPizza->creerNouvellePizza();
 $this->_monteurPizza->monterPate();
 $this->_monteurPizza->monterSauce();
 $this->_monteurPizza->monterGarniture();
 }
}

/* Клиент поръчва пица. */
$serveur = new Serveur();
$monteurPizzaHawaii = new MonteurPizzaHawaii();
$monteurPizzaPiquante = new MonteurPizzaPiquante();

$serveur->setMonteurPizza($monteurPizzaHawaii);
$serveur->construirePizza();

$pizza = $serveur->getPizza();