Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Warum Strategy Pattern nicht über Metaklassen? (https://www.delphipraxis.net/175844-warum-strategy-pattern-nicht-ueber-metaklassen.html)

Der schöne Günther 23. Jul 2013 14:10

Warum Strategy Pattern nicht über Metaklassen?
 
Metaklassen. Ich wette mit diesem Wort mache ich jede Marketingabteilung schwach.

Zum Thema: Ich blättere durch ein paar Delphi-Implementationen des Strategy Patterns. Beispielsweise auf

(Wenn ich mich nicht irre bedient sich letztes dem Enten-Beispiel aus dem Head First Design Patterns-Buch :-D)

Jetzt geht es natürlich eigentlich ums grundlegende Prinzip, aber ich wundere mich, warum jeder immer jedes Objekt eine neue Instanz einer Strategie aggregieren lässt? Grade Delphi bietet doch eigentlich schön die Möglichkeit, auf die Klasse einer Strategie, und nicht auf eine speziell erstellte Instanz einer Strategie zeigen zu lassen? Ich hätte das jetzt als "typisch Delphi" empfunden, wenn ich das nach so kurzer Zeit schon sagen darf.

Sicher ist das über Instanzen keine schlechtere Methode (sogar deutlich flexibler)- Meine Frage eher: Gibt es einen Grund, es nicht bsp. so zu tun (dummes Beispiel, wie immer)?

Delphi-Quellcode:
   TMyData = class;

   // Das sollte ein Interface sein...
   TMyDataFilterAbstract = class abstract
      class function getFilteredResult(dataIn: TMyData = nil): TMyData; virtual; abstract;
   end;

   TMyDataFilterMalZwei = class(TMyDataFilterAbstract)
      class function getFilteredResult(dataIn: TMyData): TMyData; override;
   end;

   TMyDataFilterPlusDrei = class(TMyDataFilterAbstract)
      class function getFilteredResult(dataIn: TMyData): TMyData; override;
   end;

   TMyData = class(TList<Single>)
      type
         TFilterClass = class of TMyDataFilterAbstract;
      private const
         defaultFilter: TFilterClass = TMyDataFilterMalZwei;
      public
         function getFiltered(filterType: TFilterClass = nil): TMyData;
   end;
Ähnlich auch das C++-Beispiel auf Wikipedia. Das dortige Java-Beispiel geht wieder den Weg über Instanzen.


Gibt es leidenschaftliche Meinungen zum Thema? :)

Meflin 23. Jul 2013 14:51

AW: Warum Strategy Pattern nicht über Metaklassen?
 
Ganz einfach: eine nicht-trivale Strategie kann ja auch schnell mal eigenen, internen Zustand haben. Da fährst du mit deinem statischen Ansatz ganz schnell gegen die Wand. Wenn du das ganze also von der Architektur her schon so aufbaust, wirst du nie eine (in diesem Sinne) nicht-triviale Strategie implementieren können. Was du aber vorher eher nicht abschätzen kannst, ob du das nicht doch mal willst. Gegenfrage: was soll der Vorteil der statischen Variante sein?

Mit Metaklassen hat das übrigens nix zu tun. Metaklasse wäre die Klasse, von der deine Klassendefinition eine Instanz ist. Sowas gibts aber in Delphi afair überhauptnicht.

uligerhardt 23. Jul 2013 15:05

AW: Warum Strategy Pattern nicht über Metaklassen?
 
Zitat:

Zitat von Meflin (Beitrag 1222393)
Ganz einfach: eine nicht-trivale Strategie kann ja auch schnell mal eigenen, internen Zustand haben. Da fährst du mit deinem statischen Ansatz ganz schnell gegen die Wand. Wenn du das ganze also von der Architektur her schon so aufbaust, wirst du nie eine (in diesem Sinne) nicht-triviale Strategie implementieren können. Was du aber vorher eher nicht abschätzen kannst, ob du das nicht doch mal willst. Gegenfrage: was soll der Vorteil der statischen Variante sein?

Mit Metaklassen hat das übrigens nix zu tun. Metaklasse wäre die Klasse, von der deine Klassendefinition eine Instanz ist. Sowas gibts aber in Delphi afair überhauptnicht.

Also, ich hab gleich verstanden, was gemeint war.
Zitat:

Zitat von http://docwiki.embarcadero.com/RADStudio/XE4/en/Class_References
A class-reference type, sometimes called a metaclass, is denoted by a construction of the form:
Delphi-Quellcode:
class of type
where type is any class type.


Der schöne Günther 23. Jul 2013 15:34

AW: Warum Strategy Pattern nicht über Metaklassen?
 
Deshalb der kleine Hieb mit der Marketingabteilung - So ganz Meta ist es irgendwie nicht, aber ich habe es im Delphi-Land immer als "Metaklasse" bezeichnet gesehen.

Ich denke wohl auch zu einfach (Könnte mit der Hitze zu tun haben) - Ich hatte zu dem Zeitpunkt gerade nur Signalfilter im Kopf, da geht man einmal über einen Datensatz drüber und ist fertig. Da bekomme ich keine Probleme.

Ich glaube, ich habe bislang auch noch nie irgendein längerfristiges Vorgehen das Zustände behalten musste als Strategie ausgekoppelt - Ich habe das Problem überhaupt nicht gesehen. :oops:

Meflin 23. Jul 2013 15:38

AW: Warum Strategy Pattern nicht über Metaklassen?
 
Stell dir zum Beipsiel vor, du implementierst Spielstrategien für Blackjack über das Strategiepattern. Dann hast du eine Strategie die zieht Random Karten bis zu einem Grenzwert (geht vllt. noch ohne Zustand). Und dann denkst du dir, du implementierst das doch besser mit der Kartenzählen-Strategie, die sich ja dann die letzten Spiele merken muss. Und das ganze noch für Multiplayer. Das geht einfach nicht, wenn deine Strategie nur statisch implementiert ist.

BUG 23. Jul 2013 20:29

AW: Warum Strategy Pattern nicht über Metaklassen?
 
Richtig interessant wird das Strategy-Pattern, wenn man die Strategie eines Objektes zur Laufzeit anpassen will.

Das passiert ganz leicht, wenn man den Benutzer zur Laufzeit das Verhalten anpassen lassen will.
Das Neu-Erstellen des Objekts ist natürlich zu teuer und entspricht auch nicht wirklich der der gewünschten Semantik.

Deine gefilterte Liste wäre ein Beispiel:
Der Nutzer soll den Filter der Liste für die Darstellung wählen können.
Da die Liste natürlich Unmengen an Daten enthält, ist das Neu-Erstellen keine Option.
Die verschiedenen darstellenden Widgets sollen von der Filterung keine Ahnung haben (warum auch).

Um es spannender zu machen: Der Filter könnte ein Aggregat aus verschiedenen Regeln sein, das der Nutzer über einen Assistenten erstellt.
Mach das mal statisch :mrgreen:

Der schöne Günther 23. Jul 2013 21:36

AW: Warum Strategy Pattern nicht über Metaklassen?
 
Da hätte ich mir, bei meiner Taktik, spontan eine neue Subklasse deklariert, die dann wiederum ihre von ihr aggregierten Strategien hätte kennen müssen. Ja, auf lange Sicht wäre ich nicht gut gefahren.

Wahrscheinlich hätte ich, noch von J2EE geschädigt, mir eine FilterChain-Klasse gebaut, die dann speziell dafür gut gewesen wäre und sich, mit anderen Filtern parametrisieren ließe - Großer Gott!

Manchmal bekomme ich vor mir selbst Angst, was einem bei Hitze für Gedanken im Kopf schwirren. Wo ich sitze, gibt es keine Klimaanlage :drunken:


Danke für die Antworten bislang :thumb:
Gut dass ich vorher gefragt habe, heut nachmittag kam mir das unheimlich attraktiv vor :love:

Furtbichler 24. Jul 2013 07:31

AW: Warum Strategy Pattern nicht über Metaklassen?
 
Nachtrag: So wie ich das sehe, ist deine Idee einfach kein Strategy-Pattern, sondern einfach eine Möglichkeit, ein konkretes Verhalten einer abgeleiteten Klasse zu definieren. Du kannst auch einfach die Filter-Methode abstrakt definieren und dann konkret implementieren. Gehüpft wie gesprungen.

Der schöne Günther 24. Jul 2013 08:43

AW: Warum Strategy Pattern nicht über Metaklassen?
 
"Einmal filtern, bitte" ist vielleicht wirklich kein gutes Beispiel wenn man als Strategie gleich ein langfristiges, Zustände speicherndes Vorgehen im Kopf hat. Ich bin da wohl doch etwas einfacher gestrickt 8-)

Zu meiner Verteidigung: TDatensatz hat eine Methode "sagMirWieDuGefiltertAussiehst". Welches Verhalten da intern benutzt wird um einen gefilterten Datensatz zu erzeugen möchte ich einstellen können. Dieses delegierte Verhalten wage ich, frei nach den quakenden Enten, bereits als Strategie bezeichnen zu können.


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:57 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