Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Frage zum Decorator Muster (https://www.delphipraxis.net/95305-frage-zum-decorator-muster.html)

GroHae 4. Jul 2007 22:28


Frage zum Decorator Muster
 
Hallo zusammen,

ich arbeite mich gerade durch das Buch "Entwurfsmuster von Kopf bis Fuß" Die Beispiel sind allerdings in Java

ich hab jetzt folgenden Code

Delphi-Quellcode:
unit Unit2;

interface

   type

   Getraenk = class abstract (TObject)
      Beschreibung : string;
      constructor Create;
      function GetBeschreibung : string;
      function Preis : Real; virtual; abstract;
   end;


   ZutatenDekorierer = class abstract (Getraenk)
      function GetBeschreibung : string; virtual; abstract;
   end;


// Konkrete Komponente (Kaffesorten)

   Espresso = class (Getraenk)
      constructor Create;
      function Preis : Real; override;
   end;

   Hausmischung = class (Getraenk)
      constructor Create;
      function Preis : Real; override;
   end;

   DunkleRoestung = class (Getraenk)
      constructor Create;
      function Preis : Real; override;
   end;

// konkrete Dekoriere (Zutaten)

   Schoko = class(ZutatenDekorierer)
     ActGetraenk : Getraenk;
     constructor Create(iGetraeng:Getraenk);
     function GetBeschreibung : string; override;
     function Preis : Real; override;
   end;

   HeisseMilch = class(ZutatenDekorierer)
     ActGetraenk : Getraenk;
     constructor Create(iGetraeng:Getraenk);
     function GetBeschreibung : string; override;
     function Preis : Real; override;
   end;

implementation

uses Dialogs;

{ Getraenk }

constructor Getraenk.Create;
begin
  Beschreibung := 'Unbekanntes Getränk';
end;

function Getraenk.GetBeschreibung: string;
begin
  result := Beschreibung;
end;

{ Espresso }

constructor Espresso.Create;
begin
  Beschreibung := 'Espresso';
end;

function Espresso.Preis: Real;
begin
  result := 1.99;
end;

{ Hausmischung }

constructor Hausmischung.Create;
begin
  Beschreibung := 'Hausmischung';
end;


function Hausmischung.Preis: Real;
begin
  result := 0.89;
end;

{ DunkleRoestung }

constructor DunkleRoestung.Create;
begin
  Beschreibung := 'Dunkle Röstung';
end;

function DunkleRoestung.Preis: Real;
begin
  Result := 0.99;
end;

{ Schoko }

constructor Schoko.Create(iGetraeng: Getraenk);
begin
//  ShowMessage(iGetraeng.Beschreibung);
  ActGetraenk := iGetraeng;
end;

function Schoko.GetBeschreibung: string;
begin
  result := ActGetraenk.GetBeschreibung + ', Schoko';
end;

function Schoko.Preis: Real;
begin
  result := ActGetraenk.Preis + 0.20;
end;

{ HeisseMilch }

constructor HeisseMilch.Create(iGetraeng: Getraenk);
begin
  ActGetraenk := iGetraeng;
end;

function HeisseMilch.GetBeschreibung: string;
begin
  Result := ActGetraenk.Beschreibung + ', Heiße Milch';
end;

function HeisseMilch.Preis: Real;
begin
  result := ActGetraenk.Preis + 0.10;
end;


end.
Wenn ich jetzt

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  Getraenk1 : Getraenk;
begin
  Getraenk1 := DunkleRoestung.Create;
  Getraenk1 := Schoko.Create(Getraenk1);
  Getraenk1 := Schoko.Create(Getraenk1);
  Getraenk1 := HeisseMilch.Create(Getraenk1);
  ShowMessage(Getraenk1.GetBeschreibung + ' ' + format('%f',[Getraenk1.Preis]));
end;
bekomme ich keine Bezeichnung angezeigt. Eigentlich sollte "HeisseMilch, Schoko, Schoko Dunkle Röstung" + Preis angezeigt werden.
Ich bekomme aber nur den Preis. Wenn ich die Dekoriere weg lasse und nur sage

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  Getraenk1 : Getraenk;
begin
  Getraenk1 := DunkleRoestung.Create;
  ShowMessage(Getraenk1.GetBeschreibung + ' ' + format('%f',[Getraenk1.Preis]));
end;
bekomme ich den Text Dunkle Röstung angezeigt.

Ich versteh's nicht :(

DGL-luke 4. Jul 2007 23:30

Re: Frage zum Decorator Muster
 
äußerst komisches design pattern...

auf jeden fall betreibst du hier rekursives wrapping. das heißt, irgendwo muss du die zeile

Delphi-Quellcode:
description := 'blablubb' + ActGetraenk.description;
haben. Mal sehen...

Getraenk.Getbeschreibung wird durch Zutatendekorier.Getbeschreibung verdeckt. Mach Getraenk.GetBeschreibung virtuell. (nur virtual dranhängen, kein abstract) Zutatendekorier.Getbeschreibung muss dann mit einem override versehen werden.

Jop, das ist auch schon des lösungs rätsel. tu was ich dir sage und alles wird wie von zauberhand funktionieren.

Das Problem ist, wenn du auf Getraenk1.GetBeschriebung zugreifst, wird dir immer der Name des Getraenks (der string, der in Beschreibung steht) geliefert. Da der Compiler nur weiß, dass er ein Getraenk hat. Und er greift auf die statische Methode Getraenk.GetBeschreibung zu.

(warum bei dir eine leere beschreibung kommt weiß ich nicht. ich vermute mal versionsprobleme, nämlich dass du in der ausgeführten version eine Leerstring in Getraenk.GetBeschreibung zurücklieferst)

EDIT: hab "beschreibung" übersehen. posting korrigiert.

alzaimar 5. Jul 2007 06:48

Re: Frage zum Decorator Muster
 
Sollte man nicht das Feld 'ActGetraenk' in die `Basisklasse 'Zutatendekorier' verschieben ?

GroHae 5. Jul 2007 08:16

Re: Frage zum Decorator Muster
 
Guten Morgen,

Danke für die Hilfe!

Zitat:

Getraenk.Getbeschreibung wird durch Zutatendekorier.Getbeschreibung verdeckt. Mach Getraenk.GetBeschreibung virtuell. (nur virtual dranhängen, kein abstract) Zutatendekorier.Getbeschreibung muss dann mit einem override versehen werden.
Stimmt jetzt geht's

Außerdem hatte ich in function HeisseMilch.GetBeschreibung: nicht ActGetraenk.GetBeschreibung sondern ActGetraenk.Beschreibung stehen , was dann auch einen falschen Text ergibt.

Zitat:

Sollte man nicht das Feld 'ActGetraenk' in die `Basisklasse 'Zutatendekorier' verschieben ?
Stimmt auch.

Aber ganz Erlich: Ich muß über das was ich da jetzt gemacht habe noch mal nachdenken. Weil wirklich verstehen tu ich es noch nicht ganz :gruebel:


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:42 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz