Monteur

Le monteur (builder) est un patron de conception utilisé pour créer une variété d’objets complexes à partir d’un objet source.

Explication

  • Le monteur est une classe abstraite qui contient le produit.
  • Le monteur « concret » fourni une implémentation de monteur, construit et assemble les différentes parties du produit
  • Le directeur construit un objet en utilisant la méthode de conception du monteur
  • Le produit est l’objet en cours de construction

Exemple

Pour illustrer le Monteur, nous allons créer des pizzas. Le Pizzaiolo a le rôle de directeur.

Tout d’abord, nous allons créer la composition d’une pizza avec une classe et quelques types énumérés.

type
   TPate = (ppFine, ppEpaisse);
   TSauce = (spTomate, spCreme);
   TIngredient = (gpJambon, gpFromage, gpAnanas, gpOlive);
   TGarniture = set of TIngredient;
 
   TPizza = class
   strict private
      FPate: TPate;
      FSauce: TSauce;
      FGarniture: TGarniture;
   public
      property Pate: TPate read FPate write FPate;
      property Sauce: TSauce read FSauce write FSauce;
      property Garniture: TGarniture read FGarniture write FGarniture;
 
   end;

Ensuite, le Monteur de pizza contient le produit TPizza et définie (virtual-abstract) les actions à réaliser pour en réaliser une. Une propriété est ajoutée pour pouvoir récupérer le produit.

   IMonteurPizza = interface
   ['{98B607D5-FDA3-470E-8A85-DF8DE8013F8D}']
      procedure EtalerPate;
      procedure AjouterSauce;
      procedure AjouterGarniture;
   end;
 
   TMonteurPizza = class(TInterfacedObject, IMonteurPizza)
   strict private
      FPizza: TPizza;
 
      procedure CreerPizza;
   protected
      procedure EtalerPate; virtual; abstract;
      procedure AjouterSauce; virtual; abstract;
      procedure AjouterGarniture; virtual; abstract;
 
      property Pizza: TPizza read FPizza;
   public
      function FairePizza: TPizza;
   end;
 
{ TMonteurPizza }
 
procedure TMonteurPizza.CreerPizza;
begin
   Writeln('création d''une ', Self.ClassName);
   FPizza := TPizza.Create;
end;
 
function TMonteurPizza.FairePizza: TPizza;
begin
   CreerPizza;
   EtalerPate;
   AjouterSauce;
   AjouterGarniture;
 
   Result := Pizza;
end;

Puis le monteur concret va réaliser une pizza « Hawaii ». Cette classe hérite du monteur précédent.

   TMonteurPizzaHawaii = class(TMonteurPizza)
   protected
      procedure EtalerPate; override;
      procedure AjouterSauce; override;
      procedure AjouterGarniture; override;
   end;
 
{ TMonteurPizzaHawaii }
 
procedure TMonteurPizzaHawaii.AjouterGarniture;
begin
   Pizza.Garniture := [gpJambon, gpFromage, gpAnanas];
end;
 
procedure TMonteurPizzaHawaii.EtalerPate;
begin
   Pizza.Pate := ppFine;
end;
 
procedure TMonteurPizzaHawaii.AjouterSauce;
begin
   Pizza.Sauce := spTomate;
end;

Pour terminer, le directeur est créé avec un monteur (obligatoire), ou alors un nouveau est assigné via le setter. La méthode GetPizza est le résultat de la méthode FairePizza du Monteur.

   TPizzaiolo = class
   strict private
      FMonteur: TMonteurPizza;
 
      procedure SetMonteur(const Value: TMonteurPizza);
      function GetPizza: TPizza;
   public
      constructor Create(aMonteur: TMonteurPizza);
      destructor Destroy; override;
 
      property Monteur: TMonteurPizza write SetMonteur;
      property Pizza: TPizza read GetPizza;
   end;
 
{ TPizzaiolo }
 
constructor TPizzaiolo.Create(aMonteur: TMonteurPizza);
begin
   if aMonteur = nil then
      raise Exception.Create('Le monteur est nécessaire');
 
   FMonteur := aMonteur;
end;
 
destructor TPizzaiolo.Destroy;
begin
   FMonteur.Free;
   inherited;
end;
 
function TPizzaiolo.GetPizza: TPizza;
begin
   Result := FMonteur.FairePizza;
end;
 
procedure TPizzaiolo.SetMonteur(const Value: TMonteurPizza);
begin
   if Assigned(FMonteur) then
      FMonteur.Free;
 
   FMonteur := Value;
end;

Voici le code source de l’utilisation du monteur dans une application console.

var
   Pizzaiolo: TPizzaiolo;
   Pizza: TPizza;
begin
   try
      Pizzaiolo := TPizzaiolo.Create(TMonteurPizzaHawaii.Create);
      try
         Pizza := Pizzaiolo.Pizza;
      finally
         Pizzaiolo.Free;
      end;
 
      Readln;
   except
      on E: Exception do
         Writeln(E.ClassName, ': ', E.Message);
   end;
end.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

*