Das Wissensportal für IT-Professionals. Entdecke die Tiefe und Breite unseres IT-Contents in exklusiven Themenchannels und Magazinmarken.

SIGS DATACOM GmbH

Lindlaustraße 2c, 53842 Troisdorf

Tel: +49 (0)2241/2341-100

kundenservice@sigs-datacom.de

Keine Angst mehr vor Veränderung

Sie kennen das vielleicht: Man erhält den Auftrag, eine Änderung an einer Komponente durchzuführen, die man nicht selbst erstellt hat, die schon durch viele Hände gegangen ist, kaum unter Testkontrolle steht und eng mit anderen Komponenten gekoppelt ist. Man arbeitet sprichwörtlich an einem Kartenhaus: Jede noch so kleine Änderung kann es zum Einstürzen bringen. Was hat dieser Umstand für einen Einfluss auf die agile Softwareentwicklung und wie kann man dieser Zwickmühle entgehen? In der Arbeit gemäß agiler Vorgehensmodelle manifestiert sich die Forderung nach Änderbarkeit besonders deutlich, da sich ein Produkt über viele Iterationen hinweg weiterentwickelt.

  • 21.12.2018
  • Lesezeit: 17 Minuten
  • 99 Views

Agilität bedeutet Veränderung

Das spiegelt sich auch in den Ratschlägen wider:

  • Reagieren auf Veränderung mehr als das Befolgen eines Plans, heißt es im Manifesto for Agile Software Development [AGI1].
  • Heiße Anforderungsänderungen selbst spät in der Entwicklung willkommen. Agile Prozesse nutzen Veränderungen zum Wettbewerbsvorteil des Kunden ist eines der 12 Prinzipien der agilen Softwareentwicklung [AGI2].
  • Überprüfung & Anpassung sind zwei der Säulen, auf denen Scrum als das am weitesten verbreitete agile Vorgehensmodell steht [SCR1].

Aber wie soll man denn schnell auf Änderungsbedarf reagieren, wenn jede Anpassung ein potenzielles Risiko ist? Wie kann man Software so designen, dass sie auf lange Sicht anpassbar bleibt? Hier kann das sogenannte Open/Closed-Prinzip (OCP, vgl. [Mey88], S. 57–61) Abhilfe schaffen. Die grundlegende Idee dahinter lautet: Designe deine Software so, dass sie offen für Erweiterungen und geschlossen gegenüber Modifikationen ist. “When I summarize agile to people, I usually say there‘s two main pieces to it. [...] but the other is our ability to change rapidly, to be able to deal with change easily.“ Martin Fowler [Fow18] Im Folgenden wird dieses scheinbar widersprüchliche Konzept vorgestellt und seine Bedeutung für die agile Softwareentwicklung erläutert. Weiterhin wird es anhand von Code-Beispielen (geschrieben in Java) verdeutlicht und es wird besprochen, wie das OCP neben dem Design auf operativer Ebene auch in anderen Bereichen der Softwarearchitektur Anwendung finden kann.

Änderungsbedarf als Chance

Die Zusammenarbeit zwischen IT-Abteilung und Fachseite ist in vielen Fällen geprägt von Konflikten und Missverständnissen. Besonders viele Reibungsverluste entstehen bei Änderungen an grundlegenden Anforderungen während eines laufenden Projekts. In so einem Fall kommt es schnell zu gegenseitigen Schuldzuweisungen: Die Fachseite hätte im Vorfeld nicht gründlich analysiert, das Entwicklungsteam hätte Selbstverständlichkeiten nicht erkannt usw. Letztlich ist es jedoch unmöglich, komplexe Systeme schon im Vorfeld eines Entwicklungsprojektes umfassend zu analysieren und alle Eventualitäten (z. B. gesetzliche Änderungen während der Entwicklungsphase) vorauszusehen. Des Weiteren sollte Änderungsbedarf nicht als Problem, sondern als Chance betrachtet werden: „A late change in requirements is a competitive advantage.“ Mary Poppendieck (vgl. [Fow18]) Diese Erkenntnis ist nicht neu und einer der treibenden Faktoren hinter dem agilen Manifest [AGI1]. Änderungen sind gemäß dieser Prinzipien nicht nur unvermeidbar, sondern sogar wünschenswert, wenn sie aus bewussten Entscheidungen entstehen. Neben neuen Anforderungen muss dabei insbesondere auch Änderungsbedarf berücksichtigt werden, der aus Kurskorrekturen oder Fehlerbehebungen entsteht. Dave Thomas mahnt in seinem Vortrag Agile is Dead, dass Softwareentwicklung den Mut braucht, Fehler zu machen und sie zu korrigieren [YouT]. Software-Design ist nie in Stein gemeißelt, sondern ein bewegliches Ziel. Die Fähigkeit, auch während eines Entwicklungsprojekts schnell auf Änderungsbedarf reagieren zu können, ist ein wesentlicher Wettbewerbsvorteil. Insbesondere große und langwierige Projekte profitieren davon. Nun stellt sich aber die Frage: Was bedeutet das konkret? Welche Lösungsansätze existieren, um diesen abstrakten Ansprüchen in der täglichen Projektarbeit gerecht zu werden? Hierzu gibt es eine Vielzahl von Vorschlägen. Besonders hervorzuheben sind dabei die Clean-Code-Richtlinien gemäß Robert C. Martin [Mar08] und darunter vor allem die sogenannten SOLID-Prinzipien:

  • S: Single responsibility principle,
  • O: Open/Closed principle,
  • L: Liskov substitution principle,
  • I: Interface segregation principle,
  • D: Dependency inversion principle.

Jedes dieser Prinzipien ist von wesentlicher Bedeutung für robuste, wartbare Software. In diesem Artikel wird das Open/Closed-Prinzip besprochen, da es die Änderbarkeit von Software in besonderem Maße positiv beeinflusst.

Das Open/Closed-Prinzip – ein scheinbarer Widerspruch erklärt

Die ursprüngliche Idee hinter dem Open/Closed principle (OCP) wurde bereits 1988 von Bertrand Meyer formuliert: „Modules should be both open and closed. [...] A module is said to be open if it is still available for extension. [...] A module is said to be closed if it is available for use by other modules.“ [Mey88] Wenn ein Modul fertiggestellt wurde, soll es nach Meyer also geschlossen gegenüber Modifikationen sein, um die Software robust zu halten. Würde man ein Modul niemals schließen, würde keine Multi-Modul-Software jemals fertiggestellt werden, da man sich nicht sicher sein könne, dass die Arbeit abgeschlossen ist, so Meyer. Da jedoch Veränderungsbedarf entstehen kann, sollen Module gleichzeitig offen für Erweiterungen sein. In Abbildung 1 wird diese Idee visuell verdeutlicht. Statt vorhandene Module zu verändern (farbliche Hervorhebung), sollen Erweiterungen genutzt werden. Veränderungen stellen damit eine geringere Gefahr dar, da Module bei konsequenter Anwendung des OCP nicht mehr modifiziert werden müssen. Die besonders im Kontext der agilen Softwareentwicklung notwendige schnelle Reaktionsfähigkeit auf Veränderungsbedarf und neue Anforderungen wird dadurch gefördert. Die einzelnen Module können sich in jedem Produkt-Inkrement weitgehend gefahrlos wandeln. Meyer schlägt für die Umsetzung des OCP die Nutzung von Vererbung vor. Die ursprüngliche Klasse wird dementsprechend nicht mehr angefasst; bei Bedarf werden stattdessen Sub-Klassen erstellt, in denen Verhalten hinzugefügt werden kann. Die grundlegende Idee ist gut, der Lösungsvorschlag jedoch nicht mehr zeitgemäß. Die Erfahrung hat gezeigt, dass ausufernde Vererbungshierarchien zu unverständlichem und schlecht wartbarem Code führen. „Favor object composition over class inheritance.[...] our experience is that designers overuse inheritance as a reuse technique, and designs are often made more reusable (and simpler) by depending more on object composition.“ (vgl. [GoF04], S. 20). Robert C. Martin hat die Idee von Bertrand Meyer präzisiert: Wenn Verhalten ergänzt wird, sollten dadurch keine Änderungen an anderen Modulen des Systems nötig sein. Neuer Code muss also hinzufügbar sein, ohne alten Code manipulieren zu müssen [Mar13]. Sein verallgemeinerter Vorschlag zur Umsetzung dieser Forderung lautet „Abstraction is the Key“ [OCP]. Verhalten sollte also möglichst oft abstrakt übergeben werden, da es dadurch im Nachhinein leichter ausgetauscht oder um weiteres Verhalten ergänzt werden kann, ohne dass das ausführende Modul manipuliert werden muss. In Kombination mit der Empfehlung „Favor composition over inheritance“ folgt daraus die Verwendung eines Kompositums, das eine einheitliche Fassade besitzt, oder anders ausgedrückt, ein Interface implementiert. Ein Gang-of-Four-Entwurfsmuster, das diesen Anforderungen entspricht, ist die Strategie (vgl. [GoF04], S. 315).

Umsetzung auf operativer Ebene: Strategie

Als Beispiel dient im Folgenden die Berechnung der Beitragshöhe für eine Autoversicherung. Diese geschieht in Abhängigkeit des Fahrzeugsegments und des Fahrers. In Listing 1 ist eine beispielhafte Umsetzung in Java zu sehen. Neben einer hohen zyklomatischen Komplexität von 8 (Anzahl der Pfade, in denen das Modul durchlaufen werden kann; ein hoher Wert deutet auf hohe Komplexität und schlechte Änderbarkeit hin) verstößt dieser Code gegen das OCP. Wenn beispielsweise ein neues Segment (z. B. Sportwagen) berücksichtigt werden soll, müsste dafür das betrachtete Modul um eine weitere IF-Anweisung ergänzt werden, was gemäß OCP nicht erwünscht ist, da es gegenüber Modifikationen geschlossen sein sollte. Zur Lösung dieses Problems kann das Strategie-Entwurfsmuster angewendet werden. Die Idee hinter einer Strategie ist die Kapselung von Verhalten in eine einheitliche Form (z. B. über ein Interface), um sie dadurch (auch zur Laufzeit) austauschbar zu machen. „Every single design methodology can be encapsulated in one sentence: A good design is easier to change than a bad design.“ Dave Thomas Indem man die einzelnen Pfade der in Listing 1 dargestellten Kontrollstruktur in Strategien auslagert, schafft man die Möglichkeit, sie auszutauschen oder weitere Strategien zu ergänzen, ohne das ausführende Modul modifizieren zu müssen. Dafür müssen zunächst ein allgemeines Interface angelegt und einzelne Strategien implementiert werden (Listing 2). Die Strategien sollten für eine komfortable Verwendung in einer Registry eingetragen werden. Hierfür eignet sich zum Beispiel eine Map (Listing 3). Die Umsetzung des in Listing 1 betrachteten Moduls unter Verwendung von Strategien ist in Listing 4 zu sehen. Damit konnte die maximale zyklomatische Komplexität der beteiligten Komponenten auf 3 reduziert werden und es besteht nun die Möglichkeit, Verhalten hinzuzufügen und auszutauschen, ohne das betrachtete Modul modifizieren zu müssen (Listing 5). So wird dem OCP Genüge getan. In fachlich anspruchsvolleren Szenarien werden häufig auch Entscheidungstabellen und Rules-Engines eingesetzt, welche Strategien von außen in die Anwendung injizierbar und von IT-fernem Personal pflegbar machen. Durch den Einsatz von Strategien kann somit Änderungsbedarf, der sich beispielsweise aus neuen User-Storys oder im Rahmen einer Retrospektive ergibt, im nächsten Sprint berücksichtigt werden, ohne dass dies bereits fertiggestellte Komponenten gefährdet. Das hier aufgeführte Beispiel betrachtet allerdings nur einen Teilaspekt des Problems: kleinteilige Algorithmen der operativen Ebene. Diese sind jedoch meist Teile von komplexen Objekt-Bäumen, die jeweils einen fachlichen Belang abbilden. Die Designvorgaben für die operative Ebene stoßen hier an ihre Grenzen, da bereits vorgelagerte Entscheidungen dafür sorgen müssen, dass diese komplexen Komponenten unter Einhaltung des OCP erweitert werden können. Eine Herangehensweise an die Modellierung von Beziehungen zwischen abstrakten Modulen in komplexen Softwaresystemen ist das Domain-Driven Design (DDD). Darin betrachtet das sogenannte taktische Design die einzelnen Module in einer Granularität, die eine Berücksichtigung des OCP in umfangreichen Objekt-Bäumen ermöglicht.

Listing 1: Kein OCP

Listing 2: Strategie: Interface und Implementierung

Listing 3: Registry für die Strategien

Listing 4: Umsetzung mit Strategien

Listing 5: Hinzufügen von neuem Verhalten

Umsetzung im Rahmen des taktischen Designs: Aggregate gemäß DDD

Abbildung 2

Listing 6: Strategien im Aggregat

Bei DDD handelt es sich um eine von Eric Evans im gleichnamigen Buch [Eva03] vorgestellte Sammlung von Konzepten für die Modellierung von unabhängigen, fachlichen Domänen auf Basis einer Fachlichkeit und Technik überbrückenden, kontextspezifischen Sprache. Wie bereits erwähnt, ist für die Einhaltung des OCP die Abstraktion mithilfe einer Fassade hilfreich. Darüber hinaus wird die Komposition der Vererbung vorgezogen. DDD bietet ein Konstrukt, das diese beiden Anforderungen erfüllt: das sogenannte Aggregat. Aggregate sind komplexe Bausteine, die jeweils einen fachlichen Belang abbilden und in sich konsistent sind. Das heißt, sie besitzen jeweils einen definierten Zustand, der unabhängig ist von anderen Aggregaten und damit eine Transaktionsgrenze darstellt. Es handelt sich bei ihnen um Kompositionen aus anderen Bausteinen (zustandsbehafteten Entitäten und zustandslosen Wertobjekten), gegebenenfalls angereichert um Verhalten. Dabei wird eine Wurzel-Entität definiert, die als Fassade nach außen hin fungiert. Aggregate dürfen nur über die jeweiligen Wurzel-Entitäten miteinander kommunizieren. „For each desired change, make the change easy (warning: this may be hard), then make the easy change.“ Kent Beck (2012 auf Twitter) Ein Beispiel für ein Aggregat ist die Repräsentation einer Bestellung. Diese besteht aus der namensgebenden Wurzel-Entität, einer gewissen Anzahl von Positionen (weitere Entitäten) und zustandslosen Wertobjekten wie dem Datum der Bestellung. In Abbildung 2 ist die innere Beschaffenheit des Bestellung-Aggregats und seine Beziehung zum Kunden-Aggregat dargestellt. Das OCP lässt sich innerhalb eines Aggregats sehr komfortabel gewährleisten, indem zum Beispiel einzelne Entitäten und Wertobjekte jeweils eigene Strategien mitliefern. So wäre zum Beispiel denkbar, dass Positionen über ein gemeinsames Interface und individuelle Berechnungsstrategien verfügen, die sich jeweils in Bezug auf steuerliche Effekte oder Rabatte unterscheiden. In der Wurzel-Entität werden diese Strategien dann sukzessive ausgeführt und die Ergebnisse summiert. Wenn neue Arten von Positionen hinzukommen, mit neuen individuellen Berechnungsstrategien, müssen weder die Bestellung noch andere Positionen modifiziert werden. Eine beispielhafte Umsetzung ist in Listing 6 zu sehen. Ferner ist in Abbildung 2 dargestellt, dass das Bestellung-Aggregat nur über die Wurzel-Entität referenziert werden kann. Einzelne Bestellpositionen sind für andere Aggregate nicht unmittelbar sichtbar. Dies wirkt zunächst vielleicht einschränkend, ist jedoch eine Voraussetzung für die Gewährleistung des OCP auf der Ebene des taktischen Designs. Wenn beispielsweise ein neues Aggregat eingeführt wird, hat dieses keinen Einfluss auf die innere Beschaffenheit der anderen Aggregate. Lediglich Wurzel-Entitäten (in der Rolle abstrakter Zugriffsschichten), die das neue Aggregat referenzieren, müssen gegebenenfalls modifiziert werden. So ist die Einhaltung des OCP pro Aggregat in sich selbst und nach außen in Korrelation mit anderen Aggregaten und dadurch innerhalb eines sogenannten Bounded Context gewährleistet. Bei Bounded Contexts (BD) handelt es sich kurz gesagt um den Gültigkeitsbereich für ein Domänenmodell. Sie setzen sich aus Elementen des taktischen Designs zusammen, wie den Aggregaten. Die nächste Frage muss also lauten: Kann das OCP auch in abstrakteren Bereichen der Softwarearchitektur wie der Abgrenzung zwischen BDs angewendet werden?

Umsetzung im Rahmen des strategischen Designs: Anticorruption-Layer

Abbildung 3

Ursprünglich ist das OCP als Vorschlag für besseres Software-Design (im Sinne der Gestaltung von individuellen Softwarekomponenten) eingeführt worden. Die Veränderbarkeit, die es dort fördert, ist jedoch auch auf höheren Abstraktionsebenen wünschenswert. Betrachtet man Robert C. Martins Erklärung des OCP „Wenn Verhalten ergänzt wird, sollten dadurch keine Änderungen an anderen Modulen des Systems nötig sein.“ und ersetzt „Modul“ durch „Bounded Context“, lässt sich das OCP auch im Rahmen des strategischen Designs anwenden. Um diese voneinander abzugrenzen, bietet DDD mehrere Muster. Für die Gewährleistung des OCP ist darunter der Anticorruption-Layer (ACL) besonders nützlich. Beim ACL handelt es sich um eine Art „Verteidigungslinie“ zwischen benachbarten Kontexten, die verhindern soll, dass sich Änderungen in einem auf andere auswirken. Implementiert wird er meist in Form von Fassaden ([GoF04], S. 185) und Adaptern ([GoF04], S. 139). Der ACL wurde zwar als Erstes im Rahmen von DDD definiert, lässt sich als Konzept aber auch in Projekten anwenden, die nicht streng gemäß DDD modelliert sind. Die Idee dahinter ist universal. Ersetzen Sie einfach den Begriff „Bounded Context“ durch „Fachkontext“ oder wie auch immer die fachlichen Einheiten Ihres Softwaresystems bezeichnet werden. In Abbildung 3 wird der Anticorruption-Layer zwischen den BDs „Inkasso“ und „Fakturierung“ dargestellt. In diesem Beispiel „verteidigt“ sich das Inkasso vor potenziellen Änderungen im Modell der Fakturierung. Der ACL ist in diesem Fall unidirektional und wird eindeutig Inkasso zugeordnet. Er kann aber auch multidirektional gestaltet werden, sodass er als eigenständige Komponente von mehreren BDs genutzt wird. In diesem Beispiel wird der Bestellung Service innerhalb des Faktura-Kontexts gemäß des in Listing 7 dargestellten Interfaces bereitgestellt. Aus Sicht des Inkasso-Kontexts ist das bereits im Ursprungszustand aus folgenden Gründen problematisch:

Listing 7: BestellungService im Faktura-Kontext

Listing 8: Faktura-Fassade

Listing 9: Euro-Übersetzer

Listing 10: Faktura-Adapter

  • Nur der Brutto-Betrag ist für die Abbuchung relevant.
  • Die Repräsentation von Geldbeträgen als Double entspricht nicht den Inkasso-Konventionen.
  • Innerhalb der eigenen Domäne soll nur mit den Aggregaten des Modells gearbeitet werden.

Zur Behebung dieser Probleme wird ein ACL angelegt. Dieser besteht aus drei Teilen:

  • Fassade (Listing 8)
  • Übersetzer (Listing 9)
  • Adapter (Listing 10)

In der Fassade wird der Bestellung Service (der aus dem Faktura-Kontext stammt) insofern konsolidiert, als dass direkt auch steuerliche Effekte geltend gemacht werden. Im Übersetzer wird der Double-Wert, durch den Geldbeträge im Faktura-Kontext repräsentiert werden, in Euro- und Cent-Werte aufgeteilt. Im Adapter werden schließlich die Fassade und der Übersetzer genutzt, um die ermittelten Werte in das Inkasso-Domänenmodell zu übertragen. Der Adapter wird dann im Inkasso- für den Zugriff auf den Fakturierungs-Kontext verwendet. Diese Zusammenhänge sind in Abbildung 4 noch einmal in einer Übersicht dargestellt. Damit hat der Inkasso- sein Domänenmodell vor dem Fakturierungs-Kontext verteidigt. Nun ist noch zu klären, inwiefern der ACL bei der Veränderung oder dem Hinzufügen von Verhalten die Einhaltung des OCP fördert. Nehmen wir dafür folgende Ereignisse im Fakturierungs-Kontext an:

Abbildung 4

  • Im nächsten Sprint des Fakturierungs-Teams wird die User-Story „Bei der Verarbeitung von Bestellungen sollen Kunden- und Produkt-spezifische Rabatte berücksichtigt werden können“ umgesetzt.
  • Im Retro zum vergangenen Sprint hat sich herausgestellt, dass die Nutzung des Double-Datentyps zur Repräsentation von Geldbeträgen problematisch ist. Stattdessen soll nun BigDecimal eingesetzt werden.

Die entsprechenden Änderungen in der BestellungService-Schnittstelle des Fakturierungs-Kontexts sind in Listing 11 zu sehen.

Der Änderungsbedarf, der dadurch im Inkasso-Kontext entsteht, wird komplett im ACL abgefangen:

  • Die FakturaFassade nutzt künftig die neue summeDerPositionenMit
    Rabatten()-Methode und liefert ein BigDecimal zurück.
  • Der EuroTranslator extrahiert den Euro- und Cent-Betrag künftig aus einem BigDecimal statt aus einem Double.

Listing 11: Geänderter BestellungService

Im Inkasso-Domänenmodell entsteht somit kein Änderungsbedarf und dem OCP wurde entsprochen, da der Faktura Adapter wie gehabt den lokalen Lastschrift-Typen als Rückgabewert liefert. Man könnte hier argumentieren, dass strenggenommen durch die Änderungen im ACL das OCP verletzt wurde. Dem ist zu entgegnen, dass hier eine strategische Perspektive eingenommen wurde, bei der die Verteidigung des Domänenmodells im Vordergrund stand. Dem OCP konnte auch auf dieser abstrakteren Designebene entsprochen werden.

Änderbarkeit als Investition in die agile Softwareentwicklung

Vom ersten Sprint an muss in der agilen Softwareentwicklung ein lauffähiges Produkt-In­krement geliefert werden. Daher können die einzelnen Module des Systems nicht sukzessive abgearbeitet werden. Häufig müssen sie in einem unfertigen Zustand ausgeliefert werden. Bis zum letzten Sprint hat ein Inkrement nicht den Anspruch, perfekt zu sein. Vielmehr ist es eine Diskussionsgrundlage, auf dessen Basis die Evolution des Produkts in die richtigen Bahnen geleitet wird. Evolution bedeutet Veränderung. Jedes einzelne Modul braucht die Fähigkeit, sich über viele Sprints hinweg verändern zu können. Dieser Artikel hat das Open/Closed-Prinzip als eine Möglichkeit vorgestellt, diese abstrakte Forderung in der Praxis über verschiedene Abstraktionsebenen des Software-Designs hinweg zu erfüllen. Wie auch die restlichen SOLID-Prinzipien ist es jedoch eine Investition. Es konsequent anzuwenden, erfordert Sorgfalt, Zeit sowie aufmerksame und geschulte Teams. Im Einzelfall ist also abzuwägen, ob sich diese Investition lohnt, denn Änderbarkeit ist nur ein Qualitätskriterium von vielen. Es ist jedoch wichtig, es zu benennen und als eigenständigen Wert herauszustellen. Erst wenn Software vor unvorhergesehenen Effekten durch das Hinzufügen oder Austauschen von Komponenten geschützt ist, sind Teams wirklich frei darin, die Evolution ihres Softwareprodukts von Sprint zu Sprint zu gestalten.

Weitere Informationen

[AGI1]
Manifesto for Agile Software Development, siehe:
http://agilemanifesto.org

[AGI2]
Principles behind the Agile Manifesto, siehe:
http://agilemanifesto.org/principles.html

[Eva03]
E. Evans, Domain-Driven Design. Tackling Complexity in the Heart of Software, Addison-Wesley, 2003

[Fow18]
M. Fowler, The State of Agile Software in 2018, siehe:
https://martinfowler.com/articles/agile-aus-2018.html

[GoF04]
E. Gamma, R. Helm, R. E. Johnson, J. Vlissides, Design Patterns - Elements of Reusable Object-Oriented Software, Addison Wesley, 2004

[Mar08]
R. C. Martin, Clean Code: A Handbook of Agile Software Craftsmanship, Prentice Hall, 2008

[Mar13]
R. C. Martin, An Open and Closed Case, siehe:
https://blog.cleancoder.com/uncle-bob/2013/03/08/AnOpenAndClosedCase.html

[Mey88]
B. Meyer, Object Oriented Software Construction, Prentice Hall, 1988

[OCP]
R. C. Martin, The Open-Closed Principle, siehe:
https://www2.cs.duke.edu/courses/fall07/cps108/papers/ocp.pdf

[SCR1]
H. Doshi, The Three Pillars of Empiricism (Scrum), Scrum.org, 4.122016, siehe:
https://www.scrum.org/resources/blog/three-pillars-empiricism-scrum

[YouT]
D. Thomas, GOTO 2015: Agile is Dead, siehe:
https://www.youtube.com/watch?v=a-BOSpxYJ9M

. . .

Author Image
Zu Inhalten
Christian Nockemann arbeitet seit 2009 als IT-Berater und Softwarearchitekt bei der viadee IT-Unternehmensberatung. Sein Fokus liegt auf Design und Entwicklung von Spring-basierten Enterprise-Anwendungen.

Artikel teilen