Objektorientierte Programmierung: Teil 1 – OOP in der Praxis
Ableitungen noch und nöcher
Ein sehr mächtiges Mittel der objektorientierten Programmierung ist die Ableitung bzw. Generalisierung. Mit ihrer Hilfe kann man bereits bestehende Klassen um weitere Eigenschaften (Attribute und Operation) erweitern. Dieses Mittel soll benutzt werden, um den Nachteil zu beheben, dass die Methode acceptOffer
der Klasse Bot
bei sehr vielen Strategien zu unübersichtlich wird.
Das heißt, dass man eine Basisklasse BaseBot
erstellt und die konkreten Ableitungen davon die jeweilige Strategie umsetzen. Damit nicht jeder konkrete Bot die Punkte zählen muss, übernimmt die Basisklasse diese Aufgabe.
Die CRC-Karten schauen nun wie folgt aus:
- Klasse:
BaseBot
- Benötigt:
- –
- Verantwort.:
- Basisklasse, welches die angenommenen Punkte zählt
- Klasse:
AcceptBot
- Basisklasse:
BaseBot
- Benötigt:
- –
- Verantwort.:
- nimmt ein Angebot immer an
- Klasse:
DeclineBot
- Basisklasse:
BaseBot
- Benötigt:
- –
- Verantwort.:
- lehnt ein Angebot immer ab
- Klasse:
VariableBot
- Basisklasse:
BaseBot
- Benötigt:
- –
- Verantwort.:
- entscheidet variabel, ob ein Angebot abgelehnt oder angenommen wird
Klasse:
Game
Benötigt:
BaseBot
,AcceptBot
,DeclineBot
,VariableBot
Verantwort.:
- erstellt den richtigen Bot; liest Benutzereingabe und fragt Bot nach Annahme oder Ablehnung
Man hat zwar nun die vorherige Klasse Bot
in verschiedene konkrete Klassen aufgeteilt, dadurch erhält die Klasse Game
aber auch mehr Abhängigkeiten, da sie die drei konkreten Bots alle erzeugen muss.
Daneben hat man auch eine Abhängigkeit zur Basisklasse BaseBot
, da man die Punkte am Ende ausgeben will und getPoints
aufrufen muss.
Die konkreten Bots hängen natürlich von der Basisklasse BaseBot
ab.
Die oben stehenden Bot-Klassen haben nun alle nur noch eine Verantwortlichkeit, was sehr gut ist. Daneben ist es schön, dass man, um eine neue Strategie einzubringen, nur die Klasse BaseBot
ein weiteres Mal ableiten muss.
Ein Nachteil jetzt ist aber die Erweiterbarkeit. Will man einen neuen Bot hinzufügen, muss man die Klasse Game
entsprechend anpassen, da sie den richtigen Bot erstellen muss. Wenn man das oft genug macht, fragt man sich, ob es eine gute Idee war, Game
und die jeweiligen Bot-Implementierungen so eng miteinander zu verknüpfen.
Ebenso leidet aber auch die Wartbarkeit. Ändert sich eine der konkreten Bot-Deklarationen (weil z.B. ein Bot für seine Strategie weitere Attribute benötigt), muss auch die Bibliothek libgame
neu übersetzt werden.
Die Übersichtlichkeit ist zwar noch gewährleistet, man stelle sich aber vor, der Bot hätte noch zwei andere Eigenschaften in jeweils drei Ausprägungen, die in verschiedenen Kombinationen auftreten können. Dann müsste man im Extremfall 27 (3 hoch 3) Klassen erstellen, die alle diese Möglichkeiten abbilden.
Die C++-Implementierung der obigen Klassen kann als Archiv heruntergeladen werden: oop2-beispiel.tar.gz.
Ausblick
Im nächsten Teil soll das erste Entwurfsmuster vorgestellt werden, welches im Design dieses Teiles bereits ein bisschen benutzt wurde.
Autoreninformation
Dominik Wagenführ (Webseite) ist C++-Software-Entwickler und hat täglich mit Software-Design zu tun. Dabei muss er sich immer Gedanken machen, dass seine Software auch in Zukunft einfach wartbar und leicht erweiterbar bleibt.
Dieser Artikel ist in freiesMagazin 03/2012 (ISSN 1867-7991) erschienen. Veröffentlichung mit freundlicher Genehmigung.