Entwurfsmuster ausgesetzt: Strategiemuster

In diesem Blog werden wir das Strategiedesignmuster aufdecken, mit dem eine austauschbare Familie von Algorithmen erstellt wird, die dynamisch ausgewählt werden können.

'

Willkommen zum ersten Beitrag der Reihe „Design Patterns Exposed“. In dieser Serie werden wir jedes Designmuster von Grund auf neu aufdecken.



Wenn Sie nur eine Programmiersprache und ihre Konstrukte kennen, werden Sie kein besserer Programmierer oder Entwickler. Es erfordert Kenntnisse über Entwurfsmuster, um Software zu erstellen, die heute und auch in Zukunft funktioniert.

Viele Entwickler sind bereits auf die Designprobleme gestoßen, mit denen Sie derzeit oder in Zukunft konfrontiert sind. Sie haben eine Standardmethode für den Umgang mit diesem Problem festgelegt. Durch die Verwendung von Design Patterns erhalten Sie den Vorteil, bewährte Techniken zu verwenden.

Jedes Entwurfsmuster dient zur Lösung einer bestimmten Art von Situation. Es kann Situationen geben, in denen mehr als ein Entwurfsmuster verwendet werden kann.

Die meisten Programmierer versuchen nur, das Problem zu lösen, ohne sich um Entwurfsmuster, redundanten Code oder sogar enge Kopplung zu kümmern. Aber gute Programmierer fangen anders an. Sie denken über die heutigen Anforderungen, zukünftigen Anforderungen, die Pflege von Code und die Wiederverwendbarkeit von Code nach.

Gute Programmierer haben es nicht eilig, mit dem Codieren zu beginnen, sobald sie die Anforderungen erfüllt haben. Sie sitzen und denken über das Problem nach, ob ihr Design funktionieren wird. Wenn ja, ob es nach 6 Monaten funktioniert, wenn sich die Anforderungen ändern.

Gute Programmierer nehmen Stift und Papier und beginnen, ihre Klassen und Beziehungen zwischen Klassen zu entwerfen. Sie versuchen, eine lose Kopplung und einen hohen Zusammenhalt in ihrem Design zu erreichen, während sie all dies tun und dabei objektorientierte Prinzipien im Kopf haben. Sie gehen nicht sofort in den Low-Level-Code ein. Um flexible und wiederverwendbare Software zu entwerfen, sollten Sie diesen Ansatz befolgen, da Sie sonst immer Code ändern, den Sie zuvor geschrieben haben.

Es gibt nur eine Sache, die in der Softwareindustrie konstant ist, nämlich Veränderung. Die Anforderungen werden sich sicherlich weiter ändern. Wie gestalten wir die Software, die Ihr Code problemlos an zukünftige Anforderungen anpassen kann? Dazu müssen Sie früh beginnen und es so gestalten, dass zukünftige Anforderungen Ihren vorherigen Code nicht beschädigen.

Wie kann ich das machen?

Nun, dies kann erreicht werden, indem Designprinzipien und Designmuster befolgt werden, die auf diesen Prinzipien basieren.

Lassen Sie uns nun in die Codierung eintauchen und uns auf den Weg machen, um ein besserer Programmierer zu werden. In diesem Beitrag werden wir eines der wichtigsten Muster aufdecken - Strategiemuster .

Wenn ich das Wichtigste sage, reflektiert es das allgemeine Problem, das durch das Strategiemuster gelöst wird.

Was ist ein Strategiemuster?

Hier ist die Definition direkt aus dem Buch „Gang of Four“:Das Strategiemuster wird verwendet, um eine austauschbare Familie von Algorithmen zu erstellen, aus denen zur Laufzeit der erforderliche Prozess ausgewählt wird”.

Falls Sie es sindnicht in der Lage zu verstehen, keine Sorge, wir werden es in einem erkläreneinfacherWegfür dich zumverstehen.

Lassen Sie uns zuerst das Problem verstehen und dann sehen, wie Strategy Pattern das lösen kann.

Im obigen UML-Diagramm haben wir eine abstrakte Tierklasse und zwei konkrete Klassen, Hund und Vogel, die sich von der Superklasse Tier erstrecken.

Definieren wir also eine abstrakte Tierklasse und zwei konkrete Klassen, Hund und Vogel.

Was denkst du über das obige Design? Es gibt einen großen Fehler in unserem Design.

Alle Tiere können nicht fliegen, wie im obigen Fall ein Hund nicht fliegen kann. Trotzdem hat es ein 'Fliegen' -Verhalten.

Wir haben einen Fehler gemacht, indem wir die abstrakte fly () -Methode in die Animal-Klasse geschrieben haben. Dieses Design zwingt jeden Hund, Vogel, Pinguin, Krokodil, Gans usw. der Unterklasse, die fly () -Methode zu implementieren.

Wir hätten verstehen müssen, dass Fliegen eine Fähigkeit ist, die nicht alle Tiere haben werden. Durch die Bereitstellung der fly () -Methode in der abstrakten Tierklasse haben wir die Flugfähigkeit in allen Unterklassen festgelegt, die nicht für alle Unterklassen von Tieren korrekt ist.

Sie könnten sich überlegen, wo das Problem bei der Implementierung der fly-Methode in den Unterklassen liegt. Obwohl Sie die fly () -Methode in den Unterklassen für nicht fliegende Tiere implementieren können, geben Sie einfach 'Ich kann nicht fliegen' aus. Das Problem ist jedoch, dass Sie nichtfliegenden Tieren immer noch das Flugverhalten geben. Das ist nicht richtig.

Wie fühlt es sich an, dog.fly () oder crocodile.fly () aufzurufen?

Jetzt haben wir verstanden, dass unser Design nicht korrekt ist und wir sollten die fly () -Methode aus der Animal-Unterklasse entfernen.

Was ist die andere Art, unsere Klassen so zu gestalten, dass unser Design nicht alle Tier-Unterklassen dazu zwingt, Flugverhalten zu haben?

Eine Lösung, die sofort in den Sinn kommt, ist, dass wir eine Flugschnittstelle mit Flugmethode erstellen können und nur Tiere, die fliegen können, diese Flugschnittstelle implementieren. Auf diese Weise werden nicht alle Tierunterklassen gezwungen, ein Flugverhalten zu definieren. Codieren wir also diesen Entwurfsansatz.

Jetzt sieht unsere Animal-Klasse wie folgt aus, nachdem die fly-Methode aus der Animal-Klasse entfernt wurde.

Definieren wir nun die Flugschnittstelle

Jetzt wird die Hundeklasse geändertwieden Code unten und es muss kein Flugverhalten haben.

Sehen wir uns einige unserer Tier-Unterklassen an, die Flugverhalten haben.

Wir haben unser vorheriges Problem gelöst, aber wir sind in ein neues Problem geraten, und das ist 'Code-Duplizierung'.

Angenommen, wir werden 100 verschiedene fliegende Tier-Unterklassen haben. Wir müssen den Code für das Flugverhalten duplizieren, da die Flugschnittstelle keine Implementierung für das Flugverhalten bereitstellen kann. Wenn wir später die Implementierung der fly () -Methode in einer Unterklasse ändern möchten, müssen wir diese Klasse öffnen und den Code ändern. was schlecht ist. Uns fehlt etwas Großes und das heißt, wir können das Flugverhalten einer Klasse zur Laufzeit nicht ändern.

Aber keine Sorge, Strategy Pattern ist da, um Sie aus diesem Problem herauszuholen.

Überarbeiten wir also unseren Code, um das Strategiemuster zu verwenden.

Die Flugschnittstelle bleibt unverändert. Anstatt dass jede fliegende Unterklasse die Flugschnittstelle selbst implementiert, werden wir jetzt separate konkrete Klassen definieren, die ein anderes Flugverhalten implementieren. Mal sehen, wie das geht.

Wie das alles funktioniert, sehen wir uns die TestClass an

Mithilfe des Strategiemusters können wir jetzt das Flugverhalten eines Tieres zur Laufzeit ändern, ohne dass Unterklassen gezwungen werden müssen, das Flugverhalten selbst anzugeben.

Wann sollte das Strategiemuster verwendet werden?

Wenn Sie das Verhalten zur Laufzeit dynamisch ändern möchten.

Um sicherzustellen, dass Sie das Strategiemuster klar verstehen, nehmen wir ein anderes Beispiel.

In der oben genannten Mitarbeiterklasse legen wir die Bezahlung des Mitarbeiters in Abhängigkeit von seiner Bezeichnung fest. Wenn ein Mitarbeiter ein „Praktikant“ ist, addieren wir 10% Bonus zum Grundgehalt, um das tatsächliche Gehalt zu berechnen.

Wenn ein Mitarbeiter ein „Webentwickler“ ist, fügen wir dem Grundgehalt einen Bonus von 20% hinzu, um das tatsächliche Gehalt zu berechnen. Für andere Arten von Mitarbeitern wird ein ähnlicher Vorgang durchgeführt. Obwohl unser Algorithmus zur Berechnung des tatsächlichen Entgelts sehr einfach ist, um das Verständnis zu erleichtern, enthält er meistens viele Vergleiche und Berechnungen.

Was ist also falsch mit dem Code der Mitarbeiterklasse?

Nun, der Code zur Berechnung des Gehalts (getPay ()) ist statisch. Angenommen, ich möchte den Bonus für 'Praktikant' von 10% auf 14% ändern. Ich muss den Code der Mitarbeiterklasse öffnen und ändern.

Ein weiteres Problem ist, dass ich den Gehaltsalgorithmus eines Mitarbeiters zur Laufzeit nicht ändern kann. Also, wie geht das? Das Strategiemuster wird speziell zur Behandlung dieser Art von Problemen verwendet.

Überarbeiten wir den Code, um das Strategiemuster zu verwenden.

Ich werde mehrere Algorithmen definieren, um die Bezahlung zu berechnen. Dann kann ich jeden dieser Algorithmen verwenden, um die Bezahlung zur Laufzeit zu berechnen.

Nun wollen wir sehen, wie sich die Employee-Klasse ändern wird.

Wie funktioniert Tstring in Java?

Hinweis: Ich habe die Lohnberechnungslogik aus der Employee-Klasse entfernt und eine festgelegte PayAlgorithm () -Methode erstellt, mit der ich den PayAlgorithmus festlegen werde, den ich für die Lohnberechnung verwenden möchte.

Dies gibt mir die Flexibilität, die Bezahlung durch dynamische Angabe eines PayAlgorithmus zur Laufzeit zu berechnen. Beachten Sie auch, dass ich später, wenn ich die Lohnberechnungslogik ändern muss, einen neuen PayAlgorithmus erstellen und diesen zur Berechnung des Lohns verwenden kann. Ich muss den vorherigen Code nicht ändern, ist das nicht großartig?

Mal sehen, wie es funktioniert.

Ich hoffe, Sie haben das Strategiemuster sehr gut verstanden. Der beste Weg, etwas zu lernen, ist das Üben.

Wenn Sie Fragen zu Strategiemustern oder anderen Mustern haben, lassen Sie Ihre Fragen unten.

Achten Sie auf den nächsten Beitrag, in dem wir eines der beliebtesten Designmuster, Factory Pattern, aufdecken.

Bis dahin können Sie den Code herunterladen und sicherstellen, dass Sie das Strategiemuster in Ihrem Kopf zementieren.

Hast du eine Frage an uns? Erwähnen Sie sie im Kommentarbereich und wir werden uns bei Ihnen melden.

Zusammenhängende Posts: