Строитель (шаблон проектирования)

28-04-2021, 22:39

Строитель (англ. Builder) — порождающий шаблон проектирования предоставляет способ создания составного объекта.

Цель

Отделяет конструирование сложного объекта от его представления так, что в результате одного и того же процесса конструирования могут получаться разные представления.

Плюсы

  • позволяет изменять внутреннее представление продукта;
  • изолирует код, реализующий конструирование и представление;
  • дает более тонкий контроль над процессом конструирования.

Минусы

  • алгоритм создания сложного объекта не должен зависеть от того, из каких частей состоит объект и как они стыкуются между собой;
  • процесс конструирования должен обеспечивать различные представления конструируемого объекта.

Применение

Объекты «моникер» в COM есть Строители, инициализируемые строкой. Более того, для их создания используется другой Строитель — MkParseDisplayNameEx, который определяет по строке класс моникера, создает моникер и инициализирует его этой же строкой.

Один из этих объектов, URL Moniker, используется для всей загрузки страниц, вложений и документов в Microsoft Internet Explorer.

Примеры

Java

Исходный текст на языке 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 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(); } } /** A customer ordering a pizza. */ public class BuilderExample { public static void main(String[] args) { Waiter waiter = new Waiter(); PizzaBuilder hawaiianPizzaBuilder = new HawaiianPizzaBuilder(); waiter.setPizzaBuilder(hawaiianPizzaBuilder); waiter.constructPizza(); Pizza pizza = waiter.getPizza(); } }


Исходный текст на языке Java // паттерн Builder public class NutritionFacts { private final int servingSize; private final int servings; private final int calories; private final int fat; private final int sodium; private final int carbohydrate; public static class Builder { // Обязательные параметры private final int servingSize; private final int servings; // Дополнительные параметры - инициализируются значениями по умолчанию private int calories = 0; private int fat = 0; private int carbohydrate = 0; private int sodium = 0; public Builder(int servingSize, int servings) { this.servingSize = servingSize; this.servings = servings; } public Builder calories(int val) { calories = val; return this; } public Builder fat(int val) { fat = val; return this; } public Builder carbohydrate(int val) { carbohydrate = val; return this; } public Builder sodium(int val) { sodium = val; return this; } public NutritionFacts build() { return new NutritionFacts(this); } } private NutritionFacts(Builder builder) { servingSize = builder.servingSize; servings = builder.servings; calories = builder.calories; fat = builder.fat; sodium = builder.sodium; carbohydrate = builder.carbohydrate; } } // usage NutritionFacts cocaCola = new NutritionFacts .Builder(240, 8) .calories(100) .sodium(35) .carbohydrate(27) .build();


Scala

Исходный текст на языке Scala package com package object builder { class Pizza { private var dough: String = "" private var sauce: String = "" private var topping: String = "" def setDough(dough: String) : Unit = { this.dough = dough } def setSauce(sauce: String) : Unit = { this.sauce = sauce } def setTopping(topping: String) : Unit = { this.topping = topping } def outputReceipt() : Unit = { println(s"Dough: $dough Sauce: $sauce Topping: $topping") } } abstract class AbstractPizzaBuilder { protected var pizza : Option[Pizza] = None def getPizza : Option[Pizza] = pizza def createPizza() : Unit = { pizza = Some(new Pizza) } def buildDough() : Unit def buildSauce() : Unit def buildTopping() : Unit } class HawaiianPizzaBuilder extends AbstractPizzaBuilder { override def buildDough() : Unit = { pizza.get.setDough("cross") } override def buildSauce() : Unit = { pizza.get.setSauce("mild") } override def buildTopping() : Unit = { pizza.get.setTopping("ham+pineapple") } } class SpicyPizzaBuilder extends AbstractPizzaBuilder { override def buildDough() : Unit = { pizza.get.setDough("pan baked") } override def buildSauce() : Unit = { pizza.get.setSauce("hot") } override def buildTopping() : Unit = { pizza.get.setTopping("pepperoni+salami") } } class Waiter { private var pizzaBuilder : Option[AbstractPizzaBuilder] = None def setPizzaBuilder(pizzaBuilder: AbstractPizzaBuilder) : Unit = { this.pizzaBuilder = Some(pizzaBuilder) println(s"Builder ${pizzaBuilder.getClass.getName} is set as default") } def createPizza() : Pizza = { pizzaBuilder.get.createPizza() pizzaBuilder.get.buildDough() pizzaBuilder.get.buildSauce() pizzaBuilder.get.buildTopping() pizzaBuilder.get.getPizza.get } } object BuilderTest { def main(args: Array[String]) : Unit = { val waiter = new Waiter println("Output:") waiter.setPizzaBuilder(new HawaiianPizzaBuilder) waiter.createPizza().outputReceipt() waiter.setPizzaBuilder(new SpicyPizzaBuilder) waiter.createPizza().outputReceipt() } } } // Output: // Builder com.builder.package$HawaiianPizzaBuilder is set as default // Dough: cross // Sauce: mild // Topping: ham+pineapple // Builder com.builder.package$SpicyPizzaBuilder is set as default // Dough: pan baked // Sauce: hot // Topping: pepperoni+salami

С#

Исходный текст на языке C# using System; using System.Collections.Generic; 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 virtual void BuildPartA(){} public virtual 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 List<string> parts = new List<string>(); public void Add(string part) { parts.Add(part); } public void Show() { Console.WriteLine(" Product Parts -------"); foreach (string part in parts) Console.WriteLine(part); } } }

C++

Исходный текст на языке C++ // Реализация на 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::shared_ptr<Pizza> pizza; public: PizzaBuilder() {} virtual ~PizzaBuilder() {} std::shared_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(nullptr) {} ~Waiter() { } void SetPizzaBuilder(PizzaBuilder* b) { pizzaBuilder = b; } std::shared_ptr<Pizza> GetPizza() { return pizzaBuilder->GetPizza(); } void ConstructPizza() { pizzaBuilder->createNewPizzaProduct(); pizzaBuilder->buildDough(); pizzaBuilder->buildSauce(); pizzaBuilder->buildTopping(); } }; // Клиент заказывает две пиццы. int main() { Waiter waiter; HawaiianPizzaBuilder hawaiianPizzaBuilder; waiter.SetPizzaBuilder (&hawaiianPizzaBuilder); waiter.ConstructPizza(); std::shared_ptr<Pizza> pizza = waiter.GetPizza(); pizza->ShowPizza(); SpicyPizzaBuilder spicyPizzaBuilder; waiter.SetPizzaBuilder(&spicyPizzaBuilder); waiter.ConstructPizza(); pizza = waiter.GetPizza(); pizza->ShowPizza(); return EXIT_SUCCESS; }

JavaScript

Исходный текст на языке JavaScript // Product function Pizza() { var dublicate = this; // постоянная ссылка на инстанцируемый объект для вызова при любом this var dough; var sauce; var topping; this.setDough = function(val) { dough = val; }; this.setSauce = function(val) { sauce = val; }; this.setTopping = function(val) { topping = val; }; // из-за особенностей языка, геттеры (пусть они нам и не понадобятся) // должны быть определены в той же функции, что и локальные переменные this.getDough = function() { return dough; }; this.getSauce = function() { return sauce; }; this.getTopping = function() { return topping; }; // мы должны создать метод, изменяющий св-ва уже созданного объекта // (см. createNewPizzaProduct) this.clear = function() { dublicate.setDough(undefined); dublicate.setSauce(undefined); dublicate.setTopping(undefined); }; } // Abstract Builder function PizzaBuilder() { var pizza = new Pizza(); this.getPizza = function() { return pizza; }; this.createNewPizzaProduct = function() { // если мы просто поменяем зн-е переменной pizza, то изменение никак // не отразится на дочерних классах, т.к. внутри них переменная pizza // ссылается на «старую» область памяти pizza.clear(); // если внутри реализаций (HawaiianPizzaBuilder, SpicyPizzaBuilder) // мы, вместо переменной pizza, будем использовать метод getPizza, // то можно использовать // pizza = new Pizza(); // и метод clear у Pizza не понадобится }; this.buildDough = function(val) { }; this.buildSauce = function(val) { }; this.buildTopping = function(val) { }; } // ConcreteBuilder function HawaiianPizzaBuilder() { PizzaBuilder.call(this); var pizza = this.getPizza(); // имитация protected this.buildDough = function() { pizza.setDough("cross"); }; this.buildSauce = function() { pizza.setSauce("mild"); }; this.buildTopping = function() { pizza.setTopping("ham+pineapple"); }; } function SpicyPizzaBuilder() { PizzaBuilder.call(this); var pizza = this.getPizza(); this.buildDough = function() { pizza.setDough("pan baked"); }; this.buildSauce = function() { pizza.setSauce("hot"); }; this.buildTopping = function() { pizza.setTopping("pepperoni+salami"); }; } // Director function Waiter() { var pizzaBuilder; this.setPizzaBuilder = function(builder) { pizzaBuilder = builder; }; this.getPizza = function() { return pizzaBuilder.getPizza(); }; this.constructPizza = function() { pizzaBuilder.createNewPizzaProduct(); pizzaBuilder.buildDough(); pizzaBuilder.buildSauce(); pizzaBuilder.buildTopping(); }; } // Клиент заказывает две пиццы var pizza; var waiter = new Waiter(); var hawaiianPizzaBuilder = new HawaiianPizzaBuilder(); waiter.setPizzaBuilder( hawaiianPizzaBuilder ); waiter.constructPizza(); pizza = waiter.getPizza(); alert( pizza.getDough() +", "+ pizza.getSauce() +", "+ pizza.getTopping() ); var spicyPizzaBuilder = new SpicyPizzaBuilder(); waiter.setPizzaBuilder( spicyPizzaBuilder ); waiter.constructPizza(); pizza = waiter.getPizza(); alert( pizza.getDough() +", "+ pizza.getSauce() +", "+ pizza.getTopping() );

Python

Исходный текст на языке Python #coding: utf-8 class Animal: """ Абстрактное Животное """ legs = 0 tail = False roar = '' class Mutator: """ Ответственный за размножение """ def mutate(self): self.animal = Animal() class Cat(Mutator): """ Кошка """ def create_legs(self): self.animal.legs = 4 def create_tail(self): self.animal.tail = True def create_roar(self): self.animal.roar = 'meowww!' class Dog(Mutator): """ Собака """ def create_legs(self): self.animal.legs = 4 def create_tail(self): self.animal.tail = True def create_roar(self): self.animal.roar = 'woffff!' class AnimalOwner: """ Владелец питомника """ __mutator = '' def set_animal(self, mutator): self.__mutator = mutator def create_an_animal_for_me(self): self.__mutator.mutate() self.__mutator.create_legs() self.__mutator.create_tail() self.__mutator.create_roar() def get_animal(self): return self.__mutator.animal c = Cat() d = Dog() ao = AnimalOwner() ao.set_animal(c) ao.create_an_animal_for_me() animal = ao.get_animal() print animal.roar #meowww!

PHP5

Исходный текст на языке PHP <?php /** * Паттерн строитель, оперирует известными "рецептами строительства" */ /** * Pizza - Базовый объект строительства */ class Pizza { private $_pastry = ""; private $_sauce = ""; private $_garniture = ""; public function setPastry($pastry) { $this->_pastry = $pastry; } public function setSauce($sauce) { $this->_sauce = $sauce; } public function setGarniture($garniture) { $this->_garniture = $garniture; } } /** * Builder - Абстрактный строитель */ abstract class BuilderPizza { protected $_pizza; public function getPizza() { return $this->_pizza; } public function createNewPizza() { $this->_pizza = new Pizza (); } abstract public function buildPastry(); abstract public function buildSauce(); abstract public function buildGarniture(); } /** * BuilderConcret - Конкретный строитель 1 */ class BuilderPizzaHawaii extends BuilderPizza { public function buildPastry() { $this->_pizza->setPastry ( "normal" ); } public function buildSauce() { $this->_pizza->setSauce ( "soft" ); } public function buildGarniture() { $this->_pizza->setGarniture ( "jambon+ananas" ); } } /** * BuilderConcret - Конкретный строитель 2 */ class BuilderPizzaSpicy extends BuilderPizza { public function buildPastry() { $this->_pizza->setPastry ( "puff" ); } public function buildSauce() { $this->_pizza->setSauce ( "hot" ); } public function buildGarniture() { $this->_pizza->setGarniture ( "pepperoni+salami" ); } } /** * Director - Управляющий класс, запускающий строительство * PizzaBuilder - Реализация патерна Builder, показывающая делегирование процесса создания пиццы методу constructPizza */ class PizzaBuilder { private $_builderPizza; public function setBuilderPizza(BuilderPizza $mp) { $this->_builderPizza = $mp; } public function getPizza() { return $this->_builderPizza->getPizza(); } public function constructPizza() { $this->_builderPizza->createNewPizza (); $this->_builderPizza->buildPastry (); $this->_builderPizza->buildSauce (); $this->_builderPizza->buildGarniture (); } } // Инициализация разносчика $pizzaBuilder = new PizzaBuilder(); // Инициализация доступных продуктов $builderPizzaHawaii = new BuilderPizzaHawaii(); $builderPizzaPiquante = new BuilderPizzaSpicy(); // Подготовка и получение продукта $pizzaBuilder->setBuilderPizza( $builderPizzaHawaii ); $pizzaBuilder->constructPizza(); $pizza = $pizzaBuilder->getPizza();

Ruby

Исходный текст на языке Ruby # # Базовый объект строительства # class Pizza attr_accessor :pastry, :sauce, :garniture end # # Builder - класс строитель # class BuilderPizza attr_reader :pizza def create_new_pizza @pizza = Pizza.new end def get_pizza "Your order. pastry: #{@pizza.pastry}, sauce: #{@pizza.sauce}, garniture: #{@pizza.garniture}" end end # # BuilderConcret - Конкретный строитель 1 # class BuilderPizzaHawaii < BuilderPizza def build_pastry @pizza.pastry = 'normal' end def build_sauce @pizza.sauce = 'soft' end def build_garniture @pizza.garniture = 'jambon+ananas' end end # # BuilderConcret - Конкретный строитель 2 # class BuilderPizzaSpicy < BuilderPizza def build_pastry @pizza.pastry = 'puff' end def build_sauce @pizza.sauce = 'hot' end def build_garniture @pizza.garniture = 'papperoni+salami' end end # # Director - Управляющий класс, запускающий строительство # class Waiter def set_builder_pizza(bp) @builder_pizza = bp end def get_pizza @builder_pizza.get_pizza end def construct_pizza @builder_pizza.create_new_pizza @builder_pizza.build_pastry @builder_pizza.build_sauce @builder_pizza.build_garniture end end waiter = Waiter.new builder_pizza_hawaii = BuilderPizzaHawaii.new builder_pizza_spicy = BuilderPizzaSpicy.new waiter.set_builder_pizza(builder_pizza_hawaii) waiter.construct_pizza puts waiter.get_pizza

Delphi

Исходный текст на языке 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 FreePizzaProduct; 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; procedure FreePizza; 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 FreePizzaProduct; inherited Destroy; end; procedure TPizzaBuilder.FreePizzaProduct; begin if FPizza <> nil then FreeAndNil(FPizza); 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.FreePizza; begin if FPizzaBuilder <> nil then FPizzaBuilder.FreePizzaProduct; 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; procedure ConstructAndShowPizza(Waiter: TWaiter; Builder: TPizzaBuilder); var Pizza: TPizza; begin Waiter.PizzaBuilder := Builder; Waiter.ConstructPizza; Pizza := Waiter.GetPizza; try Pizza.Show; finally Waiter.FreePizza; end; end; var Waiter: TWaiter; HawaiianPizzaBuilder: THawaiianPizzaBuilder; SpicyPizzaBuilder: TSpicyPizzaBuilder; begin HawaiianPizzaBuilder := nil; SpicyPizzaBuilder := nil; Waiter := nil; try HawaiianPizzaBuilder := THawaiianPizzaBuilder.Create; SpicyPizzaBuilder := TSpicyPizzaBuilder.Create; Waiter := TWaiter.Create; // Client has ordered two pizzas ConstructAndShowPizza(Waiter, HawaiianPizzaBuilder); ConstructAndShowPizza(Waiter, SpicyPizzaBuilder); finally Waiter.Free; HawaiianPizzaBuilder.Free; SpicyPizzaBuilder.Free; end; ReadLn; end.

VB.NET

Исходный текст на языке VB.NET Imports System.Collections.Generic Namespace Builder Public Class MainApp Public Shared Sub Main() ' Create director and builders Dim director As New Director() Dim b1 As Builder = New ConcreteBuilder1() Dim b2 As Builder = New ConcreteBuilder2() ' Construct two products director.Construct(b1) Dim p1 As Product = b1.GetResult() p1.Show() director.Construct(b2) Dim p2 As Product = b2.GetResult() p2.Show() ' Wait for user Console.Read() End Sub End Class ' "Director" Class Director ' Builder uses a complex series of steps Public Sub Construct(ByVal builder As Builder) builder.BuildPartA() builder.BuildPartB() End Sub End Class ' "Builder" MustInherit Class Builder Public MustOverride Sub BuildPartA() Public MustOverride Sub BuildPartB() Public MustOverride Function GetResult() As Product End Class ' "ConcreteBuilder1" Class ConcreteBuilder1 Inherits Builder Private ReadOnly product As New Product() Public Overrides Sub BuildPartA() product.Add("PartA") End Sub Public Overrides Sub BuildPartB() product.Add("PartB") End Sub Public Overrides Function GetResult() As Product Return product End Function End Class ' "ConcreteBuilder2" Class ConcreteBuilder2 Inherits Builder Private ReadOnly product As New Product() Public Overrides Sub BuildPartA() product.Add("PartX") End Sub Public Overrides Sub BuildPartB() product.Add("PartY") End Sub Public Overrides Function GetResult() As Product Return product End Function End Class ' "Product" Class Product Private ReadOnly parts As New List(Of String)() Public Sub Add(ByVal part As String) parts.Add(part) End Sub Public Sub Show() Console.WriteLine(vbLf & "Product Parts -------") For Each part As String In parts Console.WriteLine(part) Next End Sub End Class End Namespace

  • Charm++
  • OpenSCAD
  • Стратегия (шаблон проектирования)
  • Ember.js
  • Декартово замкнутая категория

  •  

    • Яндекс.Метрика
    • Индекс цитирования