SlideShare ist ein Scribd-Unternehmen logo
1 von 5
Downloaden Sie, um offline zu lesen
Fachthema 

Gut aufgeräumt                                                           Build-Tool verwenden sie Maven. Der Build eines Release-
                                                                         Kandidaten besteht aus zwei separaten Schritten:

Dependency-                                                              H	Bau des Artefakts auftrag.jar und
                                                                         H	Bau des Webarchivs (WAR-Datei).


Management von
                                                                         Nach einigen Tagen Arbeit läuft der Walking Skeleton und der
                                                                         manuelle Systemtest der OHO-Anwendung ist nach dem De-
                                                                         ployment auf den Tomcat erfolgreich. Nach dieser ersten Itera-
technischen Standard-                                                    tion der OHO-Entwicklung besteht die Anwendung aus zwei
                                                                         Komponenten, der fachlichen Auftrag und der technischen

komponenten                                                              Builder.


Reik Oberrath                                                            Die Komponente „Parent“

In jedem Projekt, in dem komponentenorientiert entwickelt wird, tritt    Bevor die G&G-Entwickler die Auftragsverwaltung weiterim-
immer wieder die gleiche Frage auf: Wohin mit all den allgemeinen        plementieren, wollen sie erst die übrigen Komponenten aufset-
Klassen wie Utilities, Exceptions, Interfaces und anderen Klassen, die   zen. Als Nächstes soll die Horoskopverwaltung erzeugt wer-
mehrfach gebraucht werden. Dieser Artikel empfiehlt, einige techni-      den. Allerdings fehlt noch ein Hauptmenü, in dem die Auf-
sche Standardkomponenten zu bilden, die in ein spezielles Dependen-      trags- und Horoskopverwaltung eingehängt werden kön-
cy-Management eingebunden sind. Außerdem erklärt er, welche Klas-        nen. Aus diesem Grund realisieren die G&G-Entwickler in der
sen in welche Komponenten gehören. Diese Vorgehensweise ergänzt          zweiten Iteration zunächst die fachliche Komponente Main. In
sehr gut das fachlich offene Dependency-Management [Ober12],             dieser Komponente werden die übrigen fachlichen Kompo-
welches auf die nicht-technischen Komponenten fokussiert ist, und        nenten eingebettet. Als minimale Implementierung beinhal-
spiegelt moderne Muster modularer Architektur wider [PMA]. Zur Er-       tet Main ein Hauptmenü mit dem einzigen Eintrag „Aufträge“
läuterung greift der Artikel die Java-Anwendung OHO aus [Ober12]         für die Auftragsverwaltung. Anschließend wird die Horoskop-
wieder auf. Dabei wird der Einsatz des Projekt-Management-Tools          verwaltung mit Minimalimplementierung aufgesetzt und mit
Maven erläutert.                                                         dem Menüpunkt „Horoskope“ in das Hauptmenü integriert.
                                                                           Beim Schreiben der ersten Unit-Tests für Main und Horoskop
                                                                         stellen die G&G-Entwickler fest, dass diesen neuen Kompo-
Fallstudie: Online Horoskope                                             nenten die Abhängigkeit zur JUnit-Bibliothek fehlt. Der Kom-
                                                                         ponente Auftrag wurde diese Abhängigkeit manuell zugefügt.
     Die kleine Software-Schmiede „Gut & Günstig“ (G&G)                  Gingen die Entwickler für Main und Horoskop genauso vor,
E    erhält von der Astrologin „Starlet“ den Auftrag, eine Ho-           würden sie das DRY-Prinzip [DRY] verletzen. Aus diesem
roskop-Webanwendung zu entwickeln. Die Anwendung soll
es ihren Kunden ermöglichen, ein Horoskop online sowohl
zu beauftragen als auch das Horoskop nach erfolgter Zahlung                 MU-Klassen
abzurufen. Diese Anwendung wird Online Horoskop, kurz
OHO, genannt. Die G&G-Entwickler diskutieren zurzeit das                    MU steht für Multiple Usage. MU-Klassen werden al-
Buch „Growing Object-Oriented Software, Guided by Tests“                    so für mehrfache Benutzung entworfen. MU-Charak-
[GOOS]. Auch wenn die G&G-Entwickler (noch?) nicht wirk-                    ter haben zwar die meisten Klassen, aber bei folgen-
lich Test-getrieben entwickeln, sind ihnen die Aspekte der Test-            den Klassentypen (s. auch Tabelle 1) ist dieser beson-
und Wartbarkeit sehr wichtig.                                               ders ausgeprägt:
   Zunächst möchten die G&G-Entwickler einen sogenannten
„Walking Skeleton“ implementieren, das heißt, das kleins-                   Utility-Klassen im weitesten Sinn
te mögliche Stückchen echter Funktionalität, das als Version                Diese Klassen stellen Funktionalität an zentralen Stel-
0.0.1 gebaut, installiert und als Komplettsystem getestet wer-              len bereit, die werkzeugartig für verschiedene Zwecke
den kann. Dazu wählen sie die Auftragsverwaltung aus. Auf                   von unterschiedlichen Codeblöcken aus genutzt wer-
einer Datenmaske wird ein neuer Auftrag nur mit dem Feld                    den. Dazu zählen:
„Auftraggeber“ erfasst. Beim Speichern wird automatisch eine                H	Utilities im engeren Sinn: nicht instanziierte Klassen
Auftrags-ID generiert und in einer Auftragsliste angezeigt. Für               mit statischen Methoden
diese minimale Funktionalität setzen die G&G-Entwickler eine                H	Helferklassen, die instanziiert genutzt werden
Datenbank mit einer Auftragstabelle auf, welche zwei Daten-                 H	Stammklassen (häufig abstrakt), die durch Vererbung
felder beinhaltet: Auftraggebername und ID. Sie implementie-                  Funktionalität zur Verfügung stellen
ren die Datenmaske, einen Auftragsservice und ein Auftrags-
DAO-Objekt. Zu jeder wichtigen Klasse wird eine Testklasse                  Informationstransferklassen
mit JUnit-Tests implementiert.                                              Klassen für den Informationsaustausch zwischen unter-
                                                                            schiedlichen Teilen der Software (z. B. zwischen Kom-
                                                                            ponenten). Dazu zählen:
Die Komponente „Builder“                                                    H	Datenklassen, deren Inhalte nicht wie Domain-Objek-
                                                                              te persistiert werden und die typischerweise als Ty-
Den Produktionscode der Anwendung packen die G&G-Ent-                         pen in Signaturen von Interface-Methoden verwen-
wickler in ein Artefakt „auftrag.jar“, das wiederum für ein                   det werden
Deployment auf einem Tomcat in ein Web Application Ar-                      H	Exception-Klassen, um Ausnahmebedingungen an-
chive (WAR) gepackt wird. Für den Bau des WARs erzeugen                       zuzeigen
die G&G-Entwickler die technische Komponente Builder. Als

 34                                                                                                             JavaSPEKTRUM 2/2013
          Fachthema

Grund führen sie die neue technische Komponente Parent                                          AbstractOhoUnitTest.java. Beide Komponenten bekommen Parent
ein. Das Parent-Maven-Projekt wird mit dem packaging-Typ                                        als Maven-Parent, damit sie die dort konfigurierten Abhängig-
„pom“ erzeugt. In den pom-Dateien der drei fachlichen Kom-                                      keiten erben. Für den automatischen Bau werden die neuen
ponenten Auftrag, Horoskop und Main wird Parent als „parent“                                    Komponenten in der Parent-pom-Datei als Module konfigu-
konfiguriert. Anschließend wird die Definition der JUnit-Ab-                                    riert. Zuletzt werden sie in der Parent-pom-Datei als neue Ab-
hängigkeit von der pom-Datei der Auftragskomponente in die                                      hängigkeit hinzugefügt, damit alle fachlichen Komponenten
Parent-pom-Datei verschoben (und der „scope“ von „test“ auf                                     darauf zugreifen können.
„provided“ gesetzt). Jetzt erben die drei fachlichen Komponen-                                     Diese Vorgehensweise verursacht aber ein Problem. Maven
ten diese Abhängigkeit und können die JUnit-Sourcen benut-                                      kann die Anwendung jetzt nicht mehr bauen. Die Kompo-
zen, ohne das DRY-Prinzip zu verletzen.                                                         nenten Common und Test waren von der Parent-Komponente
   Mit der Komponente Parent existiert jetzt eine zentrale Stel-                                abhängig (wegen der Parent-Konfiguration), und die Parent-
le zur Definition aller allgemeinen Abhängigkeiten. Das nut-                                    Komponente ist jetzt wegen der Maven-Dependencies von die-
zen die G&G-Entwickler, um für OHO die Logging-Funktio-                                         sen beiden Komponenten abhängig (s. Abb. 2). Der Maven-Re-
nalität einzurichten. Sie definieren in der Parent-pom-Datei                                    aktor weiß also nicht, welche Komponente (welches Projekt) er
eine Abhängigkeit zur log4j-Bibliothek und können damit in                                      zuerst bauen soll, und liefert deshalb die Fehlermeldung „The
allen Komponenten die log4j-Logger benutzen. Außerdem de-                                       projects in the reactor contain a cyclic reference“.
finieren sie in der Parent-pom-Datei die Komponenten Main,                                         Die G&G-Entwickler fin-
Auftrag, Horoskop und Builder als Module. Damit sind sie in der                                 den folgende Lösung: Sie
Lage, den Build eines Release-Kandidaten in nur einem Schritt                                   führen eine zweite Maven-
(„mvn install“ auf dem Parent-Projekt) durchzuführen. Nach                                      Parent-Komponente               ein,                           Builder
dieser zweiten Iteration besteht die OHO-Anwendung aus fünf                                     welche nur für die fachlichen
Komponenten (s. Abb. 1).                                                                        Komponenten zuständig ist.
                                                                                                Diese Komponente nennen
                                                                                                                                                              Fachliche
                                                                                                sie Parent.BLoC (Business                                  Komponenten
                                                                                                Logic Components). Alle drei
      A                 Builder                           B           Builder                   fachlichen        Komponenten
                                                                                                Auftrag, Horoskop und Main
                                                                                                                                                            Parent.BLoC
                                                                                                bekommen Parent.BLoC als
                                                                                                Maven-Parent. Parent.BLoC
                        Main                                      Fachliche
                                                                Komponenten                     werden die technischen Kom-                        Common                   Test
                                                                                                ponenten Common und Test
      Auftrag                        Horoskop                                                   als Abhängigkeiten zugefügt.
                                                                                                                                                               Parent
                                                                                                Damit erben die fachlichen
                        Parent                                        Parent                    Komponenten alle Abhängig-
                                                                                                keiten von dieser zentralen                              JUnit             log4j
                JUnit             log4j                       JUnit             log4j           Stelle und verletzen so nicht
                                                                                                                         Abb. 2: Dependency-Management mit den neuen technischen Komponenten Common un
                                                                                                das DRY-Prinzip. Parent.BLoC
                                                                                                                         Blau: Unterschiede Abb. 2: Dependency-Management mit
                                                                                                                                             zu Abb. 1b. Aufgrund der nicht möglichen, rot dargestellten Abhängigk
Abb. 1:1: Dependency-Management der ersten 5 ersten fünf OHO-Komponenten, techni-grau
   Abb. Dependency-Management der OHO-Komponenten. Technische Komponenten sind                  bekommt wiederumwurde die Komponente Parent.BLoC erzeugt. Komponenten
                                                                                                                            Parent          den neuen technischen
   dargestellt. Aus Gründen der Übersichtlichkeit sind in B und den folgenden Abbildungen die
sche Komponenten sind grau dargestellt. Aus Gründen der Übersichtlichkeit sind                                                              Common und Test. Blau: Unterschie-
   Abhängigkeiten zwischen den fachlichen Komponenten (weiß) ausgeblendet. Oben dargestellte    als Maven-Parent. Damit er-
in B und den folgenden Abbildungen die Abhängigkeiten zwischen den fachlichen                                                               de zu Abb. 1b. Wegen der nicht mög-
   Komponenten immer hängen von weiter unten stehenden ab (siehe „Dependency-Hierarchie“ in
Komponenten (weiß) ausgeblendet. Oben dargestellte Komponenten hängen im-
                                                                                                ben die fachlichen Kompo-                   lichen, rot dargestellten Abhängigkei-
   [FODM] und „Levelize Modules“ in [PMA]).
mer von weiter unten stehenden ab (s. „Dependency-Hierarchie“ in [Ober12] und                   nenten auch die Abhängig-                   ten wurde die Komponente Parent.
„Levelize Modules“ in [PMA])                                                                    keiten zu den allgemeinen                   BLoC erzeugt
                                                                                                Third-Party-Bibliotheken
                                                                                                JUnit und log4j (s. Abb. 2).

Die Komponenten „Common“, „Test“ und
„Parent.BLoC“                                                                                   Die Beziehung zwischen „Common“ und „Test“

Die G&G-Entwickler betrachten den bisher erreichten Stand                                       In der vierten Iteration implementieren die G&G-Entwickler
und stellen fest, dass sowohl im Produktions- als auch im Test-                                 nun die fachlichen Komponenten Rechnung und Stammdaten
code das DRY-Prinzip verletzt wurde: Jede fachliche Kompo-                                      mit minimaler Funktionalität. Sie stellen fest, dass die neuen
nente enthält eine Reihe von Codeblöcken, die ursprünglich                                      fachlichen Komponenten sehr einfach aufgesetzt werden kön-
für die Komponente Auftrag geschrieben und dann fast genau-                                     nen. Lediglich durch Definition der Komponente Parent.BLoC
so in die Komponente Horoskop übernommen wurden. Grund                                          als Parent stehen alle benötigten Abhängigkeiten zur Verfü-
dafür ist die „parallele Funktionalität“ beim Zugriff auf die Da-                               gung. Außerdem kann durch die Verwendung der bereits im-
tenbank durch ein DAO-Objekt, bei der Darstellung der Daten                                     plementierten Funktionalität in den technischen Komponenten
in der GUI oder beim Validieren von Testergebnissen im Test-                                    Common und Test sowohl der Produktions- als auch der Test-
code. Deshalb wollen die G&G-Entwickler mit einem Refacto-                                      code der neuen Komponenten schnell und sauber (ohne Verlet-
ring die strukturelle Qualität und damit die Wartbarkeit der                                    zung des DRY-Prinzips) implementiert werden. Die G&G-Ent-
gesamten Anwendung verbessern, bevor sie die nächste fachli-                                    wickler sind deshalb mit ihrem Refactoring aus der dritten Ite-
che Komponente Rechnung aufsetzen.                                                              ration sehr zufrieden.
  In der dritten Iteration erzeugen die G&G-Entwickler zwei                                       Allerdings diskutieren sie die Frage, ob die Komponente
neue technische Komponenten. Die Komponente Common be-                                          Common von Test abhängig sein sollte oder umgekehrt (beides
inhaltet MU-Klassen (s. Kasten „MU-Klassen“) wie AbstractDao.                                   gleichzeitig ist wegen einer dann zyklischen Referenz nicht
java und GuiValidationHelper.java, die Komponente Test die Klasse                               möglich):

www.javaspektrum.de                                                                                                                                                                      35
Fachthema 

 H	Common    abhängig von Test: Die allgemeine OHO-Test-Funk-                            java, IHoroskopDao.java, IAuftragService.java, IHoroskopService.java).
   tionalität steht im Testcode von Common zur Verfügung. Die-                           Die G&G-Entwickler bauen API in die Version OHO 2.0 ein. Da-
   se Wahl würde den Testcode von Common optimieren.                                     bei stellen sie einen großen Vorteil fest: Die als Code-Duplikate
 H	Test abhängig von Common: Die Common-Funktionalität steht                             markierten Code-Blöcke (siehe oben Kapitel „Das Problem der
   im Code von Test zur Verfügung. Diese Wahl würde den                                  Wiederverwendbarkeit“), welche fachliche Typen beinhalten
   Code von Test und damit den Testcode aller fachlichen Kom-                            und deshalb vorher nicht in Common oder Test ausgelagert wer-
   ponenten optimieren.                                                                  den konnten, können jetzt aus den fachlichen Komponenten
 Die G&G-Entwickler entscheiden sich für die zweite Alternati-                           herausgezogen werden, wenn an diesen Stellen die Interface-
 ve, weil sich fachliche Komponenten wegen Kundenwünschen                                Typen verwendet werden. Dieses gilt für den Produktions- und
 häufiger ändern als technische (siehe unten). Um beim Aufset-                           den Testcode. Aus diesem Grund bekommen die Komponen-
 zen neuer und beim Ändern existierender fachlicher Kompo-                               ten Common und Test eine Abhängigkeit zu API. Jetzt werden
 nenten möglichst flexibel zu sein, soll der Testcode der fachli-                        alle Code-Duplikate entfernt und der gemeinschaftlich genutz-
 chen Komponenten optimiert werden.                                                      te Code wird sauber an einer einzigen, zentralen Stelle imple-
                                                                                         mentiert. Abbildung 3 zeigt das neue Beziehungsgefüge.

 Das Problem der Wiederverwendbarkeit
                                                                                         Die Komponente „Global“
 In den weiteren Iterationen implementieren die G&G-Entwick-
 ler die Details der fachlichen Funktionalität in allen fünf fach-                       Beim Einbau von API stoßen die G&G-Entwickler auf ein wei-
 lichen Komponenten. Dabei gehen sie nach folgender Regel                                teres Problem, das ebenfalls die Wiederverwendbarkeit betrifft.
 vor: Wird ein Block von Programmzeilen an mehreren Stellen                              Die bisherige Sammlung von MU-Klassen in der Common-
 benötigt, wird er in einer MU-Klasse zur Verfügung gestellt –                           Komponente wurde zum Teil für OHO neu entwickelt. Ein an-
 für den Produktionscode in der Komponente Common, für den                               derer Teil stammt aber aus anderen Anwendungen, in denen
 Testcode in der Komponente Test.                                                        diese Funktionalität ursprünglich entwickelt wurde. Diesen
    Dabei müssen die G&G-Entwickler leider feststellen, dass                             Code wiederzuverwenden, war nicht immer leicht, denn der
 viele Codeblöcke nicht zentral zur Verfügung gestellt werden                            ursprüngliche Code hatte einige Abhängigkeiten zu Klassen,
 können, weil diese Codezeilen fachspezifische Java-Typen (z.                            die spezifisch für diese anderen Anwendungen waren. Das
 B. Auftrag.java) beinhalten, die in den fachlichen Komponenten                          machte manchmal ein Refactoring nötig, damit der wieder-
 definiert sind und deshalb in den technischen Komponenten                               verwertbare Code-Block herausgelöst und problemlos in den
 Common und Test nicht referenziert werden können. Die Ent-                              OHO-Code integriert werden konnte.
 wickler diskutieren dieses Problem, haben aber noch keine sau-                            Mit der Einführung der API-Komponente bekommen die
 bere Lösung dafür. Daher markieren sie diese Codestellen mit                            G&G-Entwickler das gleiche Problem in der OHO-Anwen-
 Kommentaren, die das Problem schildern, und tolerieren bis                              dung: Wenn später Common-Funktionalität für andere Anwen-
 auf Weiteres diesen Schmutz im Code.                                                    dungen wiederverwendet werden soll, darf sie keine Abhän-
                                                                                         gigkeiten zu den fachspezifischen Interface-Typen der API-
                                                                                         Komponente haben.
 Die Komponente „API“                                                                      Um die Effizienz ihrer Softwareentwicklung zu steigern,
                                                                                         beschließen die G&G-Entwickler eine technische Kompo-
  Schließlich ist alle benötigte Fachlichkeit implementiert und                          nente mit Namen Global zu erzeugen (s. Abb. 4). Diese Kom-
  die OHO-Version 1.0.0 wird produktiv. Durch den produktiven                            ponente soll diejenigen MU-Klassen beinhalten, die fachun-
                                                          Einsatz ergeben sich Kun-      spezifisch sind und in
                                                          denwünsche, die Ände-          verschiedenen Anwen-
                                                          rungen und damit weitere       dungen wiederverwen-
                       Builder                            OHO-Versionen nach sich        det werden können. Um                         Builder
                                                          ziehen (s. [Ober12]). Da-      das deutlich zu machen,
                                                          bei stellen die G&G-Ent-       enthält der Namespace
                      Fachliche                           wickler zahlreiche Pro-        der globalen Klassen                         Fachliche
                  Komponenten                             bleme fest, die das De-        keine Anwendungsbe-                       Komponenten
                                                          pendency-Management            zeichnung und lautet
                                                          zwischen den fachlichen        nur „de.gg.global“. Da-
                    Parent.BLoC                                                                                                     Parent.BLoC
                                                          Komponenten betreffen.         gegen heißt der Name-
                                                            Diese Probleme und           space in der Komponen-
                                      Test                deren Lösung wurden            te Common „de.gg.oho.                                        Test
        Common                                                                                                             Common
                                                          in [Ober12] ausführlich        common“. Das zeigt
                                                          erläutert. Die Lösung be-      an, dass sich hier Klas-
                                                          steht in der Einführung        sen befinden, die für
                 API                                                                                                              API                 global
                                                          einer neuen technischen        die OHO-Anwendung
                              Parent
                                                          Komponente API (Appli-         spezifisch, aber für alle
                                                                                                                                             Parent
                                                          cation Interface). Diese       ihre fachlichen Kompo-
                                                          beinhaltet sämtliche In-       nenten allgemein sind.
                       JUnit         log4j                                                                                             JUnit         log4j
                                                          terface-Typen für alle kon-    Tabelle 1 nennt einige
                                                          zeptionellen Schnittstellen
Abb. 3: Dependency-Management mit der neuen technischen Komponenten API.
  Abb. 3: Dependency-Management mit                                                      Beispiele für globale 4: Abb. 4: Dependency-Management mit der Komponenten Glob
                                                                                                                 Abb. Dependency-Management mit der neuen technischen
Blau: Unterschiede zu Abb. 2.                                                                                    Blau:
  der neuen technischen Komponenten API.                  zwischen den Komponen-         Klassen und solche, die Unterschiede zu Abb. 3. Komponente Global.
                                                                                                                       neuen technischen
  Blau: Unterschiede zu Abb. 2                            ten (z. B. IAuftrag.java,,     nur für OHO-Code all- Blau: Unterschiede zu Abb. 3
                                                          IHoroskop.java, IAuftragDao.   gemein sind.

   36                                                                                                                                JavaSPEKTRUM 2/2013
   Fachthema

  Klassentyp                              Common                 Global                         Test

  statische Utilities                     AuftragsUtil.java      GGValidationUtils.java         GlobalTestUtils.java,OHOTestUtils.java

  nicht statische Helferklasse            AuftragSorter.java     GGTextFieldValidator.java

  Stammklasse                             OHOTextfield.java      GGTextField.java               OhoUnitTest.java

  nicht persistierte Datenklasse          RawAuftrag.java        GGValidationResult.java

  Exception-Klasse                        OhoDaoException.java   GGValidationException.java

Tabelle 1: Beispiele für MU-Klassen



Globaler Testcode                                                        Die Entwickler einigen sich darauf, diese MU-Klassen nur
                                                                       mit einfachen Getter- und Setter-Methoden auszustatten, und
Die G&G-Entwickler überlegen, die Komponente Test aufzu-               erlauben sich ganz pragmatisch, für diese einfachen Methoden
teilen in Test.Global und Test.Common. Für die Wiederverwen-           auf Unit-Tests zu verzichten. Schließlich einigen sie sich auf die
dung von Testcode wäre das sinnvoll. Doch sind sie „vor-               im Kasten „Entscheidungsbaum für die Komponentenfindung
sichtig vor dieser Optimierung“ [VvO] und beherzigen das               neuer MU-Klassen“ dargestellte Vorgehensweise.
Clean-Code-Prinzip „Keep It Simple, Stupid“ [KISS]. Sie ent-
scheiden sich stattdessen, in der Komponente Test die Klas-
se GlobalTestUtils.java zu erzeugen und dort den wiederver-            Das Problem der „API“-Komponente
wendbaren Testcode zu pflegen. Für den aktuellen Umfang
des Testcodes reicht das derzeit vollständig aus. Die Entschei-        Im Laufe der weiteren Entwicklung der OHO-Anwendung
dung, für globalen Testcode eine eigene Komponente anzu-               stellen die G&G-Entwickler fest, dass ihr Vorsatz, in den MU-
legen, wird solange verschoben, bis die jetzige Entscheidung           Klassen der API-Komponente nur Getter- und Setter-Metho-
Probleme macht.                                                        den zu implementieren, im Projektalltag verloren ging. Einige
                                                                       nicht persistierte Datenklassen (s. Kasten „MU-Klassen“) bein-
                                                                       halten mittlerweile mehr oder weniger komplexe Code-Blöcke,
Wohin mit welcher Klasse?                                              die jetzt ungetestet sind und deshalb ein stark erhöhtes Poten-
                                                                       zial haben, einen (schwerwiegenden) Fehler in der Produktion
Für die weitere Entwicklung erstellen die G&G-Entwickler ein           zu verursachen.
Schema, nach dem sie entscheiden, in welche Komponente eine              Durch ein Refactoring wird dieses Problem aus der Welt ge-
neue MU-Klasse gehört. Dabei wird ihnen bewusst, dass API              räumt: Für alle nicht persistierten Datenklassen wird grund-
nicht nur Interface-Code beinhaltet, sondern auch Implemen-            sätzlich ein Interface in der API-Komponente angelegt, das
tierung und zwar in Form von MU-Klassen in Methoden-Sig-               in Methoden-Signaturen anderer Interfaces genutzt wird. Die
naturen (Exceptions und nicht persistierte Datenklassen). Die-         Implementierung dieser Datenklassen und der dazugehören-
ser Teil des Produktionscodes ist ungetestet, denn für die Kom-        de Testcode kommen in die Komponente Common. Außerdem
ponente API sind keine Unit-Tests vorgesehen. Dieser Code              wählen die G&G-Entwickler einen Code-Watch, der dafür ver-
kann aus API nicht herausgelöst werden, weil er von den In-            antwortlich ist, den Code zu überprüfen und dafür zu sorgen,
terfaces genutzt wird und deshalb direkt zur Schnittstelle (API)       dass dies nicht wieder vorkommt.
der Anwendung gehört.                                                    Während dieser Entscheidung trifft von ihrer Auftraggebe-
                                                                       rin „Starlet“ eine Anfrage ein: Die Anwender würden sich im-
                                                                       mer häufiger über fehlende oder falsche Validierungsfehler be-
                                                                       schweren, welche die Dateneingabe erschweren. Deshalb soll
    Entscheidungsbaum für die Komponenten-                             ermittelt werden, wie die Validierung optimiert werden kann
    findung neuer MU-Klassen                                           und wie viel Aufwand das bedeuten würde. Die G&G-Ent-
                                                                       wickler können die Beschwerden nachvollziehen, denn auch
    A:	 die Klasse spezifisch für eine spezielle fachliche
        Ist                                                            aus Entwicklersicht sind sie mit dem Validierungs-Framework
        Komponente?                                                    von OHO nicht zufrieden.
        Ja: Klasse gehört in diese Komponente.                           Als Verbesserung diskutieren sie folgende Idee: An die In-
        Nein: ➞ B                                                      terface-Getter-Methoden der Domain-Objekte (IAuftrag.java,
                                                                       IHoroskop.java ...) werden Validierungsregeln annotiert. Zu je-
    B:	Handelt es sich bei dieser Klasse um Testcode?                 der Regel gibt es eine Klasse, die diese Regel implementiert.
        Ja: Klasse gehört in die Komponente Test.                      Ein zentraler OHO-Validator analysiert die Instanzen der
        Nein: ➞ C                                                      Domain-Objekte, durchsucht ihre Annotationen nach Validie-
                                                                       rungsregeln, ruft diese für die vorliegenden Instanzen auf,
    C:	Wird die Klasse in einem API-Interface benutzt?                sammelt die Fehlermeldungen und liefert die Fehlerliste als
        Ja: Klasse gehört in die Komponente API.                       Resultat. Auf diese Weise könnte sowohl in der GUI als auch
        Nein: ➞ D                                                      im Backend die Validierung durchgeführt werden. Diese Vor-
                                                                       gehensweise würde es nötig machen, die Validierungsregeln
    D:	Enthält die Klasse OHO-spezifische Java-Typen?                 in API zu implementieren. Dadurch könnte die API-Kompo-
        Ja: Klasse gehört in die Komponente Common.                    nente, die ursprünglich testfrei konzipiert wurde, auf Testcode
        Nein: Klasse gehört in die Komponente Global.                  nicht mehr verzichten. Damit wäre aber auch der Code-Watch
                                                                       überflüssig.

www.javaspektrum.de                                                                                                                      37
Fachthema 

                                                                   die API-Komponente dazu, Implementierungscode anzurei-
                                                                   chern und zu einer monolithischen Struktur zu werden. Wer
  JavaSPEKTRUM ist eine Fachpublikation des Verlags:               das zu verhindern weiß, oder es wenigstens einschränkt, dem
                                                                   bieten die technischen Komponenten Global, Common, Test, API,
                   SIGS DATACOM GmbH                               Parent und Parent.BLoC in dem Abhängigkeitsgefüge von Ab-
                       Lindlaustraße 2c                            bildung 4 einen stabilen technischen Rahmen, um flexibel auf
                        53842 Troisdorf                            Änderungen zu reagieren und die Wiederverwendbarkeit von
                     Tel.: 0 22 41/23 41-100                       Code zu verbessern.
                     Fax: 0 22 41/23 41-199
                 E-Mail: info@sigs-datacom.de
                    www.javaspektrum.de                            Literatur und Links

                                                                   [DRY] http://www.clean-code-developer.de/Don-t-Repeat-Yourself-DRY.
                                                                   ashx?HL=dry
                                                                   [GOOS] St. Freeman, N. Pryce, Growing Object-Oriented Soft-
                                                                   ware, Guided by Tests, Pearson Education, Inc, 2010
                                                                   [KE] http://de.wikipedia.org/wiki/Komponentenbasierte_Entwicklung
                                                                   [KISS] http://www.clean-code-developer.de/Keep-it-simple-stupid-KISS.
                                                                   ashx?From=KISS
                                                                   [Ober12] R. Oberrath, Das fachlich offene Dependency-
                                                                   Management, in: JavaSPEKTRUM, 6/2012
  Nach zähen Verhandlungen und Zugeständnissen aller               [PMA] http://refcardz.dzone.com/refcardz/patterns-modular-architecture
Stakeholder können die GG-Entwickler die neue Validierung         [VvO] http://www.clean-code-developer.de/Vorsicht-vor-Optimierungen.
umsetzen. Damit ist unvermeidbar, dass die API-Komponente          ashx?HL=vorsicht
zu einer Mischung aus Interface-, Implementierungs- und Test-
code wird. Interfaces und Implementierung gehören technisch
so eng zusammen, dass die fachliche Implementierung nicht
davon getrennt werden kann.

                                                                                      Dr. Reik Oberrath ist als IT-Berater bei der iks
Fazit                                                                                 Gesellschaft für Informations- und Kommunikations-
                                                                                      systeme mbH tätig. Er beschäftigt sich seit vielen Jah-
Der Kasten „Entscheidungsbaum für die Komponentenfin-                                 ren mit der Entwicklung von individuellen Geschäfts-
                                                                                      anwendungen, speziell unter Swing und RCP. Einen
dung neuer MU-Klassen“ erklärt, welche Klasse in welche
                                                                                      besonderen Fokus legt er auf Automatisierung in der
technische Komponente gehört. Abbildung 4 zeigt die Abhän-
                                                                                      Qualitätssicherung und im Release Build sowie auf
gigkeiten zwischen diesen Komponenten. Software, die nach                             Clean Code.
dieser Vorgehensweise entworfen wurde, besitzt ein robustes                           E-Mail: R.Oberrath@iks-gmbh.com
und gleichzeitig flexibles Dependency-Management. Es ist ro-
bust, weil es für jedes Stück Implementierung einen Platz vor-
sieht, und flexibel, weil dieser Platz bei Bedarf wechseln kann,
ohne eine Dependency-Hölle zu verursachen. Allerdings neigt




 38                                                                                                                 JavaSPEKTRUM 2/2013

Weitere ähnliche Inhalte

Andere mochten auch

Service goes green
Service goes greenService goes green
Service goes green
Dirk Zimmermann
 

Andere mochten auch (11)

Test-Automation mit Selenium WebDriver - ein Artikel der iks im dotnetpro
Test-Automation mit Selenium WebDriver - ein Artikel der iks im dotnetproTest-Automation mit Selenium WebDriver - ein Artikel der iks im dotnetpro
Test-Automation mit Selenium WebDriver - ein Artikel der iks im dotnetpro
 
App-Projekte richtig steuern
App-Projekte richtig steuernApp-Projekte richtig steuern
App-Projekte richtig steuern
 
Apps als motor zur digitalen transformation
Apps als motor zur digitalen transformationApps als motor zur digitalen transformation
Apps als motor zur digitalen transformation
 
Mehr Softwarequalität: Team-Cleancoding
Mehr Softwarequalität: Team-CleancodingMehr Softwarequalität: Team-Cleancoding
Mehr Softwarequalität: Team-Cleancoding
 
Micro, Nano, Mono - Microservices verständlich erklärt.
Micro, Nano, Mono  - Microservices verständlich erklärt.Micro, Nano, Mono  - Microservices verständlich erklärt.
Micro, Nano, Mono - Microservices verständlich erklärt.
 
Softwarequalität: Definitionen, Grenzen, Wünsche - Vortrag IKS-Meeting im Jan...
Softwarequalität: Definitionen, Grenzen, Wünsche - Vortrag IKS-Meeting im Jan...Softwarequalität: Definitionen, Grenzen, Wünsche - Vortrag IKS-Meeting im Jan...
Softwarequalität: Definitionen, Grenzen, Wünsche - Vortrag IKS-Meeting im Jan...
 
Mehr Softwarequalität: Technische Schulden
Mehr Softwarequalität: Technische SchuldenMehr Softwarequalität: Technische Schulden
Mehr Softwarequalität: Technische Schulden
 
Mehr Softwarequalität: Qualität als Treiber
Mehr Softwarequalität: Qualität als TreiberMehr Softwarequalität: Qualität als Treiber
Mehr Softwarequalität: Qualität als Treiber
 
Agiles Arbeiten - Mythen, Trends und Best Practices
Agiles Arbeiten  - Mythen, Trends und Best PracticesAgiles Arbeiten  - Mythen, Trends und Best Practices
Agiles Arbeiten - Mythen, Trends und Best Practices
 
Ist Ihr Unternehmen reif für Microservices?
Ist Ihr Unternehmen reif für Microservices?Ist Ihr Unternehmen reif für Microservices?
Ist Ihr Unternehmen reif für Microservices?
 
Service goes green
Service goes greenService goes green
Service goes green
 

Mehr von IKS Gesellschaft für Informations- und Kommunikationssysteme mbH

Mehr von IKS Gesellschaft für Informations- und Kommunikationssysteme mbH (20)

Es wird Zeit KI zu nutzen - Wie es mit Azure KI Services und .NET MAUI gelingt
Es wird Zeit KI zu nutzen - Wie es mit Azure KI Services und .NET MAUI gelingtEs wird Zeit KI zu nutzen - Wie es mit Azure KI Services und .NET MAUI gelingt
Es wird Zeit KI zu nutzen - Wie es mit Azure KI Services und .NET MAUI gelingt
 
Thementag 2023 06 Dieses Mal machen wir alles richtig - 9 Hacks für wandelbar...
Thementag 2023 06 Dieses Mal machen wir alles richtig - 9 Hacks für wandelbar...Thementag 2023 06 Dieses Mal machen wir alles richtig - 9 Hacks für wandelbar...
Thementag 2023 06 Dieses Mal machen wir alles richtig - 9 Hacks für wandelbar...
 
Thementag 2023 04 Lindern, heilen oder gar fit machen.pdf
Thementag 2023 04 Lindern, heilen oder gar fit machen.pdfThementag 2023 04 Lindern, heilen oder gar fit machen.pdf
Thementag 2023 04 Lindern, heilen oder gar fit machen.pdf
 
Thementag 2023 05 Wer zu spät kommt, den bestraft das Leben - Modernisierung ...
Thementag 2023 05 Wer zu spät kommt, den bestraft das Leben - Modernisierung ...Thementag 2023 05 Wer zu spät kommt, den bestraft das Leben - Modernisierung ...
Thementag 2023 05 Wer zu spät kommt, den bestraft das Leben - Modernisierung ...
 
Thementag 2023 01 Mut zur Modernisierung - ein Praxisbeispiel.pdf
Thementag 2023 01 Mut zur Modernisierung - ein Praxisbeispiel.pdfThementag 2023 01 Mut zur Modernisierung - ein Praxisbeispiel.pdf
Thementag 2023 01 Mut zur Modernisierung - ein Praxisbeispiel.pdf
 
Thementag 2023 03 Einführung in die Softwaremodernisierung.pdf
Thementag 2023 03 Einführung in die Softwaremodernisierung.pdfThementag 2023 03 Einführung in die Softwaremodernisierung.pdf
Thementag 2023 03 Einführung in die Softwaremodernisierung.pdf
 
Thementag 2022 01 Verpassen Sie nicht den Anschluss.pdf
Thementag 2022 01 Verpassen Sie nicht den Anschluss.pdfThementag 2022 01 Verpassen Sie nicht den Anschluss.pdf
Thementag 2022 01 Verpassen Sie nicht den Anschluss.pdf
 
Thementag 2022 04 ML auf die Schiene gebracht.pdf
Thementag 2022 04 ML auf die Schiene gebracht.pdfThementag 2022 04 ML auf die Schiene gebracht.pdf
Thementag 2022 04 ML auf die Schiene gebracht.pdf
 
Thementag 2022 03 Ein Modell ist trainiert - und jetzt.pdf
Thementag 2022 03 Ein Modell ist trainiert - und jetzt.pdfThementag 2022 03 Ein Modell ist trainiert - und jetzt.pdf
Thementag 2022 03 Ein Modell ist trainiert - und jetzt.pdf
 
Thementag 2022 02 Der Deutschen Bahn in die Karten geschaut.pdf
Thementag 2022 02 Der Deutschen Bahn in die Karten geschaut.pdfThementag 2022 02 Der Deutschen Bahn in die Karten geschaut.pdf
Thementag 2022 02 Der Deutschen Bahn in die Karten geschaut.pdf
 
Daten / Information / Wissen - Möglichkeiten und Grenzen des Machine Learning
Daten / Information / Wissen - Möglichkeiten und Grenzen des Machine LearningDaten / Information / Wissen - Möglichkeiten und Grenzen des Machine Learning
Daten / Information / Wissen - Möglichkeiten und Grenzen des Machine Learning
 
Erste Schritte in die neue Welt-So gelingt der Einstieg in Big Data und Machi...
Erste Schritte in die neue Welt-So gelingt der Einstieg in Big Data und Machi...Erste Schritte in die neue Welt-So gelingt der Einstieg in Big Data und Machi...
Erste Schritte in die neue Welt-So gelingt der Einstieg in Big Data und Machi...
 
Darf es ein bisschen mehr sein - Konzepte und Strategien zur Bewältigung groß...
Darf es ein bisschen mehr sein - Konzepte und Strategien zur Bewältigung groß...Darf es ein bisschen mehr sein - Konzepte und Strategien zur Bewältigung groß...
Darf es ein bisschen mehr sein - Konzepte und Strategien zur Bewältigung groß...
 
Big Data und Machine Learning - Wer braucht das schon!?
Big Data und Machine Learning - Wer braucht das schon!?Big Data und Machine Learning - Wer braucht das schon!?
Big Data und Machine Learning - Wer braucht das schon!?
 
Erste Schritte in die neue Welt - So gelingt der Einstieg in Big Data und Mac...
Erste Schritte in die neue Welt - So gelingt der Einstieg in Big Data und Mac...Erste Schritte in die neue Welt - So gelingt der Einstieg in Big Data und Mac...
Erste Schritte in die neue Welt - So gelingt der Einstieg in Big Data und Mac...
 
Darf es ein bisschen mehr sein - Konzepte Strategien zur Bewältigung großer u...
Darf es ein bisschen mehr sein - Konzepte Strategien zur Bewältigung großer u...Darf es ein bisschen mehr sein - Konzepte Strategien zur Bewältigung großer u...
Darf es ein bisschen mehr sein - Konzepte Strategien zur Bewältigung großer u...
 
Daten / Information / Wissen - Möglichkeiten und Grenzen des Machine Learning
Daten / Information / Wissen - Möglichkeiten und Grenzen des Machine LearningDaten / Information / Wissen - Möglichkeiten und Grenzen des Machine Learning
Daten / Information / Wissen - Möglichkeiten und Grenzen des Machine Learning
 
Big Data und Machine Learning - Wer braucht das schon!?
Big Data und Machine Learning - Wer braucht das schon!?Big Data und Machine Learning - Wer braucht das schon!?
Big Data und Machine Learning - Wer braucht das schon!?
 
Daten / Information / Wissen - Möglichkeiten und Grenzen des Machine Learning
Daten / Information / Wissen - Möglichkeiten und Grenzen des Machine LearningDaten / Information / Wissen - Möglichkeiten und Grenzen des Machine Learning
Daten / Information / Wissen - Möglichkeiten und Grenzen des Machine Learning
 
Darf es ein bisschen mehr sein - Konzepte und Strategien zur Bewältigung groß...
Darf es ein bisschen mehr sein - Konzepte und Strategien zur Bewältigung groß...Darf es ein bisschen mehr sein - Konzepte und Strategien zur Bewältigung groß...
Darf es ein bisschen mehr sein - Konzepte und Strategien zur Bewältigung groß...
 

Wohin mit den Utilities - ein Artikel der iks im JavaSPEKTRUM

  • 1. Fachthema  Gut aufgeräumt Build-Tool verwenden sie Maven. Der Build eines Release- Kandidaten besteht aus zwei separaten Schritten: Dependency- H Bau des Artefakts auftrag.jar und H Bau des Webarchivs (WAR-Datei). Management von Nach einigen Tagen Arbeit läuft der Walking Skeleton und der manuelle Systemtest der OHO-Anwendung ist nach dem De- ployment auf den Tomcat erfolgreich. Nach dieser ersten Itera- technischen Standard- tion der OHO-Entwicklung besteht die Anwendung aus zwei Komponenten, der fachlichen Auftrag und der technischen komponenten Builder. Reik Oberrath Die Komponente „Parent“ In jedem Projekt, in dem komponentenorientiert entwickelt wird, tritt Bevor die G&G-Entwickler die Auftragsverwaltung weiterim- immer wieder die gleiche Frage auf: Wohin mit all den allgemeinen plementieren, wollen sie erst die übrigen Komponenten aufset- Klassen wie Utilities, Exceptions, Interfaces und anderen Klassen, die zen. Als Nächstes soll die Horoskopverwaltung erzeugt wer- mehrfach gebraucht werden. Dieser Artikel empfiehlt, einige techni- den. Allerdings fehlt noch ein Hauptmenü, in dem die Auf- sche Standardkomponenten zu bilden, die in ein spezielles Dependen- trags- und Horoskopverwaltung eingehängt werden kön- cy-Management eingebunden sind. Außerdem erklärt er, welche Klas- nen. Aus diesem Grund realisieren die G&G-Entwickler in der sen in welche Komponenten gehören. Diese Vorgehensweise ergänzt zweiten Iteration zunächst die fachliche Komponente Main. In sehr gut das fachlich offene Dependency-Management [Ober12], dieser Komponente werden die übrigen fachlichen Kompo- welches auf die nicht-technischen Komponenten fokussiert ist, und nenten eingebettet. Als minimale Implementierung beinhal- spiegelt moderne Muster modularer Architektur wider [PMA]. Zur Er- tet Main ein Hauptmenü mit dem einzigen Eintrag „Aufträge“ läuterung greift der Artikel die Java-Anwendung OHO aus [Ober12] für die Auftragsverwaltung. Anschließend wird die Horoskop- wieder auf. Dabei wird der Einsatz des Projekt-Management-Tools verwaltung mit Minimalimplementierung aufgesetzt und mit Maven erläutert. dem Menüpunkt „Horoskope“ in das Hauptmenü integriert. Beim Schreiben der ersten Unit-Tests für Main und Horoskop stellen die G&G-Entwickler fest, dass diesen neuen Kompo- Fallstudie: Online Horoskope nenten die Abhängigkeit zur JUnit-Bibliothek fehlt. Der Kom- ponente Auftrag wurde diese Abhängigkeit manuell zugefügt. Die kleine Software-Schmiede „Gut & Günstig“ (G&G) Gingen die Entwickler für Main und Horoskop genauso vor, E erhält von der Astrologin „Starlet“ den Auftrag, eine Ho- würden sie das DRY-Prinzip [DRY] verletzen. Aus diesem roskop-Webanwendung zu entwickeln. Die Anwendung soll es ihren Kunden ermöglichen, ein Horoskop online sowohl zu beauftragen als auch das Horoskop nach erfolgter Zahlung MU-Klassen abzurufen. Diese Anwendung wird Online Horoskop, kurz OHO, genannt. Die G&G-Entwickler diskutieren zurzeit das MU steht für Multiple Usage. MU-Klassen werden al- Buch „Growing Object-Oriented Software, Guided by Tests“ so für mehrfache Benutzung entworfen. MU-Charak- [GOOS]. Auch wenn die G&G-Entwickler (noch?) nicht wirk- ter haben zwar die meisten Klassen, aber bei folgen- lich Test-getrieben entwickeln, sind ihnen die Aspekte der Test- den Klassentypen (s. auch Tabelle 1) ist dieser beson- und Wartbarkeit sehr wichtig. ders ausgeprägt: Zunächst möchten die G&G-Entwickler einen sogenannten „Walking Skeleton“ implementieren, das heißt, das kleins- Utility-Klassen im weitesten Sinn te mögliche Stückchen echter Funktionalität, das als Version Diese Klassen stellen Funktionalität an zentralen Stel- 0.0.1 gebaut, installiert und als Komplettsystem getestet wer- len bereit, die werkzeugartig für verschiedene Zwecke den kann. Dazu wählen sie die Auftragsverwaltung aus. Auf von unterschiedlichen Codeblöcken aus genutzt wer- einer Datenmaske wird ein neuer Auftrag nur mit dem Feld den. Dazu zählen: „Auftraggeber“ erfasst. Beim Speichern wird automatisch eine H Utilities im engeren Sinn: nicht instanziierte Klassen Auftrags-ID generiert und in einer Auftragsliste angezeigt. Für mit statischen Methoden diese minimale Funktionalität setzen die G&G-Entwickler eine H Helferklassen, die instanziiert genutzt werden Datenbank mit einer Auftragstabelle auf, welche zwei Daten- H Stammklassen (häufig abstrakt), die durch Vererbung felder beinhaltet: Auftraggebername und ID. Sie implementie- Funktionalität zur Verfügung stellen ren die Datenmaske, einen Auftragsservice und ein Auftrags- DAO-Objekt. Zu jeder wichtigen Klasse wird eine Testklasse Informationstransferklassen mit JUnit-Tests implementiert. Klassen für den Informationsaustausch zwischen unter- schiedlichen Teilen der Software (z. B. zwischen Kom- ponenten). Dazu zählen: Die Komponente „Builder“ H Datenklassen, deren Inhalte nicht wie Domain-Objek- te persistiert werden und die typischerweise als Ty- Den Produktionscode der Anwendung packen die G&G-Ent- pen in Signaturen von Interface-Methoden verwen- wickler in ein Artefakt „auftrag.jar“, das wiederum für ein det werden Deployment auf einem Tomcat in ein Web Application Ar- H Exception-Klassen, um Ausnahmebedingungen an- chive (WAR) gepackt wird. Für den Bau des WARs erzeugen zuzeigen die G&G-Entwickler die technische Komponente Builder. Als 34 JavaSPEKTRUM 2/2013
  • 2. Fachthema Grund führen sie die neue technische Komponente Parent AbstractOhoUnitTest.java. Beide Komponenten bekommen Parent ein. Das Parent-Maven-Projekt wird mit dem packaging-Typ als Maven-Parent, damit sie die dort konfigurierten Abhängig- „pom“ erzeugt. In den pom-Dateien der drei fachlichen Kom- keiten erben. Für den automatischen Bau werden die neuen ponenten Auftrag, Horoskop und Main wird Parent als „parent“ Komponenten in der Parent-pom-Datei als Module konfigu- konfiguriert. Anschließend wird die Definition der JUnit-Ab- riert. Zuletzt werden sie in der Parent-pom-Datei als neue Ab- hängigkeit von der pom-Datei der Auftragskomponente in die hängigkeit hinzugefügt, damit alle fachlichen Komponenten Parent-pom-Datei verschoben (und der „scope“ von „test“ auf darauf zugreifen können. „provided“ gesetzt). Jetzt erben die drei fachlichen Komponen- Diese Vorgehensweise verursacht aber ein Problem. Maven ten diese Abhängigkeit und können die JUnit-Sourcen benut- kann die Anwendung jetzt nicht mehr bauen. Die Kompo- zen, ohne das DRY-Prinzip zu verletzen. nenten Common und Test waren von der Parent-Komponente Mit der Komponente Parent existiert jetzt eine zentrale Stel- abhängig (wegen der Parent-Konfiguration), und die Parent- le zur Definition aller allgemeinen Abhängigkeiten. Das nut- Komponente ist jetzt wegen der Maven-Dependencies von die- zen die G&G-Entwickler, um für OHO die Logging-Funktio- sen beiden Komponenten abhängig (s. Abb. 2). Der Maven-Re- nalität einzurichten. Sie definieren in der Parent-pom-Datei aktor weiß also nicht, welche Komponente (welches Projekt) er eine Abhängigkeit zur log4j-Bibliothek und können damit in zuerst bauen soll, und liefert deshalb die Fehlermeldung „The allen Komponenten die log4j-Logger benutzen. Außerdem de- projects in the reactor contain a cyclic reference“. finieren sie in der Parent-pom-Datei die Komponenten Main, Die G&G-Entwickler fin- Auftrag, Horoskop und Builder als Module. Damit sind sie in der den folgende Lösung: Sie Lage, den Build eines Release-Kandidaten in nur einem Schritt führen eine zweite Maven- („mvn install“ auf dem Parent-Projekt) durchzuführen. Nach Parent-Komponente ein, Builder dieser zweiten Iteration besteht die OHO-Anwendung aus fünf welche nur für die fachlichen Komponenten (s. Abb. 1). Komponenten zuständig ist. Diese Komponente nennen Fachliche sie Parent.BLoC (Business Komponenten Logic Components). Alle drei A Builder B Builder fachlichen Komponenten Auftrag, Horoskop und Main Parent.BLoC bekommen Parent.BLoC als Maven-Parent. Parent.BLoC Main Fachliche Komponenten werden die technischen Kom- Common Test ponenten Common und Test Auftrag Horoskop als Abhängigkeiten zugefügt. Parent Damit erben die fachlichen Parent Parent Komponenten alle Abhängig- keiten von dieser zentralen JUnit log4j JUnit log4j JUnit log4j Stelle und verletzen so nicht Abb. 2: Dependency-Management mit den neuen technischen Komponenten Common un das DRY-Prinzip. Parent.BLoC Blau: Unterschiede Abb. 2: Dependency-Management mit zu Abb. 1b. Aufgrund der nicht möglichen, rot dargestellten Abhängigk Abb. 1:1: Dependency-Management der ersten 5 ersten fünf OHO-Komponenten, techni-grau Abb. Dependency-Management der OHO-Komponenten. Technische Komponenten sind bekommt wiederumwurde die Komponente Parent.BLoC erzeugt. Komponenten Parent den neuen technischen dargestellt. Aus Gründen der Übersichtlichkeit sind in B und den folgenden Abbildungen die sche Komponenten sind grau dargestellt. Aus Gründen der Übersichtlichkeit sind Common und Test. Blau: Unterschie- Abhängigkeiten zwischen den fachlichen Komponenten (weiß) ausgeblendet. Oben dargestellte als Maven-Parent. Damit er- in B und den folgenden Abbildungen die Abhängigkeiten zwischen den fachlichen de zu Abb. 1b. Wegen der nicht mög- Komponenten immer hängen von weiter unten stehenden ab (siehe „Dependency-Hierarchie“ in Komponenten (weiß) ausgeblendet. Oben dargestellte Komponenten hängen im- ben die fachlichen Kompo- lichen, rot dargestellten Abhängigkei- [FODM] und „Levelize Modules“ in [PMA]). mer von weiter unten stehenden ab (s. „Dependency-Hierarchie“ in [Ober12] und nenten auch die Abhängig- ten wurde die Komponente Parent. „Levelize Modules“ in [PMA]) keiten zu den allgemeinen BLoC erzeugt Third-Party-Bibliotheken JUnit und log4j (s. Abb. 2). Die Komponenten „Common“, „Test“ und „Parent.BLoC“ Die Beziehung zwischen „Common“ und „Test“ Die G&G-Entwickler betrachten den bisher erreichten Stand In der vierten Iteration implementieren die G&G-Entwickler und stellen fest, dass sowohl im Produktions- als auch im Test- nun die fachlichen Komponenten Rechnung und Stammdaten code das DRY-Prinzip verletzt wurde: Jede fachliche Kompo- mit minimaler Funktionalität. Sie stellen fest, dass die neuen nente enthält eine Reihe von Codeblöcken, die ursprünglich fachlichen Komponenten sehr einfach aufgesetzt werden kön- für die Komponente Auftrag geschrieben und dann fast genau- nen. Lediglich durch Definition der Komponente Parent.BLoC so in die Komponente Horoskop übernommen wurden. Grund als Parent stehen alle benötigten Abhängigkeiten zur Verfü- dafür ist die „parallele Funktionalität“ beim Zugriff auf die Da- gung. Außerdem kann durch die Verwendung der bereits im- tenbank durch ein DAO-Objekt, bei der Darstellung der Daten plementierten Funktionalität in den technischen Komponenten in der GUI oder beim Validieren von Testergebnissen im Test- Common und Test sowohl der Produktions- als auch der Test- code. Deshalb wollen die G&G-Entwickler mit einem Refacto- code der neuen Komponenten schnell und sauber (ohne Verlet- ring die strukturelle Qualität und damit die Wartbarkeit der zung des DRY-Prinzips) implementiert werden. Die G&G-Ent- gesamten Anwendung verbessern, bevor sie die nächste fachli- wickler sind deshalb mit ihrem Refactoring aus der dritten Ite- che Komponente Rechnung aufsetzen. ration sehr zufrieden. In der dritten Iteration erzeugen die G&G-Entwickler zwei Allerdings diskutieren sie die Frage, ob die Komponente neue technische Komponenten. Die Komponente Common be- Common von Test abhängig sein sollte oder umgekehrt (beides inhaltet MU-Klassen (s. Kasten „MU-Klassen“) wie AbstractDao. gleichzeitig ist wegen einer dann zyklischen Referenz nicht java und GuiValidationHelper.java, die Komponente Test die Klasse möglich): www.javaspektrum.de 35
  • 3. Fachthema  H Common abhängig von Test: Die allgemeine OHO-Test-Funk- java, IHoroskopDao.java, IAuftragService.java, IHoroskopService.java). tionalität steht im Testcode von Common zur Verfügung. Die- Die G&G-Entwickler bauen API in die Version OHO 2.0 ein. Da- se Wahl würde den Testcode von Common optimieren. bei stellen sie einen großen Vorteil fest: Die als Code-Duplikate H Test abhängig von Common: Die Common-Funktionalität steht markierten Code-Blöcke (siehe oben Kapitel „Das Problem der im Code von Test zur Verfügung. Diese Wahl würde den Wiederverwendbarkeit“), welche fachliche Typen beinhalten Code von Test und damit den Testcode aller fachlichen Kom- und deshalb vorher nicht in Common oder Test ausgelagert wer- ponenten optimieren. den konnten, können jetzt aus den fachlichen Komponenten Die G&G-Entwickler entscheiden sich für die zweite Alternati- herausgezogen werden, wenn an diesen Stellen die Interface- ve, weil sich fachliche Komponenten wegen Kundenwünschen Typen verwendet werden. Dieses gilt für den Produktions- und häufiger ändern als technische (siehe unten). Um beim Aufset- den Testcode. Aus diesem Grund bekommen die Komponen- zen neuer und beim Ändern existierender fachlicher Kompo- ten Common und Test eine Abhängigkeit zu API. Jetzt werden nenten möglichst flexibel zu sein, soll der Testcode der fachli- alle Code-Duplikate entfernt und der gemeinschaftlich genutz- chen Komponenten optimiert werden. te Code wird sauber an einer einzigen, zentralen Stelle imple- mentiert. Abbildung 3 zeigt das neue Beziehungsgefüge. Das Problem der Wiederverwendbarkeit Die Komponente „Global“ In den weiteren Iterationen implementieren die G&G-Entwick- ler die Details der fachlichen Funktionalität in allen fünf fach- Beim Einbau von API stoßen die G&G-Entwickler auf ein wei- lichen Komponenten. Dabei gehen sie nach folgender Regel teres Problem, das ebenfalls die Wiederverwendbarkeit betrifft. vor: Wird ein Block von Programmzeilen an mehreren Stellen Die bisherige Sammlung von MU-Klassen in der Common- benötigt, wird er in einer MU-Klasse zur Verfügung gestellt – Komponente wurde zum Teil für OHO neu entwickelt. Ein an- für den Produktionscode in der Komponente Common, für den derer Teil stammt aber aus anderen Anwendungen, in denen Testcode in der Komponente Test. diese Funktionalität ursprünglich entwickelt wurde. Diesen Dabei müssen die G&G-Entwickler leider feststellen, dass Code wiederzuverwenden, war nicht immer leicht, denn der viele Codeblöcke nicht zentral zur Verfügung gestellt werden ursprüngliche Code hatte einige Abhängigkeiten zu Klassen, können, weil diese Codezeilen fachspezifische Java-Typen (z. die spezifisch für diese anderen Anwendungen waren. Das B. Auftrag.java) beinhalten, die in den fachlichen Komponenten machte manchmal ein Refactoring nötig, damit der wieder- definiert sind und deshalb in den technischen Komponenten verwertbare Code-Block herausgelöst und problemlos in den Common und Test nicht referenziert werden können. Die Ent- OHO-Code integriert werden konnte. wickler diskutieren dieses Problem, haben aber noch keine sau- Mit der Einführung der API-Komponente bekommen die bere Lösung dafür. Daher markieren sie diese Codestellen mit G&G-Entwickler das gleiche Problem in der OHO-Anwen- Kommentaren, die das Problem schildern, und tolerieren bis dung: Wenn später Common-Funktionalität für andere Anwen- auf Weiteres diesen Schmutz im Code. dungen wiederverwendet werden soll, darf sie keine Abhän- gigkeiten zu den fachspezifischen Interface-Typen der API- Komponente haben. Die Komponente „API“ Um die Effizienz ihrer Softwareentwicklung zu steigern, beschließen die G&G-Entwickler eine technische Kompo- Schließlich ist alle benötigte Fachlichkeit implementiert und nente mit Namen Global zu erzeugen (s. Abb. 4). Diese Kom- die OHO-Version 1.0.0 wird produktiv. Durch den produktiven ponente soll diejenigen MU-Klassen beinhalten, die fachun- Einsatz ergeben sich Kun- spezifisch sind und in denwünsche, die Ände- verschiedenen Anwen- rungen und damit weitere dungen wiederverwen- Builder OHO-Versionen nach sich det werden können. Um Builder ziehen (s. [Ober12]). Da- das deutlich zu machen, bei stellen die G&G-Ent- enthält der Namespace Fachliche wickler zahlreiche Pro- der globalen Klassen Fachliche Komponenten bleme fest, die das De- keine Anwendungsbe- Komponenten pendency-Management zeichnung und lautet zwischen den fachlichen nur „de.gg.global“. Da- Parent.BLoC Parent.BLoC Komponenten betreffen. gegen heißt der Name- Diese Probleme und space in der Komponen- Test deren Lösung wurden te Common „de.gg.oho. Test Common Common in [Ober12] ausführlich common“. Das zeigt erläutert. Die Lösung be- an, dass sich hier Klas- steht in der Einführung sen befinden, die für API API global einer neuen technischen die OHO-Anwendung Parent Komponente API (Appli- spezifisch, aber für alle Parent cation Interface). Diese ihre fachlichen Kompo- beinhaltet sämtliche In- nenten allgemein sind. JUnit log4j JUnit log4j terface-Typen für alle kon- Tabelle 1 nennt einige zeptionellen Schnittstellen Abb. 3: Dependency-Management mit der neuen technischen Komponenten API. Abb. 3: Dependency-Management mit Beispiele für globale 4: Abb. 4: Dependency-Management mit der Komponenten Glob Abb. Dependency-Management mit der neuen technischen Blau: Unterschiede zu Abb. 2. Blau: der neuen technischen Komponenten API. zwischen den Komponen- Klassen und solche, die Unterschiede zu Abb. 3. Komponente Global. neuen technischen Blau: Unterschiede zu Abb. 2 ten (z. B. IAuftrag.java,, nur für OHO-Code all- Blau: Unterschiede zu Abb. 3 IHoroskop.java, IAuftragDao. gemein sind. 36 JavaSPEKTRUM 2/2013
  • 4. Fachthema Klassentyp Common Global Test statische Utilities AuftragsUtil.java GGValidationUtils.java GlobalTestUtils.java,OHOTestUtils.java nicht statische Helferklasse AuftragSorter.java GGTextFieldValidator.java Stammklasse OHOTextfield.java GGTextField.java OhoUnitTest.java nicht persistierte Datenklasse RawAuftrag.java GGValidationResult.java Exception-Klasse OhoDaoException.java GGValidationException.java Tabelle 1: Beispiele für MU-Klassen Globaler Testcode Die Entwickler einigen sich darauf, diese MU-Klassen nur mit einfachen Getter- und Setter-Methoden auszustatten, und Die G&G-Entwickler überlegen, die Komponente Test aufzu- erlauben sich ganz pragmatisch, für diese einfachen Methoden teilen in Test.Global und Test.Common. Für die Wiederverwen- auf Unit-Tests zu verzichten. Schließlich einigen sie sich auf die dung von Testcode wäre das sinnvoll. Doch sind sie „vor- im Kasten „Entscheidungsbaum für die Komponentenfindung sichtig vor dieser Optimierung“ [VvO] und beherzigen das neuer MU-Klassen“ dargestellte Vorgehensweise. Clean-Code-Prinzip „Keep It Simple, Stupid“ [KISS]. Sie ent- scheiden sich stattdessen, in der Komponente Test die Klas- se GlobalTestUtils.java zu erzeugen und dort den wiederver- Das Problem der „API“-Komponente wendbaren Testcode zu pflegen. Für den aktuellen Umfang des Testcodes reicht das derzeit vollständig aus. Die Entschei- Im Laufe der weiteren Entwicklung der OHO-Anwendung dung, für globalen Testcode eine eigene Komponente anzu- stellen die G&G-Entwickler fest, dass ihr Vorsatz, in den MU- legen, wird solange verschoben, bis die jetzige Entscheidung Klassen der API-Komponente nur Getter- und Setter-Metho- Probleme macht. den zu implementieren, im Projektalltag verloren ging. Einige nicht persistierte Datenklassen (s. Kasten „MU-Klassen“) bein- halten mittlerweile mehr oder weniger komplexe Code-Blöcke, Wohin mit welcher Klasse? die jetzt ungetestet sind und deshalb ein stark erhöhtes Poten- zial haben, einen (schwerwiegenden) Fehler in der Produktion Für die weitere Entwicklung erstellen die G&G-Entwickler ein zu verursachen. Schema, nach dem sie entscheiden, in welche Komponente eine Durch ein Refactoring wird dieses Problem aus der Welt ge- neue MU-Klasse gehört. Dabei wird ihnen bewusst, dass API räumt: Für alle nicht persistierten Datenklassen wird grund- nicht nur Interface-Code beinhaltet, sondern auch Implemen- sätzlich ein Interface in der API-Komponente angelegt, das tierung und zwar in Form von MU-Klassen in Methoden-Sig- in Methoden-Signaturen anderer Interfaces genutzt wird. Die naturen (Exceptions und nicht persistierte Datenklassen). Die- Implementierung dieser Datenklassen und der dazugehören- ser Teil des Produktionscodes ist ungetestet, denn für die Kom- de Testcode kommen in die Komponente Common. Außerdem ponente API sind keine Unit-Tests vorgesehen. Dieser Code wählen die G&G-Entwickler einen Code-Watch, der dafür ver- kann aus API nicht herausgelöst werden, weil er von den In- antwortlich ist, den Code zu überprüfen und dafür zu sorgen, terfaces genutzt wird und deshalb direkt zur Schnittstelle (API) dass dies nicht wieder vorkommt. der Anwendung gehört. Während dieser Entscheidung trifft von ihrer Auftraggebe- rin „Starlet“ eine Anfrage ein: Die Anwender würden sich im- mer häufiger über fehlende oder falsche Validierungsfehler be- schweren, welche die Dateneingabe erschweren. Deshalb soll Entscheidungsbaum für die Komponenten- ermittelt werden, wie die Validierung optimiert werden kann findung neuer MU-Klassen und wie viel Aufwand das bedeuten würde. Die G&G-Ent- wickler können die Beschwerden nachvollziehen, denn auch A: die Klasse spezifisch für eine spezielle fachliche Ist aus Entwicklersicht sind sie mit dem Validierungs-Framework Komponente? von OHO nicht zufrieden. Ja: Klasse gehört in diese Komponente. Als Verbesserung diskutieren sie folgende Idee: An die In- Nein: ➞ B terface-Getter-Methoden der Domain-Objekte (IAuftrag.java, IHoroskop.java ...) werden Validierungsregeln annotiert. Zu je- B: Handelt es sich bei dieser Klasse um Testcode? der Regel gibt es eine Klasse, die diese Regel implementiert. Ja: Klasse gehört in die Komponente Test. Ein zentraler OHO-Validator analysiert die Instanzen der Nein: ➞ C Domain-Objekte, durchsucht ihre Annotationen nach Validie- rungsregeln, ruft diese für die vorliegenden Instanzen auf, C: Wird die Klasse in einem API-Interface benutzt? sammelt die Fehlermeldungen und liefert die Fehlerliste als Ja: Klasse gehört in die Komponente API. Resultat. Auf diese Weise könnte sowohl in der GUI als auch Nein: ➞ D im Backend die Validierung durchgeführt werden. Diese Vor- gehensweise würde es nötig machen, die Validierungsregeln D: Enthält die Klasse OHO-spezifische Java-Typen? in API zu implementieren. Dadurch könnte die API-Kompo- Ja: Klasse gehört in die Komponente Common. nente, die ursprünglich testfrei konzipiert wurde, auf Testcode Nein: Klasse gehört in die Komponente Global. nicht mehr verzichten. Damit wäre aber auch der Code-Watch überflüssig. www.javaspektrum.de 37
  • 5. Fachthema  die API-Komponente dazu, Implementierungscode anzurei- chern und zu einer monolithischen Struktur zu werden. Wer JavaSPEKTRUM ist eine Fachpublikation des Verlags: das zu verhindern weiß, oder es wenigstens einschränkt, dem bieten die technischen Komponenten Global, Common, Test, API, SIGS DATACOM GmbH Parent und Parent.BLoC in dem Abhängigkeitsgefüge von Ab- Lindlaustraße 2c bildung 4 einen stabilen technischen Rahmen, um flexibel auf 53842 Troisdorf Änderungen zu reagieren und die Wiederverwendbarkeit von Tel.: 0 22 41/23 41-100 Code zu verbessern. Fax: 0 22 41/23 41-199 E-Mail: info@sigs-datacom.de www.javaspektrum.de Literatur und Links [DRY] http://www.clean-code-developer.de/Don-t-Repeat-Yourself-DRY. ashx?HL=dry [GOOS] St. Freeman, N. Pryce, Growing Object-Oriented Soft- ware, Guided by Tests, Pearson Education, Inc, 2010 [KE] http://de.wikipedia.org/wiki/Komponentenbasierte_Entwicklung [KISS] http://www.clean-code-developer.de/Keep-it-simple-stupid-KISS. ashx?From=KISS [Ober12] R. Oberrath, Das fachlich offene Dependency- Management, in: JavaSPEKTRUM, 6/2012 Nach zähen Verhandlungen und Zugeständnissen aller [PMA] http://refcardz.dzone.com/refcardz/patterns-modular-architecture Stakeholder können die GG-Entwickler die neue Validierung [VvO] http://www.clean-code-developer.de/Vorsicht-vor-Optimierungen. umsetzen. Damit ist unvermeidbar, dass die API-Komponente ashx?HL=vorsicht zu einer Mischung aus Interface-, Implementierungs- und Test- code wird. Interfaces und Implementierung gehören technisch so eng zusammen, dass die fachliche Implementierung nicht davon getrennt werden kann. Dr. Reik Oberrath ist als IT-Berater bei der iks Fazit Gesellschaft für Informations- und Kommunikations- systeme mbH tätig. Er beschäftigt sich seit vielen Jah- Der Kasten „Entscheidungsbaum für die Komponentenfin- ren mit der Entwicklung von individuellen Geschäfts- anwendungen, speziell unter Swing und RCP. Einen dung neuer MU-Klassen“ erklärt, welche Klasse in welche besonderen Fokus legt er auf Automatisierung in der technische Komponente gehört. Abbildung 4 zeigt die Abhän- Qualitätssicherung und im Release Build sowie auf gigkeiten zwischen diesen Komponenten. Software, die nach Clean Code. dieser Vorgehensweise entworfen wurde, besitzt ein robustes E-Mail: R.Oberrath@iks-gmbh.com und gleichzeitig flexibles Dependency-Management. Es ist ro- bust, weil es für jedes Stück Implementierung einen Platz vor- sieht, und flexibel, weil dieser Platz bei Bedarf wechseln kann, ohne eine Dependency-Hölle zu verursachen. Allerdings neigt 38 JavaSPEKTRUM 2/2013