понедельник, 16 апреля 2012 г.

Строитель

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

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

  • Применение
  • алгоритм создания сложного объекта не должен зависеть от того, из каких частей состоит объект и как они стыкуются между собой
  • процесс конструирования должен обеспечивать различные представления конструируемого объекта
  • type
    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.
    

    Комментариев нет:

    Отправить комментарий