Agile Entwicklung

Ich habe neulich ein relativ übersichtliches Swing/JPA Projekt gebaut und hatte dabei den Luxus zeitlich recht frei zu sein.

Bei GUI-lastigen Programmen für Kunden ist es besonders wichtig, schnell einen Prototypen zu haben, den der Kunde ausprobieren kann. Die meisten Kunden kommen nicht aus der IT-Branche und sind es oft nicht gewohnt, alltägliche Abläufe zu abstrahieren. Es ist also ziemlich belanglos, wie gut die Vorgespräche waren, es muss schnell etwas Konkretes zum ausprobieren her, damit erfahren werden kann, was vorher besprochen wurde. Damit hat man dann eine großartige Grundlage für die ganz sicher nötigen Anpassungen, bis Kunden- und Enwicklervorstellung sich decken.

Provisorien halten ewig

Der Code von dem funktionsfähigen Prototypen sah schrecklich aus und auch nur wenigen Tage Pause hätten vermutlich dafür gesorgt, dass nichtmal ich weiß, was ich da geschrieben habe. Alle GUI Konstrukte für den Hauptdialog in einer Klasse, keine Zeile Dokumentation (abgesehen von den „FixMe“ und „ToDo“ Kommentaren) und redundanter Code.

Zwar hat das Programm die funktionalen Anforderungen erfüllt, war aber nicht mehr wirklich wartbar. Das ist allerdings für einen nicht Techniker nicht sichtbar. Der Kunde sieht die GUI, sieht, dass was passiert, wenn er irgendwo draufdrückt und ist ersteinmal zufrieden. Es wird jetzt sehr schwierig zu erklären, dass das Programm zwar funktioniert aber noch nicht „fertig“ ist. Für den Kunden ist das Projekt jetzt beendet.

Dass das auch auf InHouse Projekte von Firmen mit eigener IT-Abteilung zutrifft, sehe ich täglich bei meinen Beratungskunden. Da Erklären mir regelmäßig Administratoren den Unterschied zwischen „bösen“ und „guten“ Exceptions: Gute Exceptions werden kontinuierlich ins Log geschrieben und werden zu bösen Exceptions, wenn die Applikation den Server lahmlegt. Dass es sich meist um exakt die gleichen Exceptions handelt die nur zu unterschiedlichen Zeitpunkten (einmal kurz nach dem Start des Servers – einmal kurz vor dem Absturz) betrachtet werden, ist dabei uninteressant.

Refactoring gehört zum Projekt

Nun, mein GUI Projekt sieht inzwischen gut aus. Ich habe den redundanten Code zusammengefasst, das Eventsystem überarbeitet und den Hauptdialog in mehrere Klassen aufgeteilt.

Gerade bei den etwas altbackenen, geschwätzigen Sprachen wie Java ist dabei eine gute IDE ausgesprochen hilfreich. Was dafür jedoch noch wichtiger ist, sind gute Tests, damit man sicherstellen kann, dass man beim Aufräumen nicht die funktionalen Anforderungen zerschießt.

Ich kann jetzt auch nach längerer Pause auf den Code gucken und weiß, wozu er gut ist – ja ich weiß sogar, wo ich eventuelle Erweiterungen einbauen kann. Und die Erweiterungen kommen. Ein gutes Programm ist ab einem bestimmten Komplexitätsgrad niemals fertig. Es gibt immer eine Zusatzfunktion, die das Leben für den Benutzer angenehmer macht oder eben Aufgrund von Veränderungen im Benutzungsumfeld nötig wird. Bedürfnisse erzeugen Bedürfnisse.

Die erste Entwicklung hat jetzt mit dem Refactoring ca. 20% länger gedauert als die Erstellung des first Shot und wird bei der Erweiterung die Zeit sicherlich auf wenigstens die Hälfte reduzieren. Der zusätzliche Aufwand wird sich so mittelfristig rechnen. Auch nur mittelfristiges Denken ist aber leider in der Branche nicht mehr sehr üblich. Der Prototyp wird zum finalen Produkt, jede Erweiterung wird ein Abreißen und Neubauen mit gleichzeitigem schimpfen auf die Unfähigkeit des ursprünglichen Entwicklers, der das Projekt mit Erstellung des funktionalen Prototypen aus den Händen gerissen bekommt. Teuer und nicht sehr lehrreich ist dieses Vorgehen.

Für eine kontinuierliche Produktentwicklung gehört deswegen Refactoring zwingend zur Projektzeit und sollte von vorne herein mit eingeplant werden.

Die Kristallkugel

Agile Entwicklung basiert auf Kommunikation und ständiger Veränderung. Die gleichen Grundprinzipien, die Gesellschaft am Leben erhält. Könnte man mit dem klassischen Design First Ansatz ein System bauen, dass allen Marktanforderungen entspricht?

Dazu müsste man in die Zukunft blicken können. Müsste Anforderungen kennen, bevor sich diese im Markt etabliert haben. Man müsste die Folgebedürfnisse bereits vorwegnehmen können. Das führt üblicherweise nur zu einer Menge an Funktionen, die später keinen Interessieren und ein Fehlen von Funktionen, die mittelfristig wichtig sind. Egal wie gut man sein Produkt plant, es bleibt bei dem Grundsatz, dass Bedürfnisse Bedürfnisse erzeugen. Das ist der Motor der Welt. Somit ist es ziemlich beliebig, was ich für eine Funktionalität plane, es wird immer eine geben, die darauf aufbaut. Im Zweifelsfall finanziert man also mit dem Blick in die Kristallkugel einen Holzweg aus Mahagoni.

Es ist meist eine gute Idee, sich bei neuen Produkten ersteinmal auf das Problem zu beschränken, dass sie vornehmlich lösen sollen. Neue Anforderungen kommen im Betrieb von ganz allein.

Java EE Arbeitsumgebung

Ich werde oft gefragt, was bei einer Entwicklung im Enterprise Java Umfeld hilft. Hier meine derzeitigen Favoriten:

Teil 1: Tools

IDE: Netbeans

„Wozu brauche ich überhaupt eine IDE? Ein Editor tut es doch auch.“ Das ist erstmal nicht falsch. Was bei einer IDE meist nett ist, sind die Tools zum Refactoring und zur Navigation im Quellcode.

Ich selbst habe jahrelang Eclipse benutzt und es ist eine wirklich gute IDE. Was mich in jüngster Zeit immer wieder gestört hat ist die unterschiedliche Qualität der benötigten Plugins. Es geht einfach zu viel Zeit verloren bin dem Versuch die Plugins so zu kombinieren, dass man eine einigermaßen funktionierende Arbeitsumgebung hat. Für die Tools, die ich benutze ist die Unterstützung in Netbeans deutlich besser und spätestens seit der 6er Version steht Netbeans auch in Punkto Geschwindigkeit nicht mehr nach.

Build Tool: Maven 2

Das Probem in größeren Projekten ist oft einen Build Prozess zu bauen, der einigermaßen nachvollziehbar ist und diese Standards dann über die einzelnen Unterprojekte beizubehalten. Innerhalb von kürzester Zeit kommt es so zu einem Modulwidldwuchs mit Abhängigkeiten, die nur noch von einem Mitarbeiter durchblickt werden, der leider schon seit Jahren nicht mehr in der Firma ist.

Maven gibt im Wesentlichen eine Projektstruktur vor. Zusätzlich sind automatisierte Tests, Dokumentationsgeneration sowie automatische Codeanalyse bereits in den Build Prozess integriert. Das Hauptargument für die Meisten dürfte jedoch die automatisierte Verwaltung von Bibliotheksabhängigkeiten sein.

Continuous Integration: Hudson

Es ist zwar schön und gut, wenn ein Build lokal auf dem Entwicklerrechner läuft, allerdings hat man zu oft das Problem, dass er eben auch nur auf diesem läuft. Was hilft, ist ein Build in einer neutralen Umgebung. Gleichzeitig möchte man fertige Builds auch anderen Entwicklern zur Verfügung stellen. Das wohl genialste CI Tool ist Hudson. Mit keinem Tool ist es einfacher ein Projekt aufzusetzen.

Configuration Management: Subversion

Ich gebe zu, es viel mir schwer, mich von dem seit über 10 Jahren benutzen cvs zu trennen. Aber im Java Umfeld ist insbesondere die von Subversion gebotene Möglichkeit Ordner zu verschieben (wenn man z.B. mal ein Paket umbenennt) unbezahlbar. Transaktionale Commits sind in einem größeren Entwicklungsumfeld ebenfalls ein Plus sowie die feingranulare Rechteverwaltung.

Bug Tracking: jira

Das Tool kostet Geld aber es ist nach meiner Erfahrung jeden Cent wert. Komplexe Rechteverwaltung, hierachische Projektstrukturen, Zeitverwaltung. Die Liste der Features ist quasi endlos. Für mich klar die Nummer eins der Bugtracker.

Wiki: Confluence

Source Code Dokumentation ist eine Sache aber im Entwicklungsprozess fallen noch eine Menge anderer Dokumente an: Anforderungen, Designdokumente oder auch einfach Anleitungen, Tips und Tricks usw. Damit diese Dokumente aktuell gehalten werden, müssen sie permanent für alle Beteiligten im Zugriff und änderbar sein. Gleichzeitig sollten diese Änderungen nachvollziehbar sein. Das alles sind Anforderungen, die ein Wiki erfüllt. Confluence ist ein sehr gutes Wiki System. Wenn man Jira kauft, gibt es das für einen relativ geringen Aufpreis dazu. Neben den herausragenden Verwaltungsmöglichkeiten halte ich insbesondere die Möglichkeit, Wiki-Seiten direkt aus Word heraus zu ändern, für ein absolutes Killerargument. Gerade in den kundennahen Abteilungen sitzen oft Mitarbeiter, die sich mit Word deutlich besser als mit der Wiki Sprache anfreunden können. Wer schon einmal versucht hat, aus einem shared Verzeichnis das gerade für das Projekt aktuelle Word Dokument herauszufinden, wird wissen, wovon ich rede. Kommunikation ist alles und Confluence ist eine gute Hilfe.

Application Server: Glassfish

Der Open Source Appliaction Server von Sun ist einfach großartig. Ursprünglich war er nichts weiter als die Referenzimplementaion von Java EE 5. Inzwischen ist es ein solider und schneller Applicationserver mit einem Beeindruckenden Featureset und einer extram agilen Community. Die Adminstartions Tools und Oberfläche sind das Beste, was ich bislang gesehen habe. Großartig sind auch die Call Trace Features und vor allem die unverschämt gute Dokumentation. Ich glaube nicht, dass es derzeit einen besseren Java EE 5 Applicationserver gibt. Die Installation mit einem Wizzard dauert wenige Minuten und spätestens wenn man einen Blick auf die Adminoberfläche geworfen hat, ist zumindest die Vorentscheidung bereits gefallen.