Seit etwa einem Monat arbeite ich an einem neuen Flexible Learning-Kurs für das CampusLab: Grundlagen der Objektorientierung. Zugegeben, die Objektorientierung ist lange kein Megatrend mehr und es gab kürzlich einige interessante neue Trends wie die funktionale Programmierung. Dennoch gibt es bei unseren Kunden noch einige Teams, die mit der sukzessiven Umstellung prozeduraler Codes auf ein objektorientiertes Design kämpfen und hierbei vor allem Unterstützung beim Aufbau von Knowhow brauchen. In diesem Artikel möchte ich mit Euch eine Erkenntnis aus diesem Projekt teilen. Es handelt sich um eine geschickte Verbindung der beiden objektorientierten Entwurfsmuster „Strategie“ und „abstrakte Fabrik“ aus Gamma et al. (2010).
Zunächst benötigen wir ein anschauliches Alltagsbeispiel. Stellen wir uns also vor, wir entwerfen einen Online-Shop, der verschiedene Artikel in verschiedene Länder verkauft. Dazu zählen zwei Export-Schlager wie ein veganes Mineralwasser und ein Hundekeks, der – klinisch nachgewiesen – den Speichelfluss von Boxern reduzieren soll. Weil beide Artikel in den vielen unterschiedlichen Ländern stets unterschiedlich besteuert werden, brauchen wir länder- und artikelspezifische Mehrwertsteuerstrategien. Der Name lässt schon erkennen, dass wir hier das Strategiemuster anwenden können, um die Preisberechnung von dieser Komplexität (z.B. im Sinne übertrieben großer Fallunterscheidungen und vielen unnötigen Abhängigkeiten) zu befreien:
Bei diesem Muster ist aber zu beachten, dass zu jeder Erzeugung eines Artikelobjekts stets auch das passende Mehrwertsteuerstrategie-Objekt erzeugt und im Attribut „strategie“ abgelegt werden muss. Man kann sich vorstellen, dass bei sehr vielen Artikeln und sehr vielen Strategien ein Entwickler das vielleicht mal vergessen könnte und dass bei jeder Änderung einer Mehrwertsteuerstrategie nach allen Stellen gesucht werden muss, wo die betroffenen Artikel erzeugt werden. Hier kommt das Fabrikmuster wie gerufen, sorgt es sich doch um die Lösung genau solcher komplizierten Erzeugungsprobleme.
Zur Erinnerung: Das Fabrikmuster lagert Code zur einheitlichen Erzeugung von Objekten, der sich häufig ändert oder zu unangenehmen Abhängigkeiten führt, in konkrete Fabrikklassen aus, die ein gemeinsames Fabrik-Interface implementieren. Sie können „Produktfamilien“ erzeugen, worunter in unserem Beispiel die Kombination aus einem konkreten Artikel und der dazu passenden konkreten Strategie gemeint ist. Schauen wir uns die Kombination des Fabrik- und Strategiemusters am Beispiel an:
Wir entwerfen ein Artikelfabrik-Interface, das die beiden Methodensignaturen zur Erzeugung von Artikeln und Mehrwertsteuerstrategien festlegt. Für jede Kombination aus Artikel und Land wird dann eine konkrete Fabrik implementiert, die sich neben der Erzeugung des konkreten Artikels auch um die Erzeugung der entsprechenden länderspezifischen Mehrwertsteuerstrategie kümmert. Doch wozu dieser Aufwand? Wir haben jetzt deutlich mehr Klassen in unserem Code als vorher!
Stimmt. Der Entwickler wird es etwas schwerer haben – vor allem, wenn er die Muster nicht kennt – auf den ersten Blick die Abhängigkeiten zwischen den Klassen zu verstehen. Wir erkaufen uns damit aber ein paar sehr entscheidende Vorteile: Sollte irgendein Land mal wieder seine Mehrwertsteuer anpassen (z. B. weil deutsche Behörden zu dem Schluss kommen, dass Hundekekse nicht mehr subventioniert werden sollten), schlägt diese Änderung nur noch in der konkreten Fabrik auf – nirgendwo anders! Oder wird ein neuer Artikel in das Sortiment aufgenommen, wird der Programmierer anhand des bestehenden Quellcodes sofort erkennen, dass dafür eine Fabrik eingesetzt werden muss, die er noch zu implementieren hat. Probiert es mal an einem Beispiel aus!
- Gamma, E. et al. (2010): Entwurfsmuster: Elemente wiederverwendbarer objektorientierter Software., 6. Auflage, Addison-Wesley. ISBN 9783827330437.