Kontextklasse im Strategiemuster

10

Ich versuche, das Strategiemuster zu verstehen und frage mich: Ist die Kontextklasse ein Muss oder kann ich sie weglassen, ohne den Zweck des Musters zu beeinträchtigen?

Ich hatte den Eindruck, ich brauchte eine Art Schalter zum Lesen verschiedener Dateitypen, wollte aber nicht nur etwas hacken und mich später mit Refactoring befassen (obwohl es natürlich immer vorkommt, dass Code refactored werden kann, aber die Idee war: try um vorher so schlau wie möglich im Design zu sein ...):

Geben Sie hier die Bildbeschreibung ein

Bild aus Wikimedia genommen

Kann der Client direkt an die Strategieoberfläche delegieren oder gibt es etwas, das ich gerade über die Kontextklasse nicht verstanden habe?

interface Reader {
    // read information from file and fill data list field of Client
    readFile();
}
class ExcelReader implements Reader{ /* */ }
class PdfReader implements Reader{ /* */}

class Client{
    // strategic choice
    Reader r;

    // data list field
    List<Data> data;

    // Client Constructor
    public Client(){
        if(<file ends in .xls>)
            r = new ExcelReader();
        else
            r = new PdfReader();
        r.readFile();
    }
}

Oben abgebildet fehlt also die Kontextklasse. Entspricht der Code dem Strategiemuster?

Panny
quelle
1
Als weiteren interessanten / wichtigen Punkt möchte ich Sie darauf aufmerksam machen, dass das Konzept der Typklassen in funktionalen Sprachen "einfach" das Strategiemuster mit den Arten en.wikipedia.org/wiki/Kind_(type_theory) ) ist. Beide sind nur ein Implementierungsmechanismus für Ad-hoc-Polymorphismus.
AndreasScheinert
Hat dies (weit oder weniger) mit Java 8 Project Lambda zu tun? Der Wikipedia-Artikel ist zu dicht, als dass ich ihn sofort verstehen könnte. Wenn dies jedoch Teil des theoretischen Hintergrunds für die effiziente Nutzung der kommenden Java-Funktionen (oder der Programmierung im Allgemeinen) ist, werde ich gerne mehr Zeit in ihn investieren.
Panny
1
Sehr weit, aber ich würde ja argumentieren, Typklassen brauchen. Eine Programmiersprache, die höhere Arten unterstützt. Das wäre bei Scala und Haskell der Fall. Mein Punkt hier war, dass (Ad-hoc-) Polymorphismus anders implementiert wird und wenn Sie zurücktreten, können Sie einige Einblicke in den Polymorphismus im Allgemeinen gewinnen.
AndreasScheinert

Antworten:

13

In Ihrem Beispiel ist der Codeaufruf readFileTeil des Client-Konstruktors. Diese Methode ist der "Kontext", den Sie suchen . Das Strategiemuster benötigt buchstäblich keine "Kontextklasse", und in der ersten Version Ihres Codes befindet sich das Strategieobjekt (in Ihrem Fall der "Reader") möglicherweise nur in einer lokalen Variablen. Besonders wenn nur eine "strategische Methode" ("readFile") aufgerufen werden muss.

Wenn Ihre Codebasis jedoch von einer Version zur nächsten wächst, ist es nicht unwahrscheinlich, dass immer mehr "strategische" Methoden aufgerufen werden. Die Entscheidung, welche Strategie angewendet werden soll, und die Durchführung der "strategischen Methoden" werden zu unterschiedlichen Zeiten erfolgen und an verschiedenen Stellen in Ihrem Code. Also fängst du an, sie umzugestalten, um die Logik an einem Ort zu halten. Dies führt direkt zu einer Implementierung, die dem Diagramm in Ihrer Frage ähnelt.

Doc Brown
quelle
5

Bestimmt. Muster sind nur Richtlinien. Sie müssen sie noch anpassen und korrekt auf das jeweilige Problem anwenden. Persönlich erlaube ich selten, dass die Strategie zur Laufzeit festgelegt wird. häufiger wird es beim Bau spezifiziert oder in einer Fabrik gesponnen.

Es könnte aber auch argumentiert werden, dass dies setStrategyprivat ist und meine Injektion nur das gezeigte Muster verwendet.

Telastyn
quelle
Bedeutet dies, dass die abgebildete Kontextklasse weggelassen werden kann, ohne das Muster zu beeinträchtigen? Oder anders ausgedrückt, ist es in Ordnung , wenn meine Client - Klasse ist die dargestellte Kontextklasse?
Panny
6
@panny - Ich zögere, die Frage zu beantworten, da dies darauf hinweist, dass Sie den Punkt der Antwort verpasst haben, und tatsächlich Muster insgesamt. Das Strategiemuster ermöglicht es Ihnen, das Verhalten zu variieren, indem Sie verschiedene konkrete Implementierungen hinter einer Schnittstelle bereitstellen. Es ist ein Konzept , keine Formel .
Telastyn