Login
Newsletter
Werbung

Do, 17. Mai 2012, 15:00

Objektorientierte Programmierung: Teil 2 - Die richtige Strategie

Der Begriff der objektorientierten Programmierung (kurz OOP) existiert schon eine ganze Weile. Wer zuvor prozedural programmiert hat, erwischt sich beim Übergang zu OOP öfter dabei, wie er die früheren Funktionen einfach mit einer Klasse umgibt und dies als objektorientierte Programmierung verkauft. Die Artikelreihe soll an einem einfachen Beispiel zeigen, was man in so einem Fall besser machen könnte.

Hinweis: Bevor man im Artikel fortfährt, sollte man sich den vorherigen Teil der Reihe durchgelesen haben (siehe Objektorientierte Programmierung: Teil 1). Alle Artikel dieses Workshops finden Sie in der Übersicht.

Die Wahl der richtigen Strategie

Ein sehr beliebtes und bekanntes Entwurfsmuster ist das Strategie-Muster. Es dient vorrangig dazu, verschiedene Verhalten als Klassen umzusetzen, die von einer Basisklasse abgeleitet sind. »Außen« nutzt man dann nur diese Basisklasse, die konkreten Strategien sind dem Nutzer unbekannt. Zusätzlich ist es möglich, zur Laufzeit einer Klasse ein neues Verhalten/eine neue Strategie zu geben.

Dies wurde ansatzweise auch schon in der letzten Umsetzung gemacht, bei der jeder konkrete Bot von einer Basisklasse BaseBot abgeleitet war. Ein großer Unterschied besteht aber darin, dass es damals kein Verhalten war, dass man erstellt hat, sondern ein bestimmter Typ.

Design

Das Strategie-Entwurfsmuster wird eins zu eins umgesetzt, wie es von der »Gang of Four« vor langer Zeit definiert wurde. Da die Basisklasse aller konkreten Strategien keinerlei Logik umfasst, wird ein Interface IStrategy benutzt.

Der Bot enthält dann dieses Interface als Strategie. Hierfür wurde eine Aggregation gewählt, weil die Strategie auch ohne Bot existieren kann (und wird), da sie von Game erzeugt wird. Der Bot übernimmt dann nur noch dessen Zerstörung beim Beenden.

Das Strategie-Muster in der Umsetzung

Dominik Wagenführ

Das Strategie-Muster in der Umsetzung

Klassenaufteilung

Klasse:
IStrategy
Benötigt:
-
Verantwort.:
Interface für die konkreten Strategien, um ein Angebot anzunehmen oder abzulehnen

Klasse:
AcceptStrategy
Basisklasse:
IStrategy
Benötigt:
-
Verantwort.:
nimmt ein Angebot immer an

Klasse:
DeclineStrategy
Basisklasse:
IStrategy
Benötigt:
-
Verantwort.:
lehnt ein Angebot immer ab

Klasse:
VariableStrategy
Basisklasse:
IStrategy
Benötigt:
-
Verantwort.:
entscheidet variabel, ob ein Angebot abgelehnt oder angenommen wird

Klasse:
Bot
Benötigt:
IStrategy
Verantwort.:
zählt die angenommenen Punkte

Klasse:
Game
Benötigt:
Bot, VariableStrategy, IStrategy, AcceptStrategy, DeclineStrategy
Verantwort.:
erstellt den Bot und die richtige Strategie dazu; liest Benutzereingabe und fragt Bot nach Annahme oder Ablehnung

Abhängigkeiten

Das Interface IStrategy und die konkreten Strategien haben keine Abhängigkeiten.

Der Bot ist nur vom Interface IStrategy abhängig, nicht aber von den konkreten Strategien.

Da die Klasse Game die konkreten Strategien erstellen muss, hängt es von diesen auch ab. Zusätzlich erstellt sie auch den Bot und gibt dessen Punkte am Ende aus.

Vor- und Nachteile

Das Design der Klasse Bot ähnelt sehr stark dem ersten Ansatz im ersten Teil. Der große Unterschied ist, dass die Strategie durch ein echtes Objekt und nicht nur durch einen String repräsentiert werden muss.

Der Vorteil ist nun, dass der Bot dank des Strategie-Musters die konkreten Strategien nicht kennen muss und völlig losgelöst davon arbeiten kann. Mit diesem Design hat man das Design-Prinzip »Programmiere gegen Schnittstellen, nicht gegen Implementierungen« umgesetzt.

Auch hat der Bot nun wirklich nur eine Aufgabe, nämlich Punkte zählen. Die Entscheidung, ob ein Angebot angenommen oder abgelehnt wird, muss er selbst nicht mehr treffen, dies übernimmt seine gesetzte Strategie.

Das Strategie-Muster hat auch den Vorteil, dass zusätzliche, ganz andere Verhaltensweisen des Bots leicht ergänzt werden können. Hätte der Bot zwei weitere Verhaltensarten, die es in jeweils drei unterschiedlichen Ausprägungen gibt, erweitert man die Klasse Bot um zwei Interfaces und fügt insgesamt acht neue Klassen (pro Verhalten ein Interface und drei Realisierungen) hinzu.

Der Nachteil der Erweiterbarkeit bleibt aber nach wie vor. Es ist zwar extrem leicht, eine neue Strategie zu realisieren und diese dem Bot unterzuschieben, aber dennoch muss die Klasse Game alle konkreten Strategien kennen. Wird eine neue Strategie hinzugefügt, muss auch Game angepasst werden. Das ist also immer noch nicht die ultimative Lösung.

Implementierung

Die C++-Implementierung der obigen Klassen kann als Archiv heruntergeladen werden: oop3-beispiel.tar.gz.

Kommentare (Insgesamt: 6 || Alle anzeigen )
Design Pattern Seite (Dexter, Fr, 18. Mai 2012)
Re[2]: WTF (ich, Fr, 18. Mai 2012)
Re: WTF (cs, Fr, 18. Mai 2012)
Re: WTF (sothis, Fr, 18. Mai 2012)
Re: WTF (Pffft..., Do, 17. Mai 2012)
Pro-Linux
Pro-Linux @Facebook
Neue Nachrichten
Werbung