Polymorphismus vs. Strategiemuster

Lesezeit: 11 Minuten

Benutzer-Avatar
TryinHard

Was ist der Unterschied zwischen der Strategy Muster u Polymorphism auf Java?

Ich bin verwirrt, dass alles, was über das Strategiemuster erreicht wird, im Grunde durch Polymorphismus möglich ist. Korrigiert mich, wenn ich in dieser Hinsicht falsch liege.

Bitte geben Sie mir auch ein Beispiel, um meine Verwirrung zu beseitigen.

  • Es geht um Äpfel und Birnen, da Sie kein Strategiemuster haben können ohne Polymorphismus als Schnittstelle muss implementiert werden, daher ist Ihre Frage für mich verwirrend.

    – Hovercraft voller Aale

    24. Juli 2015 um 11:05 Uhr


  • Ich denke, er möchte nur ein Beispiel, in dem das Strategiemuster nützlicher ist als Polymorphismus. Dies geschieht, wenn Sie verschiedene Strategien für mehrere Objekte wiederverwenden möchten. Andernfalls macht es wirklich keinen Sinn und Sie sollten Polymorphismus verwenden.

    – Joshua Byer

    24. Juli 2015 um 23:57 Uhr

  • Related Welches Muster verwendet Collections.sort mit einem Comparator?

    – Chetan Kinger

    26. Februar 2017 um 6:00 Uhr


Benutzer-Avatar
rolgalan

Für mich ist der Link aus König post und das Beispiel in Wikipedia sind klar genug, aber ich werde versuchen, Ihnen ein neues Beispiel zu geben. Wie sie sagten, ist Strategiemuster meistens eine Möglichkeit, das Verhalten eines Algorithmus zur Laufzeit zu ändern. Natürlich können Sie dies auf viele verschiedene Arten erreichen (z. B. indem Sie einen Wert halten und switch-case verwenden, aber es wäre nicht so schön wie Strategy Pattern).

Nehmen wir an, Sie entwickeln ein rundenbasiertes Strategiespiel mit zwei Arten von Einheiten: Infanterie und Panzer (Unterklassen von Unit). Ihr Terrain könnte sein Ebenen, Eisenbahn oder Wälder.

class Unit{
    MovementStrategy ms;      
    final int baseMovement;
    int x,y;

    public Unit(int baseMovement){
        this.baseMovement = baseMovement;
    }

    abstract void fire();

    void moveForward(){
        x = x + ms.getHexagonsToMove(baseMovement);
    }

    void setMovementStrategy(MovementStrategy ms){
        this.ms = ms;
    }
}

Jede Unit-Unterklasse muss implementiert werden Feuer() Methode, weil für sie wird es ganz anders sein (Panzer schießt schwere Langstreckengeschosse und Infanterie schießt mehrere leichte Kurzstreckengeschosse). In diesem Beispiel verwenden wir seitdem normalen Polymorphismus/Vererbung Feuer() Methode wird für jede Einheit wirklich anders sein, und es wird sich während des Spiels nicht ändern.

class Infantry extends Unit{
    public Infantry(){
        super(2);
    }

    void fire(){
        //whatever
    }
}

class Tank extends Unit{
    public Tank(){
        super(5);
    }

    void fire(){
        //whatever
    }
}

Einheiten können sich auch bewegen und haben ein Feld basisBewegung das enthält die Anzahl der Sechsecke, die es gehen kann. Wir entwickeln ein Strategiespiel, keine Simulation der realen Welt, also ist es uns egal, wie sie sich bewegen, wir wollen nur einen Wert zu ihren Koordinaten hinzufügen (in meinem Beispiel verwende ich nur die X-Koordinate, um einen einfacheren Code zu erhalten ). Wenn das gesamte Gelände gleich wäre, bräuchten wir kein Strategieobjekt … aber wir müssen das Verhalten der Methode move() zur Laufzeit ändern!

Also implementieren wir eine andere BewegungsStrategie Klasse für jede unserer Geländearten, und wir programmieren unser Spiel so, dass es a auslöst setBewegungsstrategie() zu jeder Einheit, die sich auf jedem Sechseck bewegt. Und wir brauchen nicht einmal etwas anderes in unsere Unit-Unterklassen zu schreiben.

interface MovementStrategy{
    public int getHexagonsToMove(int base);
}

class PlainMovementStrategy implements MovementStrategy{
    public int getHexagonsToMove(int base){
        return base;
    }
}

class RailroadMovementStrategy implements MovementStrategy{
    public int getHexagonsToMove(int base){
        return base*3;
    }
}

class ForestMovementStrategy implements MovementStrategy{
    public int getHexagonsToMove(int base){
        return (int)(base/2);
    }
}   

Nun, wenn überhaupt Einheit bewege dich nach innen a Waldwir nennen

unit.setMovementStrategy(new ForestMovementStrategy());

Und sobald es um a geht Schmuckloswir machen:

unit.setMovementStrategy(new PlainMovementStrategy());

Jetzt können wir ändern, wie weit sich unsere Einheiten je nach Terrain bewegen, und wir müssen keine der Unterklassen neu schreiben.

Ich hoffe, dies hilft Ihnen, den Unterschied besser zu verstehen.

  • Ich frage mich nur: Gibt es einen Vorteil, eine Aufzählung für dieses spezielle Beispiel zu verwenden, anstatt jedes Mal ein neues Objekt zu erstellen, wenn der Standort die Bewegungsstrategien ändert?

    – D. Ben Knoble

    31. Juli 2015 um 19:23 Uhr

  • Enum könnte hier funktionieren, Sie können einer Aufzählung sogar abstrakte Methoden hinzufügen. Wenn Sie jedoch dieser Route folgen, schlage ich vor, dass die Aufzählung eine Schnittstelle implementiert. Auf diese Weise können Sie die Enum-Implementierung jederzeit durch eine andere Implementierung austauschen, ohne dass die aufrufende Klasse stark umgestaltet werden muss.

    – ein Glasmann

    31. Juli 2015 um 20:08 Uhr

Benutzer-Avatar
Chetan Kinger

Ich bin verwirrt, dass alles, was über das Strategiemuster erreicht wird, im Grunde durch Polymorphismus möglich ist.

Ohne Lenkrad kann man kein Auto fahren. Das bedeutet nicht, dass ein Lenkrad ein Auto ist. In ähnlicher Weise beruht das Strategiemuster auf Polymorphismus, aber das bedeutet nicht, dass sie dasselbe sind.

Der Zweck des Strategiemusters besteht darin, die Verwendung von Komposition (has-a) gegenüber Vererbung (is-a) zu fördern. Anstatt dass Ihre Klasse das Verhalten von einer Superklasse erbt, definieren Sie das Verhalten in einer separaten Klasse und Ihre Klasse hat einen Verweis darauf.

Soweit ein Beispiel geht, werfen Sie einen Blick auf Dies Antwort, die einen guten Job macht.

Benutzer-Avatar
Premraj

  • Grundlegender Unterschied: Polymorphismus ist Programmiersprachenkonzept, und Strategiemuster ist einer von Behavioral Design Pattern von GoF.

  • Polymorphismus ist die Bereitstellung einer einzigen Schnittstelle für mehrere verschiedene zugrunde liegende Datentypen.

    • Beispiel: Das Lenkrad (dh die Schnittstelle) ist gleich, unabhängig davon, welche Art von tatsächlichem Lenkmechanismus verwendet wird. Das heißt, das Lenkrad funktioniert gleich, unabhängig davon, ob Ihr Auto über eine manuelle Lenkung, eine Servolenkung oder eine Zahnstangenlenkung verfügt. Sobald Sie also wissen, wie man das Lenkrad bedient, können Sie jede Art von Auto fahren.

    • Beim Programmieren Polymorphismus auf zwei Arten implementiert:

      • Early-Binding/Static/Compile-Time Polymorphism (z. B. Funktionsüberladung)
      • Late-Binding/Dynamic/Run-Time Polymorphism (ex: function overriding)
  • EIN Strategiemuster definiert eine Reihe von Algorithmen, die austauschbar verwendet werden können.

    • Das Strategiemuster ist ein dynamisches Muster (Wie soll ein Verhalten in der Software ausgeführt werden?).

    • Beispiel für Core-Java: java.util.Comparator#compare()ausgeführt von unter anderem Collections#sort().

    • Verkehrsmitteln ist analog zu Strategie-Entwurfsmuster. Wir nutzen Auto, Fahrrad, Bus, Nahverkehrszug und so weiter. Tag für Tag gehen wir mit unterschiedlichen Strategien ins Büro.

  • java.util.Comparator#compare() ist ein großartiges Beispiel!! Jetzt schäme ich mich, dass ich nicht zuerst daran gedacht habe. Ich verwende es häufig in meinen Projekten.

    – Rollgalan

    28. Juli 2015 um 13:43 Uhr

  • Wenn java.util Comparator#compare ein Beispiel für das Strategiemuster ist, sind Strategiemuster und Polymorphismus dann ein und dasselbe? Wenn ja, was ist dann der Unterschied zwischen Polymorphismus und Strategiemuster?

    – Chetan Kinger

    22. Juni 2019 um 19:10 Uhr


Wenn Sie eine Analogie herstellen, in der:

  • in einem Fall haben Sie mehrere überschreibbare Methoden;
  • im anderen Fall haben Sie eine Strategy-Schnittstelle mit mehreren Implementierungen,

dann ist der Unterschied der Grad der Kopplung, der im ersten Fall sehr stark ist, während im zweiten Fall jeder Fremdcode an der Logik Ihrer Klasse teilnehmen kann, indem er zu seiner Strategieimplementierung beiträgt.

Benutzer-Avatar
Edwin Dalorzo

Q: Was ist der Unterschied zwischen dem Strategiemuster und Polymorphismus in Java?

Die Fragen sind sicherlich verwirrend, da es zunächst keinen Zusammenhang zwischen diesen beiden Ideen zu geben scheint.

Polymorphismus ist ein viel breiteres Konzept in der Programmierung, und ja, das Strategiemuster in Java verwendet eine Form von Polymorphismus, die als katalogisiert wird Inklusionspolymorphismus um seine Absicht zu erreichen, aber dies ist keineswegs die einzige Art von Polymorphismus, die existiert, und es ist auch nicht die einzige Möglichkeit, das Strategiemuster zu implementieren, wie ich bald zeigen werde.

Auch Polymorphismus ist nicht etwas, das nur in Java oder in objektorientierten Programmiersprachen existiert. In allen Programmierparadigmen gibt es verschiedene Formen von Polymorphismus, und nicht in allen Sprachen sind Sie gezwungen, Polymorphismus zu verwenden, um ein Strategiemuster zu implementieren (z. B. funktionale Sprachen).

Für weitere Diskussionen zu diesem Thema lesen Sie bitte diese andere Antwort, in der wir diskutiert haben, ob Polymorphismus ohne Vererbung möglich ist, und ich gebe interessante Referenzen und Beispiele für andere Arten von Polymorphismus wie parametrischen und Ad-hoc-Polymorphismus.

Im Idealfall wird Ihnen dies zeigen, dass Polymorphismus ein umfassenderes Konzept ist, das über die Grenzen der objektorientierten Programmierung und sogar über Vererbung und Subtypisierung hinausgeht.

Q: Ich bin verwirrt, dass alles, was über das Strategiemuster erreicht wird, im Grunde durch Polymorphismus möglich ist. Korrigiert mich, wenn ich in dieser Hinsicht falsch liege.

Aus meiner Sicht bestehen die Beziehungen zwischen diesen beiden Konzepten darin, dass das Strategiemuster die in Sprachen wie Java verfügbare Kraft des Polymorphismus nutzt, um seine Absicht zu implementieren, und dass der Polymorphismus an sich als Muster betrachtet werden kann.

Betrachten Sie zum Beispiel dieses Zitat aus dem GoF-Buch:

Wenn wir von prozeduralen Sprachen ausgegangen wären, hätten wir möglicherweise Entwurfsmuster namens „Vererbung“, „Kapselung“ und „Polymorphismus“ aufgenommen.

Es ist nur so, dass wir Polymorphismus selten als Muster betrachten, erstens, weil er viele Dinge impliziert und weil er in verschiedenen Sprachen unterschiedlich implementiert ist und weil er sich typischerweise als eine Form von Sprachmerkmal darstellt.

In seinem Buch Elemental Design Patterns kommentiert Jason Mc C. Smith das obige GoF-Zitat mit den Worten:

Muster sind sprachunabhängige Konzepte; Sie nehmen Form an und werden zu konkreten Lösungen, wenn Sie sie in einer bestimmten Sprache mit einem bestimmten Satz von Sprachmerkmalen und -konstrukten implementieren […]
Das bedeutet, dass es etwas seltsam ist, über „Java-Entwurfsmuster“, „C++-Entwurfsmuster“, „Websphere-Entwurfsmuster“ und so weiter zu sprechen, obwohl wir das alle tun. Es ist eine leicht faule Form der Abkürzung für das, was wir wirklich meinen oder bedeuten sollten: Entwurfsmuster, wie sie in Java, C++, WebSphere usw. implementiert sind, unabhängig von Sprache oder API.

Wie Sie also sehen können, denken Sie beim Strategiemuster aus der Perspektive der Java-Implementierung, aber in anderen Sprachparadigmen wurden solche Muster möglicherweise auf andere Weise implementiert, wahrscheinlich ohne Verwendung von Vererbung, zum Beispiel rein funktional Programmiersprachen wird dies mit Sicherheit implementiert Funktionen hoher Ordnung und Funktion Zusammensetzung.

Als solches wäre dies eine Strategiemusterimplementierung, ohne darauf zurückzugreifen Inklusionspolymorphismus überhaupt. In einer Funktionskompositionsstrategie können wir immer noch andere Formen des Polymorphismus verwenden (z. B. parametrisch), aber das ist keine Voraussetzung für das Strategiemuster

F: Bitte geben Sie mir auch ein Beispiel, um meine Verwirrung auszuräumen.

Wie oben besprochen, sind wir in Java wahrscheinlich gezwungen, Einschlusspolymorphismus zu verwenden, um ein Strategiemuster zu implementieren, aber wie oben auch erklärt, gehören Muster nicht zu einer bestimmten Sprache, also wenn wir uns das Strategiemuster als ein lebendiges Konzept vorstellen Außerhalb von Sprachgrenzen werden Sie leicht sehen, dass andere Sprachen dies auf unterschiedliche Weise implementieren.

In einer hypothetischen funktionalen Sprache habe ich möglicherweise eine Funktion, die einige Daten aus einer Datei liest, möglicherweise ist die Datei verschlüsselt und Sie müssen eine Entschlüsselungsstrategie bereitstellen:

function readFile(path: String, decrypt: string -> string) {
    return decrypt(loadFromDisk(path));
}

Und das decrypt Argument ist eine Funktion, die dem Zweck eines Strategiemusters dient, es kapselt einen austauschbaren Algorithmus.

Jetzt können Sie tun

readFile("customers.txt", aes)
readFile("finance.txt", blowfish)

Wo aes und blowfish sind Entschlüsselungsfunktionsstrategien.

Es gibt Dutzende von Sprachen, die so funktionieren, SML, Haskell, JavaScript usw.

Benutzer-Avatar
Hermann Wilen

Zuerst. Polymorphismus kann zwei verschiedene Dinge bedeuten. Am häufigsten bezieht sich Polymorphismus auf einen polymorphen Typ. Sie fragen jedoch nach dem Muster.

Polymorpher Code kann sich bei jeder Ausführung selbst ändern, während die Funktion des Codes gleich bleibt. Ein einfaches Beispiel ist 1+3=4 statt 5-1=4. Beide erzielen das gleiche Ergebnis mit unterschiedlichem Code. Dies ist nützlich für Code, der nicht erkannt werden möchte, z. B. Computerviren oder kryptografische Codes.

Das Strategiemuster hingegen verwendet eine Familie von Algorithmen, die ausgetauscht werden können. Dies kann beim Übersetzen von Text verwendet werden. Zuerst bestimmt ein Code die Sprache. Wenn die Sprache Schwedisch oder Spanisch ist, wird der Text von verschiedenen Funktionen derselben Familie, translateSwedish() oder translateSpanish(), verarbeitet.

Um die Dinge abzurunden. Polymorpher Code verwendet unterschiedlichen Code, der das gleiche Ergebnis erzielt. Während Strategy anderen Code verwendet, um bessere Ergebnisse zu erzielen.

Benutzer-Avatar
Joshua Byer

Bedenken Sie

Wir haben Tiere und ein Strategiemusterobjekt, um zu beschreiben, wie sie sich bewegen … zum Beispiel

fliegen/schwimmen/gehen

Angesichts der großen Anzahl von Tieren, die eine dieser Methoden verwenden (dh Tausende von verschiedenen Tieren fliegen), müssen wir denselben Code für viele verschiedene Tiere verwenden. Dieser Code sollte nur an einer Stelle vorhanden sein, damit er leicht geändert werden kann und keinen unnötigen Platz einnimmt.

In diesem Beispiel führt ein einfacher Polymorphismus-Ansatz zu einer massiven Code-Duplizierung. Ein komplexerer Ansatz, der eine Zwischenklasse zwischen Tier und beispielsweise Rotkehlchen einordnet, berücksichtigt nicht, dass die Art und Weise, wie sich ein Tier bewegt, nicht wirklich das ist, was es definiert. Darüber hinaus ist es möglich, dass ein Tier andere Strategieobjekte hat und diese nicht alle durch Zwischenklassen polymorph gemacht werden können.

1055790cookie-checkPolymorphismus vs. Strategiemuster

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy