Post bewerten
Mittwoch, März 26, 2008
Übersichtsartikel zu eXtreme Programming
Dienstag, März 18, 2008
Software-Architektur mit Dependency-Injection
Dieser Artikel beschreibt meine Erfahrungen mit Dependency-Injection (DI) in mehrjährigen Großprojekten. Dabei geht es vor allem um die Best-Practices für Entwurf und Architektur.
Wir haben vor allem handprogrammierte DI, Pico-Container und Java-Server-Faces als DI-Container eingesetzt. Der Artikel bezieht sich primär auf Pico-Container. Die „Erkenntnisse“ lassen sich aber auf andere DI-Container übertragen.
In einem Großprojekt haben wir ein System mit vielen Singletons schrittweise auf Pico-Container umgestellt. Wir haben einige größere Refactorings in dem Projekt durchgeführt und bei vielen war der Nutzen letztlich zweifelhaft. Der Umbau auf Pico-Container gehört aber definitiv zu den Umbauten, die sich deutlich gelohnt haben.
Zielsetzungen
Mit DI kann man eine Reihe von Zielen erreichen:
- Entwurf entkoppeln
- Abhängigkeiten explizieren
- Testbarkeit verbessern
- Singletons und static-Attribute eliminieren
Entwurf entkoppeln
DI führt nicht automatisch zu einer Entkopplung der Systemkomponenten. Man kann sich auch mit DI eigenartige und unwartbare Abhängigkeitsgeflechte zusammenbauen. Ohne DI hingegen ist es in der Praxis fast unmöglich, entkoppelte Systeme zu bauen. In diesem Sinne ist DI eine notwendige, aber keine hinreichende Bedingung für Entkopplung. Wenn man zusätzlich zu DI noch Interfaces und testgetriebene Entwicklung einsetzt, bekommt man aber ohne größere Anstrengungen ein gut entkoppeltes System.
Abhängigkeiten explizieren
DI macht die Abhängigkeiten von Objekten an ihrer Schnittstelle deutlich. Dadurch ist erstmal natürlich nur ein wenig Dokumentation gewonnen. In unseren Projekten hat dieses kleine bisschen Mehr an Dokumentation aber erheblichen Einfluss darauf gehabt, wie gut man Entwürfe verstehen konnte.
Testbarkeit verbessern
Durch die Entkopplung ließen sich die einzelnen Komponenten besser testen. Hier fällt insbesondere die Harmonie von DI mit Mock-Testen[1] positiv auf. Zusammen mit testgetriebener Entwicklung entsteht ein schlagkräftiges Trio.
Nicht zuletzt laufen so entkoppelte Tests viel schneller ab als klassisch erstellte Unit-Tests (in einigen Fällen konnten wir Testlaufzeiten von mehreren Minuten auf unter 10 Sekunden reduzieren).
Singletons und static-Attribute eliminieren
Setzt man DI konsequent ein, braucht man weder Singletons noch irgendeine andere Form statischer Attribute. Dadurch werden Zustandsabhängigkeiten im System reduziert, so dass sich Systemteile besser unabhängig voneinander wieder verwenden und testen lassen.
In unseren Projekten sind durch die Umstellung von Singletons auf DI eine ganze Reihe eigenartiger Phänomene beim Ausführen und beim Testen verschwunden.
Pico-Container im Code
Pico-Container ist ein sehr leichtgewichtiger DI-Container, der programmatisch konfiguriert wird. Daher können programmatisch DI-Container erzeugt und an andere Objekte übergeben werden. Da ist eine Fußangel versteckt: Man sollte Pico-Container minimal-invasiv benutzen. Das bedeutet, dass möglichst wenig Code Kenntnis davon haben soll, dass Pico-Container (oder ein anderer DI-Container) eingesetzt wird. Folglich sollten die Pico-Container nur im Startup erzeugt werden. Weitere Klassen dürfen nicht vom Pico-Container abhängen. In der Schichtung des Systems liegt der Pico-Container also ganz oben.
Pico-Container in Tests
In Unittests hat Pico-Container nichts verloren. Sind die getesteten Klassen so kompliziert miteinander verflochten, dass man sie manuell nicht zusammenstecken kann, ist Refactoring angesagt – und zwar schleunigst.
Welche Klassen registriert man beim DI-Container?
In unseren Projekten haben sich drei Typen von Klassen etabliert, die wir typischerweise beim DI-Container registrieren.
- Fabriken
- Services
- Objekte, die nur einmal existieren dürfen (ehemalige Singletons)
Wofür baut man Fabriken?
Wenn ein Objekt andere Objekte erzeugen will, kann man diese Objekte nicht über DI hineinreichen – man weiß ja noch nicht, wie viele Objekte erzeugt werden. In solchen Fällen reicht man stattdessen Fabriken per DI in das Objekt.
Fabriken werden häufig mit static-Methoden implementiert. Wenn man die Fabriken beim DI-Container registriert, wäre das jedoch einigermaßen witzlos. Also gilt: Fabriken sollten keine static-Methoden enthalten – static-Attribute sowieso nicht.
In vielen Projekten habe ich beobachtet, dass viel zu selten Fabriken benutzt werden! Fabriken (ohne static-Methoden) helfen bei DI und erleichtern das Testen mit Mocks ungemein[2]. Im Zweifel würde ich lieber eine Fabrik zuviel spendieren.
Abschluss
Unsere Erfahrungen mit Pico-Container haben wir in erster Linie in Rich-Clients gesammelt. Wir haben Pico-Container serverseitig nicht verwendet. Es sollte jedoch möglich sein, weil der Pico-Container sehr leichtgewichtig ist. Der Overhead für die Erzeugung bei jedem Request oder EJB-Aufruf sollte in den meisten Anwendungen zu verkraften sein. Wenn der Overhead zu groß wird, kann man den Pico-Container mind. bei Webanwendungen auch in der Session speichern.
Inzwischen kommen viele Server-Infrastrukturen aber bereits mit eigenen DI-Containern (Spring, JSF, EJB 3), so dass man serverseitig i.d.R. wahrscheinlich nicht in die Verlegenheit kommt, Pico-Container einzusetzen.
Referenzen- Easy Mock: http://www.easymock.org
- EJB 3: http://java.sun.com/products/ejb/docs.html
- Java Server Faces: http://java.sun.com/javaee/javaserverfaces
- Pico Container: http://www.picocontainer.org
- Spring: http://www.springframework.org
[1] z.B. mit Easy Mock
[2] Beim Testen gilt: Jedes Testproblem kann durch eine weitere Indirektion gelöst werden.
Post bewerten
Montag, März 17, 2008
Grails-Anwendung: Team-Radar ist Live
Post bewerten
Montag, März 03, 2008
Junit 4.4: assertThat
Junit 4.4 ist bereits seit über einem halben Jahr verfügbar. Von den Projekten, die ich kenne, arbeiten viele aber noch mit JUnit 4.0 oder noch älter. Grund genug, einmal ein unscheinbar daher kommendes neues Feature zu betrachten.
assertThat
Zunächst gibt es eine neue assert-Methode namens assertThat. assertThat bekommt zwei Parameter übergeben, den tatsächlichen Wert (im Gegensatz zu assertEquals als ersten Parameter) und einen Matcher. Über die Matcher wird letztlich die zu testende Bedingung ausgedrückt.
Aus
assertEquals(10, list.size());
wird
import static org.hamcrest.core.Is.is;
...
assertThat(list.size(), is(10));
Diese Art der Notation geht in Richtung Fluent-Interface und ist aus meiner Sicht etwas besser lesbar als die klassische Notation.
Zusätzlich zu is() sind weitere Matcher verfügbar, so dass man im Wesentlichen mit assertThat auskommen sollte und die meisten anderen assert-Methoden nicht mehr braucht.
Ausdrucksstärker mit Hancrest
Die assertThat-Notation geht auf Hamcrest zurück. In JUnit 4.4 ist ein Teil davon enthalten - warum man da so halbe Sachen gemacht hat, erschließt sich mir nicht. Wenn man assertThat verwenden möchte, empfiehlt es sich aus meiner Sicht, Hamcrest komplett mit einzubinden. Dann hat man mächtige Matcher zur Verfügung, die die Tests nicht nur lesbarer, sondern auch kürzer gestalten. Möchte ich z.B. den Inhalt einer Liste testen, ist das mit Hamcrest ein Einzeiler:
import static org.hamcrest.Matchers.*;)
...
assertThat(list, hasItems("a", "b", "c"));
Bessere Fehlermeldungen
Nicht zuletzt generiert Hancrest bei fehlschlagenden Tests Fehlermeldungen, die häufig aussagekräftiger sind als bei JUnit-Classic. Bei JUnit-Classic war man außerhalb von assertEquals auf assertTrue oder assertFalse angewiesen und hat dann nur die Meldung bekommen, dass der Test fehlgeschlagen war. Die Gründe dafür konnte man in der Meldung aber nicht erkennen. Hamcrest hingegen generiert aus dem kompletten Matcher eine aussagekräftige Fehlermeldung:
assertThat(foo, anyOf(is(1), is(3)));
prüft, dass das foo den Wert 1 oder 3 hat (man möge mir das schwache Beispiel verzeihen). Wenn das nicht der Fall ist, erhalten wir in JUnit eine aussagekräftige Fehlermeldung:
java.lang.AssertionError:
Expected: (is <1> or is <3>)
got: <2>
Fazit
Das assertThat-Feature kommt etwas unscheinbar daher. Ich finde, dass dem Feature mehr Ehre gebührt und dass es in der Praxis einen größeren positiven Effekt hat, als man zunächst meinen möchte.
Post bewerten
Samstag, Februar 02, 2008
Wer erinnert sich noch: Real Programmers Don't Use PASCAL
Also hier für alle alten Säcke nochmal der Link auf den Artikel (damals kursierten schlechte Fotokopien davon, heute gibt es das Internet). Auf dass wir in sentimentalen "das waren noch Zeiten"-Gefühlen versinken...
Und vielleicht finden den Artikel ja auch die Jüngeren amüsant.
Post bewerten
Mittwoch, Januar 23, 2008
Zertifizierung durch Community
Auf der einen Seite wird argumentiert, dass Zertifikate dem Kunden eine Auskunft über bestimmte Minimalkriterien geben. Auf der anderen Seite steht, dass das Minimum möglicherweise nur aussagt, dass man eine bestimmte Zeit in einer Schulung abgesessen hat und das für den Kunden zu wenig aussagekräftig ist.
Daher haben sich viele auf den Standpunkt gestellt, Zertifikate bringen nur dann etwas, wenn man zu ihrer Erlangung auch Fähigkeiten nachweisen muss.
Es gibt jetzt eine neue Web-Site namens You Vouch For, die diesen Ansatz auf Community-Basis verfolgt. Man trägt sich dort ein und kann andere Leute "zertifizieren", also bescheinigen, dass sie bestimmte Dinge können.
Mir fallen sofort dutzende Gründe ein, warum das Vorhaben nicht funktionieren könnte. Ich finde es aber ausreichend interessant, dass man der Geschichte eine Chance geben sollte. Ich habe mich also gleich mal registriert...
Post bewerten
Freitag, Januar 04, 2008
Verteilte Meetings mit Card-Meeting
Drollige Geschichte am Rande: Einer der Teilnehmer wollte von zu Hause aus an der Retrospektive teilnehmen und hatte sich seinen Rechner zerschossen. Also ist er zu seiner Schwester und hat deren alten PC verwendet. Der Rechner war anscheinend etwas zu alt für Skype. Auf jeden Fall ist Nico immer wieder aus dem Chat geflogen. Das haben wir aber zuerst gar nicht bemerkt, weil wir Skype im Hintergrund hatten und Card-Meeting im Vordergrund.
Nico hat dann einfach eine rote Karte in Card-Meeting geschrieben "Nico wieder zu Skype einnladen" und hat damit in Card-Meeting rumgewedelt, so dass wir auf das Problem aufmerksam wurden.
Post bewerten
Freitag, Dezember 21, 2007
mein erstes Grails-Projekt
Bei Groovy und Grails verhält es sich anders. Ich hatte jetzt das Glück, dass ich zum Jahresausklang ein kleines Grails-Projekt machen konnte. Ich hatte Grails bereits vorher ein wenig ausprobiert und hatte daher eine Idee, was mich erwartete. Und diese Erwartungen wurden noch übertroffen.
Wir haben in sehr kurzer Zeit eine kleine aber komplette Internetanwendung mit lächerlich wenig Code geschrieben. (Sobald die Anwendung Live ist, werde ich den Link hier mal posten.)
Besonders beeindruckt hat mich die Klarheit des Programmiermodells. Struts, JSF und Spring Web-MVC haben bei mir immer das Gefühl hinterlassen, dass intern Dinge passieren, die ich nicht ganz verstehe. Dieses Gefühl habe ich mit Grails nicht.
Weiterhin ist interessant, dass wir - obwohl es für alle das erste Grails-Projekt war - jedes Problem in weniger als 2 Stunden lösen konnten. Bei anderen Java-Technologien hatten wir immer wieder Fälle, wo wir uns Tage oder gar Wochen die Zähne ausgebissen haben; teilweise konnten wir die Probleme gar nicht lösen und mussten dann mit Work-Arounds arbeiten.
Post bewerten
Samstag, Dezember 15, 2007
neues Buch zu Scrum
Post bewerten
Korrektur zur DAO-Aussage im Hibernate-Buch
Das stimmt, wenn man DAOs nur zur Kapselung der DB bzw. von JDBC verwenden möchte. Denn das leistet Hibernate sehr gut. Dennoch sollte man seine Anwendung ohne Datenbank testen wollen, also Mocks einsetzen. Und dazu braucht man dann doch wieder sowas wie DAOs.
In unseren Projekten setzen wir da auf das Repository-Muster von Domain Driven Design (Eric Evans), was technisch den DAOs sehr ähnlich ist.
Sorry für die Falschaussage und Danke an Eberhard Wolff, dass er mich darauf aufmerksam gemacht hat.
Post bewerten
Screencast zum Vortrag "Einfachheit in Softwareprojekten"
Glücklicherweise hat Jens Himmelreich den Ton separat aufgezeichnet und mir zur Verfügung gestellt. Nach ziemlich viel Arbeit habe ich es dann auch geschafft, Bild und Ton so zu mischen, dass sie synchron laufen.
Das Gesamtkunstwerk kann man sich hier ansehen (oder einfach nur den Ton oder die Folien als PDF runterladen).
Nochmal vielen vielen Dank an Jens Himmelreich. Ohne seine Ton-Aufnahme wäre das alles nichts geworden.
Post bewerten
die zweite Internet-Blase?
Post bewerten
Samstag, Dezember 08, 2007
Lohnt sich Dependency-Injection
Ich finde, die Diskussion geht etwas am eigentlichen Kern vorbei. DI ist erstmal nur eine Technik, genauso wie Mock-Testen. Keines von beiden ist generell gut oder schlecht. Genauso wie Entkopplung nicht automatisch gut ist. Man muss auch die richtigen Teile entkoppeln.
Meiner Meinung nach ist das Dependency-Inversion-Principle (DIP) das übergeordnete Konzept. DIP sagt, dass ein High-Level-Konzept nicht von Low-Level-Implementationen abhängen sollen. Demnach darf z.B. die Fachlogikschicht nicht von der Datenbankschicht abhängen. Begründung: Low-Level-Implementationen ändern sich häufiger als High-Level-Konzepte und die Änderungen finden nicht nur hinter dem API der Low-Level-Implementation statt, sondern schlagen häufig bis in die Klienten durch. Hängen die High-Level-Konzepte von den Low-Level-Implementationen ab, müssen sie unnötig häufig geändert werden.
Das bedeutet: DIP ist generell gut.
DI und Mocks erlauben mir, DIP umzusetzen. Daher sind DIP und Mocks mind. dann gut, wenn sie für DIP eingesetzt werden.
Interessanterweise korreliert DIP mit vielen Aspekten aus Quasar.
Post bewerten
Warum einfach, wenn es auch kompliziert geht?
In dem Vortrag ich von einem Experiment berichtet, dass von Bavelas an der Stanford-Universität durchgeführt wurde. Man hat Propanden mit Bildern von Gewebezellen konfrontiert. Sie sollten ohne medizinische Vorkenntnisse diagnostizieren, ob die Zellen gesund oder krank sind. Sie bekamen als Feedback dann jeweils, ob sie richtig oder falsch gelegen haben. Aus dem Feedback entwickelten sie ein Modell darüber, woran man krankhafte Gewebezellen erkennt.
Allerdings hat man nur der einen Gruppe korrektes Feedback gegeben. Die andere Gruppe hat zufälliges Feedback erhalten.
Schließlich hat man Paare mit jeweils einem Vertreter jeder Gruppe gebildet, die dann gemeinsam Gewebezellen diagnostizieren sollten. Und dabei setzte sich meistens die Person durch, der man das zufällige Feedback gegeben hatte.
Begründung: Diese Person hat sich auf Basis des zufälligen Feedbacks ein sehr kompliziertes (aber falsches) Modell darüber gemacht, woran man krankhafte Zellen erkennt. Die Person mit dem korrekten und einfachen Modell war begeistert von der Detailtiefe des komplizierten Modells ("da habe ich selbst wohl etwas übersehen") und ist daher der meist falschen Einschätzung seines Partners gefolgt.
Und dieses Phänomen findet sich auch ständig in der Softwareprojekten. Es ist so verführerisch den komplizierten Architekturen, Technologien und Vorgehensmodellen zu folgen. Ich glaube jedoch, dass das meistens der falsche Weg ist: Komplizierte Lösungen sind auch dann falsch, wenn sie richtig sind.
Eine genauere Beschreibung des Experimentes findet sich in "Wie wirklich ist die Wirklichkeit?" von Paul Watzlawick im Kapitel ("Warum einfach, wenn es auch kompliziert geht?"). Der Text findet sich unter der gleichen Überschrift auch Online auf Seite 20ff.
Post bewerten
Montag, November 26, 2007
Interview mit Weinberg
Post bewerten
Sonntag, November 25, 2007
Wie viele Blogs?
Auf mehrfachen Wunsch eines einzelnen Herren überdenke ich diese Entscheidung gerade. Feedback dazu nehme ich gerne entgegen. Wollt Ihr lieber einen Gesamtblog lesen oder lieber getrennt nach privat und IT?
Post bewerten
Audio gesucht zu "Einfachheit in Softwareprojekten"
Mind. ein Teilnehmer hat den Ton auch aufgenommen. An den wendet sich dieser Post. Wenn Du das hier liest und der Ton einigermaßen brauchbar ist, schicke mir bitte, bitte, bitte den Ton an stefan AT stefanroock DOT de
Und wenn jemand einen Tipp hat, wie man eine übersteuerte Tonspur reparieren kann, immer her damit.
Post bewerten
Termine, Termine, Termine
Ich habe dann eine Weile versucht, den zentralen elektronischen Terminkalender manuell mit meiner Papier-Version zu synchronisieren. Erfolglos.
Also habe ich mir auch einen PDA zugelegt, einen Palm. Als zentralen Terminkalender hatten wir seinerzeit Netscape Calendar im Einsatz. Die Synchronisation zwischen beiden hat wirklich hervorragend geklappt. Und auch der Netscape-Calendar war einfach zu benutzen.
Der Netscape-Calendar wurde irgendwann aber nicht mehr weiterentwickelt, PDA und Telefon wurden eins (nämlich Nokia 9300i) und ich habe durch Arbeitgeberwechsel serverseitig mit Microsoft Exchange/Outlook zu kämpfen.
Seitdem ist das Synchronisieren eine Katastrophe. Denn zuerst muss ich mal das Handy mit meinem Notebook verbinden. Und dann muss sich die ganze Geschichte noch mit dem Exchange-Server verbinden. Und das funktioniert bei mir leider nicht stabil. Jedes mal, wenn ich mich am Synchronisieren versuche, dauert es mind. ein paar Stunden, manchmal sogar Tage, bis ich es hinbekommen habe: Handy und Notebook wollen sich nicht mehr erkennen. Die Anmeldung am lokalen Outlook funktioniert nicht. Und dann ist der Exchange-Server nicht erreichbar. Und natürlich bekomme ich bei keinem der Probleme eine aussagelräftige Fehlermeldung.
Das führt natürlich dazu, dass ich mich vor dem Synchronisieren drücke und es nächstes mal noch viel länger dauert.
Auf der Suche nach einem Ausweg bin ich auf Google-Calendar und GooSync gestoßen. Google-Calendar ist wunderbar einfach zu benutzen (fairerweise muss ich sagen: der Outllok-Kalender ist so schlecht auch nicht, wenn man mal den richtigen der mehreren möglichen Kalender zu fassen hat). GooSync sorgt für die Synchronisation zwischen Handy und Google-Calendar. Es gibt eine kostenfreie Standardversion und eine Premium-Version, die ich mit 20 Pfund / Jahr durchaus erschwinglich finde. Die Installation ist sehr einfach (man bekommt einfach eine SMS auf's Handy geschickt und wenn man die speichert, ist alles installiert). Und meine ersten Synchronisationsversuche lassen sich auch ganz gut an.
Jetzt muss nur noch der Outlook-Kalender weg und ich wäre wieder in dem Terminparadies, aus dem ich vor ca. 5 Jahren vertrieben wurde: Sync starten und alles flutscht.
P.S.: Es gibt auch Software, die Outlook mit dem Google-Calendar synchronisiert. Die behebt mein Problem aber nicht wirklich. Die Anmeldung an Outlook und am Exchange-Server bringt immer noch Probleme ohne Ende.
Post bewerten
Dienstag, November 20, 2007
Freitag, November 09, 2007
13949712720901ForOSX
Details.
Post bewerten
Mittwoch, November 07, 2007
W-JAX: REST-Vortrag
Inzwischen gibt es den JSR-311 namens JAX-RS für ein standardisiertes API für REST, an dem Stefan Tilkov auch mitarbeitet. Der ist noch im Early-Draft-Stadium. Es sieht aber schon ganz nett aus.
Beim Vortrag habe ich denn auch ein Tool kennengelernt, dass wir bei unserem REST-Projekt auch benötigt hätten: curl. Mit dem Ding kann man HTTP über die Kommandozeile machen. Im Gegensatz um Browser kann man manuell den Header, die Methode (GET, POST, PUT, DELETE etc.) festlegt und auch den Body.
Post bewerten
Dienstag, Oktober 30, 2007
Sonntag, Oktober 07, 2007
W-JAX 2007
Gleich am Anfang des Agile Day halte ich zusammen mit meinem Kollegen Henning Wolf einen Vortrag über Festpreisverträge in agilen Projekten. Dieses Thema treibt uns ständig um. Auf der einen Seite ist klar, dass klassische Festpreiskonstellationen schlecht zu agilen Vorgehensweisen passen, weil sie unter anderem das Lernen "verbieten". Allerdings sind die Alternativen rar. Stattdessen Aufwandsprojekte vorzuschlagen, ist zu sehr aus der Perspektive der Entwickler argumentiert. Aber der Wurm muss dem Fisch schmecken und nicht dem Angler. Und das tut er bei Aufwandsprojekten in der Regel nicht. Denn der Auftraggeber verliert ein gutes Stück der Kontrolle über die Kosten-Nutzen-Relation seines Projektes. In dem Vortrag wird es also sehr stark um das gehen, was sich zwischen Festpreis und Aufwand abspielen kann.
Ich organisiere außerdem die Lightning Talks auf dem Agile Day. Im Gegensatz zu den Lightning Talks auf den XP-Days stehen auf der W-JAX die reinen Anfängerthemen nicht im Vordergrund.
Und wie bei den XP-Days gibt es es auch bei der W-JAX ein Speaker-Logo:
Post bewerten
XP-Days 2007
Für Einsteiger in die agile Softwareentwicklung liefern die Lightning Talks am 22.11.07 einen guten Überblick. Neben den Inhalten ist die Präsentationsstruktur sehr interessant: viele kurze Vorträge, die jeweils eine Aussage genau auf den Punkt bringen.
Am 23.11.07 werde ich dann etwas zu einem meiner Lieblingsthemen sagen: Einfachheit in Softwareprojekten.
Aber eigentlich schreibe ich diesen Blog-Eintrag nur, damit ich Gelegenheit habe, das coole XP-Days-Speaker-Logo zu verwenden, das mein Kollege Bernd Schiffer erstellt hat.
Post bewerten
Samstag, Oktober 06, 2007
Klassen und Methoden im Wandel
Wenn man eine Klasse sucht, kann man sie leicht anhand ihres Namens finden. Und wenn man dann das API der Klasse liest, ist gleich klar, was die Methoden tun. Insbesondere ist klar, ob eine Methode nur einen Wert liefert oder ob sie gefährlich den Objektzustand manipuliert.
In den letzten Jahren hat sich an verschiedenen Stellen ein deutlich anderer Programmierstil entwickelt. Der primäre Fokus hat sich gewandelt. Es geht nicht mehr primär darum, dass man das API einer Klasse leicht lesen und verstehen kann. Stattdessen soll der Klientencode möglichst gut lesbar sein.
Bei der Benennung von Unit-Tests findet sich eine zarte Andeutung in diese Richtung. Statt AuftragTest.testSummenberechnung findet man heute immer häufiger AuftragTest.berechnetSummeDerPositionen. Die zweite Variante lässt sich als Spezifikation lesen "Auftrag berechnet Summe der Positionen".
Noch deutlicher wird es, wenn man sich Behaviour Driven Development (BDD) ansieht.
Schließlich nutzen die Fluent Interfaces dieses Konzept auch außerhalb des Testens bzw. Spezifizierens für Produktivcode.
Aus
TimeInterval meetingTime = new TimeInterval(fiveOClock, sixOClock);
wird
TimeInterval meetingTime = fiveOClock.until(sixOClock);
Für viele Entwickler, die schon länger im Java- oder C++-Geschäft sind, sind diese fließenden Interfaces sehr gewöhnungsbedürftig. Allerdings wird eine Klasse viel häufiger eingesetzt als gelesen. Also scheint es nicht gerade abwegig, mehr Gewicht auf die Benutzbarkeit als die API-lesbarkeit zu legen.
Trotzdem wird man absehbar wohl nicht alle Klassen mit einem Fluent Interfaces versehen. Dazu ist der Aufwand zu groß. Aber bei den Klassen, die sehr häufig benutzt werden, sind Fluent Interfaces sicher eine Überlegung Wert.
Nachtrag: Ein Beispiel für ein Fluent Interface findet sich z.B. in Hibernate, wenn man eine Criteria zusammenbaut.
Post bewerten
Sonntag, September 30, 2007
Ideenfluss
Jetzt kommt anderes produzierendes Gewerbe an und sagt: "Die ITler sind ja immer ganz vorne mit dabei. Die machen Scrum. Wie können wir das bloß auf unsere Probleme übertragen?"
Dabei müssten sie doch nur gucken, was Toyota macht. Das sollte sich sich deutlich einfacher übertragen lassen. Aber vielleicht ist das zu langweilig?
Post bewerten
Agil: Wann was bewerten?
In diesem Sinne hatten wir interessante Diskussionen, die sich vor allem um die Frage drehte, wie man mit den Scrum-Sprints umgehen soll: Bei der Entwicklung eines Zuges hat man erst sehr spät den Zug und kann den nicht bereits am Anfang dem Kunden zeigen. Außerdem stand die Frage im Raum, wie man vom klassischen Vorgehen schrittweise in Richtung Scrum kommt. Dabei hat sich herauskristallisiert, dass es drei zusammenhängende Aspekte gibt, die man gemeinsam in Richtung Scrum entwickeln muss:
- Was wird präsentiert?
- Wem wird es präsentiert?
- Wann wird es präsentiert?
Klassisch hat man einen Projektplan mit Meilensteinen. Bezogen auf die o.g. Fragen gilt für das klassische Projektvorgehen:
- Was wird präsentiert? Immer unterschiedlich, je nach Meilenstein. Mal eine Konzeption, mal ein physikalisches Teil.
- Wem wird es präsentiert? Manchmal dem Kunden. Häufig gibt es aber gar keinen richtigen Kunden für das, was das präsentiert wird. Es sind nur interne Dokumente.
- Wann wird es präsentiert? In unregelmäßigen Abständen, jeweils wenn ein Artefakt fertig ist. Wenn es zum geplanten Zeitpunkt nicht fertig ist, wird der Termin häufig verschoben.
Scrum hingegen fordert:
- Was wird präsentiert? Das, was der Kunde später auch bekommt, wofür er bezahlt.
- Wem wird es präsentiert? Dem Kunden. Wenn es ein Serienprodukt für viele (vielleicht anonyme) Kunden ist, übernimmt ein Kundenvertreter (Produktverantwortlicher) die Kundenrolle.
- Wann wird präsentiert? In der Regel alle 2 bis 4 Wochen, aber auf jeden Fall in regelmäßigen Abständen (Timeboxing).
Wie kommt man jetzt von Meilensteinen zu Scrum? Der erste Schritt ist einfach: Man macht Punkt drei genauso wie Scrum es fordert: Man definiert einen festen Rythmus, in dem man den Projektfortschritt bewertet und ggf. die Pläne anpasst. Seine Meilensteine kann man erstmal parallel dazu bestehen lassen. Es ist jedoch das Ziel, die Meilensteine komplett zu ersetzen.
Und jetzt muss man sich für die Punkte eins und zwei schrittweise an Scrum annähern. Derjenige, dem präsentiert wird, muss dem Kunden immer ähnlicher werden und das, was präsentiert wird, muss dem immer ähnlicher werden, wofür der Kunde bezahlt.
Das wird im ersten Schritt häufig bedeuten, dass man intern einen Kundenvertreter benennt, der den Kunden vertritt - selbst dann, wenn es einen echten Kunden gibt. Wenn sich mit dem Kundenvertreter das Vorgehen intern eingespielt hat, lädt man den Kunden zu den Präsentationen mit ein. Und schließlich kommt der interne Kundenvertreter nicht mehr. im gleichen Zuge wie der interne Kundenvertreter durch den echten Kunden ersetzt wird, muss sich das Artefakt ändern, das präsentiert wird. Schließlich muss der Kunde auch bewerten können, was er präsentiert bekommt. Und hier ist es natürlich auch bei der Entwicklung physikalischer Dinge so, dass man sie in Einzelkomponenten zerlegen kann. Und diese Einzelkomponenten werden weitgehend unabhängig voneinander entwickelt und getestet. Einige Einzelkomponenten können also auch bereits lange vor Ende des Projektes präsentiert werden. Und dort wo es nicht geht, muss man Dinge finden, die der Kunde versteht: Prototypen, Konzepte und Präsentationen in der Sprache des Kunden etc.
Fazit 1: So anders ist die Entwicklung physikalischer Dinge auch wieder nicht.
Fazit 2: Das skizzierte Vorgehen funktioniert genauso gut für Softwareprojekte, die den Sprung ins kalte Scrum-Wasser scheuen und sich lieber schrittweise vorarbeiten wollen.
Post bewerten
Freitag, September 21, 2007
Power-Point bei Google
Von den Features her ist Zoho Show da deutlich weiter.
Post bewerten
Montag, Juli 16, 2007
Video-Podcast zu Hibernate
Post bewerten
Agile Werbefilme
Da sind schon ein paar interessante Filmchen dabei - der Lego-Film zum Build-Prozess ist übrigens von uns (namentlich von meinem Kollegen Andreas).
Post bewerten
XP-Day: Call for Sessions
Post bewerten
Montag, Juli 09, 2007
Oho Zoho
Mein Bruder Arne wusste aber Rat: Zoho bietet eine kostenlose Präsentationssoftware als Web-Anwendung, mit der man kooperativ auch Abbildungen erstellen kann. Und ich konnte sogar unsere bereits mit Power-Point begonnene Abbildung importieren.
Interessanterweise hat Zoho nicht nur einen Power-Point-Clone im Angebot, sondern auch noch einen Word-Clone, einen Excel-Clone, eine Planungssoftware mit ToDo-Listen und Kalender, ein Wiki, ein CRM-System etc (siehe http://www.zoho.com). Also deutlich mehr als z.B. Google zu bieten hat. Nach kurzem Draufgucken sah das ganze auch sehr passabel aus.
Aber es gibt leider einen Pferdefuß: Die Performance ist nicht ausreichend für professionellen Einsatz. Für den Power-Point-Clone kann ich damit leben, weil ich keine Alternative kenne. Aber bei den anderen Services nehme ich dann doch lieber andere Anbieter.
Aber vielleicht kriegen die Zoho-Leute die Performance-Probleme ja noch in den Griff.
Post bewerten
Dienstag, Juli 03, 2007
Freitag, Juni 29, 2007
Java zu komplex?
Und dann berichtet die Computerzeitung über einen Programmierwettbewerb namens Platforms, an dem unter anderem Teams in Java und PHP programmiert haben. Das Beste Team war ein Java-Team, aber die anderen beiden Java-Teams sind anscheinend an der Komplexität gescheitert. Die drei PHP-Teams hatten wohl durchweg gute Ergebnisse.
Das erinnert mich sehr an einen frühen Performancevergleich zwischen C++ und Java. Dort war das beste C++-Programm um Größenordnungen schneller als das beste Java-Programm. Allerdings waren die Java-Programme im Durchschnitt leicht schneller als die C++-Programme. Die Begründung ist einfach: Mit C++ konnte man viel performantere Programme schreiben als in Java. Allerdings muss man dafür soviel an Komplexität beherrschen, dass die meisten Entwickler mit C++ sehr langsame Programme geschrieben haben.
So hört es sich jetzt auch mit Java und PHP an: Mit Java kann man bessere Systeme schreiben als mit PHP. Allerdings können nur wenige Entwickler die Komplexität von Java so gut beherrschen, dass das auch gelingt.
Jetzt haben wir wahrscheinlich nur das Problem, dass alle Entwickler glauben, sie würden zu den wenigen gehören, die die Komplexität beherrschen. Die Statistik sagt aber was anderes. Die sagt: "Was auch immer Du denkst. Wahrscheinlich bist Du nicht in der Lage, die Komplexität zu beherrschen."
Daher mache ich hier mal den Anfang: Mich überfordert das ganze Zeugs rund um EJB, WSDL, SOAP, WS-*, JTA, JAAS, extends und super bei den Generics, geheimnisvolle Compilefehler rund ums Autoboxing, Abhängigkeitswirren bei Classloadern, etc. Natürlich kriege ich es letztlich dann doch ans Laufen. Aber die Zeit dafür würde ich lieber in die Entwicklung kundennützlicher Features investieren.
Post bewerten
Dämlicher Desktop
Interessanterweise hat Windows eine Eigenart, die mir das Arbeiten mit dem Desktop verleidet. Wenn man die Bildschirmauflösung verändert, schiebt Windows die Icons auf dem Desktop so zusammen, dass sie noch alle angezeigt werden können. Das ist vernünftig. Richtig dämlich ist aber, dass die Originalanordnung nicht wieder hergestellt wird, wenn man die Originalauflösung wieder herstellt. Die Anordnung der Icons müsste abhängig von der Bildschirmauflösung gespeichert werden. Wird sie aber anscheinend nicht. Und leider hat sich das auch mit Windows Vista nicht verbessert.
Wenn man einen Desktop-Rechner hat, ist das wahrscheinlich nicht so schlimm. Aber wenn man sein Notebook auch für Präsentationen nutzt, schaltet man ständig die Auflösungen um und hat dann den Ärger.
Auf dem Mac ist das bestimmt besser gelöst, oder?
Post bewerten
Dienstag, Juni 26, 2007
Lastenheft vs. User Stories
Diese höhere Bedeutung des Lastenheftes liegt vor allem an Kommunikationsproblemen zwischen Fachabteilungen und Softwareentwicklern. Die von den Softwareentwicklern geschriebenen Pflichtenhefte sind für Fachabteilungen größtenteils unverständlich und daher keine geeignete Basis für die Vereinbarung des zu entwickelnden Systems.
Genau dieses Kommunikationsproblem adressieren auch die agilen Methoden, aber mit anderen Mitteln als dem Lastenheft. Bei den agilen Methoden wird das statische Lastenheft quasi durch
einen Lastenheft-Generator ersetzt. Dieser Lastenhaft-Generator ist ein Mitarbeiter des Kundenund heißt ja nach gewählter Nomenklatur mal Kunde (XP) und mal Produktverantwortlicher (Scrum).
Dieser Produktverantwortliche hat die Aufgabe, jeweils soviele Anforderungen zu generieren, wie zur Zeit realisiert werden können. Er generiert das Lastenheft quasi während der Projektarbeit. Dabei wird auf persönliche Kommunikation zwischen Produktverantwortlichem und Entwicklern gesetzt, um Kommunikationsprobleme zu vermeiden.
Damit übertragen agile Vorgehensweisen die Prinzipien der Just-In-Time-Production auf die
Softwareentwicklung: Die Anforderungen sind genau in dem Moment definiert, in dem sie benötigt werden.
Die Vorteile dieser Vorgehensweise liegen auf der Hand: Es wird keine lange Vorlaufphase für
die Definition des Lastenhaftes benötigt. Man kann sofort mit der Softwareentwicklung beginnen, sobald der Bedarf entdeckt wurde. Der Produktverantwortliche kann auf veränderte Rahmenbedingungen sofort reagieren - er muss ja nicht massenhaft bereits definierte Anforderungen ändern. Die Kosten auf Kundenseite sinken, weil der Produktverantwortliche immer nur genau die Anforderungen definiert, die auch realisiert werden. Es wird kein Aufwand in die Definition von Anforderungen gesteckt, die dann doch nicht realisiert werden. Erste Versionen der Software kann der Produktverantwortliche begutachten, daraus lernen und die Generierung weiterer Anforderungen mit dem Gelernten abgleichen.
Allerdings ist diese agile Vorgehenweise nicht für alle Kunden sofort umsetzbar - genau so wenig, wie es der westlichen Industrie gelungen ist, Just-In-Time-Production vom einen Tag auf den nächsten umzusetzen. Die Problematik bei der agilen Softwareentwicklung liegt in der Rolle des Produktverantwortlichen. Es ist durchaus eine Herausforderung, die Anforderungen genau zeitgerecht (eben Just-In-Time) zu definieren. Generiert der Produktverantwortliche die Anforderungen zu langsam, hat das Entwicklerteam kostenpflichtigen Leerlauf oder muss mit undurchdachten Anforderungen arbeiten. Generiert der Produktverantwortliche die Anforderungen zu schnell, liegen sie auf Halde.
Je mehr Anforderungen auf Halde liegen, desto größer die Gefahr, dass ein Teil der Anforderungen gar nicht realisiert wird. In diesem Fall hat der Produktverantwortliche seine wertvolle Arbeitszeit umsonst investiert. Anforderungen auf Halde wären in der Nomenklatur der Just-In-Time-Production Verschwendung.
Die Definition und die Realisierung von Anforderungen im Fluss zu halten entspricht genau dem Flow-Gedanken aus dem Just-In-Time-Production. Die einzelnen Produktionseinheiten in eine Fabrik entsprechend einzustellen, heißt Production Leveling. Und genau diese Herausforderung besteht auch bei agilen Softwareprojekten.
Eine große Hürde ist dabei häufig die Organisationsstruktur des Kunden. Muss der Produktverantwortliche sehr viele Parteien einbeziehen, ohne dass es sehr klare Strukturen gibt, gleicht seine Aufgabe dem sprichwörtlichen Hüten von Flöhen. Es besteht ein hohes Risiko, dass ein ziemlich inkonsistentes System entsteht.
Tatsächlich mag in solchen Fällen das Lastenheft doch die bessere Variante sein. Das gilt
allerdings nur, wenn der Lastenheft-Autor auch ausreichend Zeit für all die Abstimmungen
zur Verfügung hat. Unter Zeitdruck erstellte Lastenhefte neigen zu undurchdachten Anforderungen. Da sie statisch festgeschrieben sind, ist der Kunde dann mit dem Lastenheft wiederum schlechter bedient als mit dem agilen Produktverantwortlichen.
Zwischen dem Produktverantwortlichen im Sinne von Scrum oder XP und dem klassischen Lastenheft gibt es aber auch Zwischenstufen. FDD liefert mit der vorgeschalteten gemeinsamen Modellierungsphase einen guten Ansatzpunkt. Das Projekt wird dabei in Abschnitte von maximal 6 Monaten unterteilt. Für jeweils einen solchen Abschnitt findet eine Upfront-Analyse/-Modellierung statt. Dadurch wird die Gefahr von Inkonsistenzen reduziert. Natürlich bezahlt man das, indem man nicht mehr so schnell auf neue Erkenntnisse reagieren kann, wie mit XP oder Scrum. Man ist aber immer noch schneller und leichtgewichtiger unterwegs als mit dem klassischen Lastenheft.
Post bewerten
Samstag, Juni 23, 2007
Donnerstag, Juni 21, 2007
XP-Day 2007
Post bewerten
Mittwoch, Juni 20, 2007
Thinkpad T60
Ich habe den größeren Akku und die kleinere, aber schneller Festplatte einbauen lassen. Im Sparsam-Betrieb reicht der Akku knapp 5 Stunden - so lange wie beide Akkus beim DELL zusammen.
Die Tastatur fühlt sich beim Thinkpad etwas besser an als beim DELL. An Hardwarefeatures fällt zunächst mal der Fingerabdrucksensor ein, mit dem man sich anmelden kann, nachdem man etwas trainiert hat, wie man den Finger richtig über den Sensor zieht. Nettes Feature. Es dauert aber Ewigkeiten, bis ich mich mit dem Ding auch anmelden kann - ich habe bis heute nicht verstanden, wie ich das gemacht habe. Schneller als die Eingabe des Passworts ist die Anmeldung mit dem Sensor allerdings nicht - dazu ist die Fingerabdruck-Erkennung zu langsam.
Auf dem Thinkpad ist Windows Vista installiert. Es braucht leider eine Weile zum Hochfahren (mehrere Minuten, 25 Sekunden aus dem Sleep-Mode). Von der Bedienbarkeit zeigt Vista aber dann einen deutlichen Fortschritt gegenüber Windows XP. Es sieht besser aus (wahrscheinlich ist das alles bei Apple angeguckt - immer noch besser also schlecht selbst ausgedacht).
Besonders nützlich ist, dass man überall Suchfelder hat, um nach Programmen, Dateien und Verzeichnissen zu suchen. Wenn man ungefähr weiß, was man sucht, tippt man das ein und muss sich nicht mehr durch Verzeichnisse oder Menüs klicken.
Etwas verwirrt war ich am Anfang, weil das System die fest eingebauten Verzeichnisse mal englisch und mal deutsch anzeigt. Im Dateisystem heißt es z.B. "Programme". Wenn man Software installiert, sagt die, sie würde sich nach "Program Files" installieren, sie landet aber unter "Programme".
Wenn man einen Verzeichnispfad ins Clipboard keopiert und in ein Textfeld einfügt, erscheint auch der englische Name. Anscheinend heißt alles englisch und der Explorer übersetzt.
Die Software, die ich bisher verwendet habe, läuft auch auf Vista. Nur bei Eclipse muss man tricksen. Bei Vista darf man nicht mehr ohne Bestätigung ins Programme-Verzeichnis schreiben. Daher muss man Eclipse beim Start explizit sagen, dass die Config-Dateien an einem anderen Ort abgelegt werden müssen und neue Plugins muss man auch an einen anderen Ort installieren. Oder man installiert Eclipse nicht im Programme-Verzeichnis. Muss man halt nur wissen.
Zusätzlich zu den automatischen Windows-Updates ist auf dme Gerät das "Lenovo Produktivitätscenter" installiert. Das lädt z.B. automatisch Aktualisierungen des BIOS etc. Das ist doch auch mal nett.
Dummerweise ist das Lenovo-Produktivitätscenter nicht ganz kompatibel mit Windows Vista. Daher erscheinen seine Benachrichtigungsfenter nicht auf dem Desktop, sondern in einem Extra-Modus, auf den Vista ständig hinweist, wenn sich im Hintergrund das Produktivitätscenter geöffnet hat. Nach kurzem Notebookbetrieb schlägt das Produktivitätscenter vor, ein dutzend Aktualisierungen nachzuladen. OK. Die ganze Geschichte bleibt nach ein paar Stunden bei 77% Fertigstellung stehen. Also boote ich den Rechner neu. Danach zeigt das Notebook beim Login nicht mehr die Option für den Fingerabdrucksensor an. Es dauert eine Weile bis ich bemerke, dass man sich immer noch per Fingerabdruck anmelden kann. Hin und wieder kommt auch noch der alte Anmeldebildschirm. Und hin und wieder gibt die Fingerabdruck-Software einen "internal error" und stürzt ganz am Anfang ab. So richtig ausgereift wirkt das noch nicht. Mit der Zeit ist das Problem aber immer seltener aufgetreten.
Ich installiere die Software für die UMTS-PC-Karte. Im Internet bei Vodafone gibt es extra eine Version für Vista. Nach der Installation klappt mit der Karte auch alles super. Dafür gehen LAN und WLAN nicht mehr. Vista zeigt mit abwechselnd "lokaler Zugriff" und "eingechränkte Konnektivität für die beiden Netzwerk-Adapter an. Die Ursache scheint zu sein, dass ich jetzt mit "Nicht identifiziertes Netzwerk"
verbunden bin. Ich probiere der Reihe nach alle Problemlösungen aus, die Vista mir vorschlägt. Alles ohne Erfolg. Jetzt schlängt Vista mir vor, ONLINE nach einer Lösung zu suchen. Pfiffig...
Also deinstalliere ich das Vodafone-Zeug. Jetzt habe ich einen absolut sicheren Rechner. Ich kann mich mit gar nichts mehr verbinden :-(
Nach stundenlangem rumprobieren und mehrfachen Neustart meines Routers geht alles wieder. Ich installiere die Software für die UMTS-Karte. Es scheint immer noch alles zu funktionieren.
Ich fahre auf die JAX und bin wahrscheinlich der einzige Teilnehmer, der nicht ins dortige WLAN kommt. Woran es liegt, kann ich mit Windows Vista nicht herauskriegen. Der Rechner verbindet sich zwar mit dem WLAN, vom Internet kann ich aber nichts sehen. Also benutze ich halt die UMTS-Karte. Das WLAN im Hotel hingegen funktioniert.
Als ich wieder zu Hause ankomme, geht weder WLAN noch LAN - auch nicht nach mehrfachem Neustart von Rechner und Router. Ich bin echt genervt. Windows meint, dass wahrscheinlich LAN- und WLAN-Netzwerkadapter kaputt sind.
Ich suche bei Lenovo im Internet. Man soll beim Systemstart F11 drücken. Dann kommt ein Diagnose-Programm. Dort soll man "Hardwarediagnoe" auswählen. Den Punkt gibt es aber nicht, auch sonst nichts, was mir weiterhilft.
Also ermittle ich die Telefonnummer für den Support und stelle fest, dass der
in Deutschland nur Mo.-Fr. 8-16 Uhr besetzt ist. Die Franzosen haben es besser
mit 24*7-Support. Aber ich spreche kein französisch. Naja, man kann auch in
den USA anrufen. Da ist auch immer jemand da. Da habe ich aber keinen Nerv drauf. Also deinstalliere ich nochmal die Vodafone-Software und schon funktioniert es wieder. Scheint also doch an der Vodafone-Software zu liegen. Ich werde mal deren Support anrufen.
Auch ohne Vodafone-Software schaltet sich ab und an das WLAN des Notebooks ab. Keine Ahnung warum.
Fazit: Das Thinkpad ist leicht besser als mein alter Dell. Vista ist leicht besser als Windows XP. Richtig begeistern kann ich mich aber für beides nicht.
Post bewerten
Freitag, Juni 15, 2007
FDD-Reisebericht: Features beschreiben und organisieren
Interessant ist, dass FDD ein festes Beschreibungsschema für Features hat:
<Aktion> <Ergebnis> <Objekt>
So entsteht ein einfacher Satz wie "Berechne Summe der Auftragspositionen".
Damit man in großen Projekten die Übersicht nicht verliert, werden Features zu Feature-Sets zusammengestellt. Dabei empfiehlt sich eine feste Richtlinie, wie Feature-Sets gebildet werden. FDD schlägt für Geschäftsanwendungen vor, Feature-Sets nach Geschäftstätigkeiten zu bilden, z.B. "Auftragsannahme".
Hat man es mit sehr vielen Feature-Sets zu tun, werden diese wiederum in Major Feature-Sets gruppiert, wieder nach einer festen Richtlinie. FDD schlägt für Geschäftsanwendungen vor, Major Feature-Sets nach Geschäftsbereichen zu organisieren, z.B. "Einkauf".
In meinem aktuellen Projekt haben wir die Anforderungen auf das FDD-Schema umgestellt und damit einige positive Erfahrungen gemacht:
- Wir verwalten unsere Anforderungen in einem Issue-Tracker (Mantis). Der FDD-Satz bildet die Zusammenfassung der Anforderung. Dadurch sind i.d.R. die Zusammenfassungen in einer Übersichtsliste so aussagekräftig, dass man in Diskussionen die Details gar nicht mehr braucht. Früher sind wir mit der Übersichtsliste der Anforderungen und dem Ausdruck der Details zu jeder Anforderung in Abstimmungsmeetings gegangen. Heute haben wir nur noch die Übersichtsliste dabei. Es ist alles viel übersichtlicher geworden.
- Durch die Feature-Beschreibungsform fällt leicht auf, wenn man versehentlich mehere Dinge in einer Anforderung zusammengeworfen hat. Man trennt Anforderungen eher auf und das Risiko sinkt, dass man was Wichtiges übersieht (versteckte Features).
- Durch das Feature-Beschreibungsschema sind unsere Features kleiner geworden. Insbesondere haben wir keine Features mehr, die sehr groß sind. Das ist besonders wichtig, weil wir gerade die großen Anforderungen immer wieder gnadenlos unterschätzt haben.
- Wenn Anwender / Kunden Anforderungen beschreiben, passen die Beschreibungen in der Regel nicht ins FDD-Schema und in den Details finden sich häufig auch mehrere Anforderungen. Wir formen die Anforderungen dann in die FDD-Form um.
- Die Gruppierung in Feature-Sets ist für das Tracking mit Parking-Log-Diagrammen sehr nützlich. In Mantis setzen wir die Kategorien als Feature-Sets ein und verwenden als Richtlinie Feature-Set=Geschäftstätigkeit.
- Major-Feature-Sets bilden wir in Mantis als eigene Projekte an.
Post bewerten
Mittwoch, Juni 13, 2007
FDD-Reisebericht: Parking-Lot-Diagramme
In einem Parking-Lot-Diagramm bekommt jeder Anforderungsbereich (Feature-Set) ein Rechteck, das Auskunft über die Verantwortlichkeit, die Menge der zugehörigen Features, den Fortschritt und den geplanten Fertigstellungstermin enthält.

Über die aus Scrum stammenden Feature-Burndown-Diagramme hinaus sind Parking-Lot-Diagramme gut geeignet, um den Status großer Projekte zu visualisieren.

Ein interessanter Aspekt in FDD ist, dass für die Parking-Lot-Diagramme nur die Anzahl der Features gezählt wird ohne Gewichtung. Man geht davon aus, dass die Unterschiede in den einzelnen Featureaufwänden nicht so riesig sind und sich im Mittel ausgleichen.
Ich setze in meinem aktuellen Projekt Parking-Lot-Diagramme zusätzlich zu Feature-Burndowns ein und habe damit gute Resultate erzielt.
Post bewerten
Dienstag, Juni 12, 2007
SEE 2007: eine andere Welt
Irgendwie war ich selbst als Vortragender zur Geschichte der agilen Methoden auf die Konferenz geraten. Der Vortrag war gut besucht und meine kleine Umfrage am Anfang ergab, dass ca. 95% der Teilnehmer xUnit benutzt, ca. 90% XP kennen und ca. 70% Scrum. Am Ende des Vortrags hatten wir eine angeregte, aber keine kontroverse Diskussion - ich hatte das anders erwartet.
Am Ende gab es dann noch eine Podiumsdiskussion über reichhaltige (cooler Marketinggag das Wording, Respekt) vs. agile Vorgehensweisen. Das Podium war mit 5 Klassikern und Christian Weiss von oose als Agilisten besetzt. Christian Weiss hat darüber im Blog von Bernd Oesterreich berichtet.
Dort schreibt er:
Mir fiel es jedenfalls schwer, Sinn und Zweck von Agilität überzeugend zu verdeutlichen. Vielleicht liegt hier aber auch das eigentliche Problem: Mein Eindruck war, dass beide Fraktionen im Grunde ihres Herzens dieselben Ziele verfolgen.
Letzteres glaube ich nicht so recht, denn: Auf der Podiumsdiskussion gab es eine kurze Phase, in der sich reichhaltig und agil anzunähernd drohten. Das hat der Moderator glücklicherweise unterbunden. Glücklicherweise, weil es nicht darum geht, ob man alle 3 Monate ein Stück Software ausliefert oder ob man auch in agilen Projekten Dokumentation schreibt (wenn es einen Sponsor dafür gibt). Es geht um die Geisteshaltung bei der Softwareentwicklung und um die Perspektive auf Kundenwert, Verschwendung (Lean, Kaizen), Verantwortung, Ehrlichkeit, Menschen und Teams. Und diese Sichtweisen scheinen mir mind. bei den Podiumsteilnehmern (ausgenommen Christian Weiss) gänzlich anders zu sein, als sie in agilen Projekten gelebt werden.
Ich kann mir aber durchaus vorstellen, dass ein Teil der Konferenzzeilnehmer wirklich gerne agil vorgehen würde und nur nicht so recht weiß, wie. Das habe ich jedenfalls aus einigen Diskussionen mitgenommen.
In diesem Sinne arbeiten wir weiterhin daran, Möglichkeiten zu finden, wie man agil vorgehen kann, auch wenn man nach außen nach V-Modell aussehen muss - V-Modell XS.
Post bewerten
Mittwoch, Mai 30, 2007
Verschlüsselung für GMail und Konsorten...
Mal sehen, was aus dem Service noch so wird. Natürlich sind noch eine Reihe von Fragen ungeklärt, aber der Service steckt noch in den Kinderschuhen und kann die fehlenden Antworten noch liefern.
Post bewerten
Dienstag, Mai 22, 2007
Flashfilm zum Build-Prozess
Post bewerten
positive Kritik zu unserem Hibernate-Buch...
Post bewerten
Mopore-Togo
Ich habe nachgefragt und das verwendete Tool heißt Mopore-Togo und ist Open-Source.
Interessant ist noch, dass das Tool in Java 6 geschrieben ist. Es zeigt sehr schön, dass es mit Java nach ca. 10 Jahren doch noch möglich wird, Software zu schreiben, die sich native anfühlt.
Post bewerten
Sonntag, Mai 06, 2007
Feature-Driven-Development: Reiseberichte
Ich werde meine Erkenntnisse und Einsichten, die ich bei meiner Reise ins FDD-Land gewonnen habe, hier in loser Abfolge veröffentlichen. Stay tuned!
Wer sich nicht gedulden kann, dem kann ich das Buch A Practical Guide to the Feature-Driven Development von Stephen R. Palmer und John M. Felsing uneingeschränkt empfehlen.
Post bewerten
Freitag, Mai 04, 2007
Buchkritik zu "Refactoring in Large Software Projects"
Dazu gibt es jetzt auch Kritiken: hier und hier.
Post bewerten
Dienstag, Mai 01, 2007
Grails-Buch schon da: auf dem Poster -)
Ja, es ist wahr: Bernd Schiffer und ich schreiben zusammen an einem Buch über Grails, dass bei Addison-Wesley erscheinen wird. Nicht ganz richtig ist, dass man in Kürze mit dem Erscheinen des Buches rechnen kann - obwohl Amazon den Mai als Erscheinungsdatum nennt und auf der JAX letzte Woche das abgebildete Poster aushing.
Tatsächlich soll der Buch mit Grails 1.0 fertig werden. Es ist also noch etwas Zeit.
Post bewerten
Montag, April 23, 2007
Live-Blogging von der JAX
Post bewerten
Dienstag, April 17, 2007
Javas Argumente für dynamische Programmiersprachen
List<vertrag> vertraege = ...
Aber dann wird es ganz schnell kompliziert, weil Generics mit Subtypen inkompatibel sind:
List<Vertrag> vertraege = new List<Bausparvertrag>(); // Compile-Fehler
Und Ruckzuck ist man bei Wildcards:
List <? extends Vertrag> ...
List <? super Bausparvertrag> ...
void <T> foo(List<T extends Vertrag> x) ...
Das scheint mir in der Praxis sehr schwer beherrschbar zu sein. Es sind einfach zuwenig Entwickler fundiert in Typtheorie ausgebildet :-)
Interessant dabei ist, dass dieser ganze komplizierte Overhead nur dazu ist, den Compiler zufrieden zu stellen. Mit dynamischen Programmiersprachen kann man das alles viel einfacher haben.
Wer sich mit Generics in Java befassen will oder muss, findet hier eine gute Einführung.
Post bewerten
Montag, März 19, 2007
Scrum ist nicht Agil?
Scrum biete agiles Management. Man bräuchte aber auch aktive Kundeneinbindung, iteratives Vorgehen (inkl. Incremental Design) und selbstorganisierende Teams. Das ist alles auch mit Scrum möglich, aber Scrum gibt keine konkreten Hinweise, was jeweils zu tun ist.
XP deckt immerhin noch das iterative Vorgehen / inkrementelles Design ab.
Für die aktive Kundeneinbindung und die selbstorganisierenden Teams scheint aber noch was zu fehlen.
Post bewerten
Transaktionslose Anwendungsentwicklung
Daher halte ich es auch für sehr schade, dass sich in breiten Kreisen die Ansicht durchgesetzt hat, dass man auf jeden Fall verteilte Transaktionen braucht, wenn man mehrere Datenbanken oder zu integrierende Systeme hat.
Dass das keineswegs so ist, beschreibt Martin Fowler am Beispiel eBay.
Post bewerten
Montag, März 12, 2007
Die Mächtigkeit der Gleichförmigkeit
Gilt diese Aussage generell für Cobol-Systeme?
Nein, definitiv nicht. Ich habe auch einige Cobol-Systeme gesehen, die deutlich schlechter strukturiert waren als viele Java-Systeme.
Liegt es daran, dass an die Java-Systeme viel höhere Anforderungen gestellt wurden also an die Cobol-Systeme?
Nein. Viele der Java-Systeme unterschieden sich nur dadurch von den Cobol-Systemen, dass sie eine grafische Benutzungsoberfläche mit Swing hatten. Und die ist in Java eher leichter zu programmieren als in Cobol alles von Hand für zeichenbasierte Oberflächen zu codieren. Und selbst wenn Swing die Sache erschwert hätte, hätte das nur Auswirkungen auf die oberflächennahen Teile des Systems haben dürfen und nicht auf die Gesamtstruktur.
Liegt es daran, dass das Cobol-System besonders klein und übersichtlich war?
Nein. Es handelte sich um eine komplette Warenwirtschaft mit Lagerverwaltung und Produktion. Das System ist von ca. 10 Leuten über 10 Jahre lang weiterentwickelt worden.
Liegt es daran, dass am Cobol-System besonders gut ausgebildete Entwickler gearbeitet haben?
Nein. Es gab kaum ausgebildete Informatiker im Team. Einer der Entwickler war vorher Koch und ein anderer Steuerfachgehilfe.
Woran lag es denn dann?
Das System hatte eine einfache Musterarchitektur, die sich durch das ganze System zog. Stammdatenprogramme, Dialog-Programme, Auswahl-Dialoge, Batch-Programme, Druck-Jobs wurden nach dem immer gleichen Schema entwickelt, dass über die Jahre entstanden ist.
Damit war jedem Entwickler bei einer neuen Anforderung sofort klar, wo welche Änderungen notwendig waren und auch, wie teuer diese werden würden. Schätzungen, die stark von den tatsächlichen Aufwänden abwichen, habe ich im Projekt nie erlebt.
Dabei sind natürlich unglaublich viele Redundanzen entstanden. Wenn man ein neues Stammdatenprogramm schreiben wollte, hat man sich ein existierendes Stammdatenprogramm geschnappt und dieses angepasst. Das war Wiederverwendung durch Copy&Paste in Reinkultur.
Und trotzdem hat es funktioniert. Dabei sind sich alle einig, dass das eigentlich unmöglich ist.
Ich glaube, der Grund ist in der Gleichförmigkeit zu suchen, die das System hatte. Redundanzen sind gar nicht so schlimm, wenn sie jedem klar sind. Wenn ich für das Hinzufügen eines Feldes 100 Stellen anpassen muss, ist das halb so wild, wenn mir
- klar ist, wo ich die 100 Stellen im Code finde und
- jede Änderung mechanisch durchführbar ist, gerade wg. der Gleichförmigkeit des Codes.
Für diese Änderungen ist neben der Gleichförmigkeit eine andere Eigenschaft wichtig: Minimale Abhängigkeiten. Wenn niemand von den geänderten Code-Stellen abhängt, besteht nur geringe Gefahr, durch die Änderungen etwas kaputt zu machen. Außerdem gibt es das Risiko des Ripple-Effekts nichts: Die Änderung bringt weitere Änderungen in abhängigen Code nach sich, die wieder Änderungen in abhängigem Code nach sich ziehen...
Das führt mich zu der These, dass die bessere Cobol-Struktur sich an nur einer Eigenschaft festmacht: Es gab in dem Cobol-System weniger und klarer definierte Abhängigkeiten als in vielen Java-Systemen.
Diese Eigenschaft hat man sich erkauft durch Redundanzen (geht in Cobol auch nicht wirklich anders). Offensichtlich konnte man mit den Redundanzen aufgrund der Gleichförmigkeit besser umgehen als mit Java-Strukturen, die weniger Redundanzen aber dafür größere Abhängigkeiten aufweisen.
Sollten wir also zu Cobol zurück? Auf gar keinen Fall!
Wir sollten uns aber bewusster werden, wie gefährlich Abhängigkeiten zwischen Systemteilen werden können und wie leicht man sich in OO-Programmiersprachen unentwirrbare Abhängigkeitsgeflechte schafft. Vielleicht sollten wir eher einmal gleichförmige Redundanzen zulassen, um damit Abhängigkeiten zu reduzieren?
Post bewerten
Sonntag, März 11, 2007
Zweite Auflage des Hibernate-Buches erschienen

Neben ein paar kleineren Verbesserungen haben wir das Buch auf Hibernate 3.2 aktualisiert, das Java Persistence API (EJB 3) ergänzt und die Integration von Hibernate in Spring beschrieben.
Post bewerten
Dienstag, März 06, 2007
Buchtipp: Practical Common Lisp
Das Buch gehört zu den sehr wenigen IT-Büchern, bei denen das Lesen Spaß macht.
Auch wenn man selbst nicht mit Common Lisp arbeiten wird, öffnet das Buch ganz neue Perspektiven. Es ist schon erstaunlich, wie weit Common Lisp seiner Zeit voraus war und noch ist. Ich kenne keine andere Programmiersprache, die so mächtige Features hat wie Common Lisp.
Das Macro-System (nicht zu vergleichen mit dem C-Macros) erlaubt die Definition eigener Sprachen in Common Lisp - ein Ansatz, der heute als DSL (Domain Specific Language) bekannt ist und mit vergleichsweise wahnsinnig hohem Aufwand und Code-Generierung betrieben wird.
So kann man eigentlich bei jedem Feature anderer Programmiersprachen sagen: "Das hat Common Lisp auch, nur mächtiger und flexibler." Da stimmt es mich schon etwas traurig, dass sich Common Lisp nicht in der Breite durchgesetzt hat und man heute noch mit vergleichsweisen Krücken unterwegs ist.
Da drängt sich natürlich die Frage auf, warum wir dann nicht einfach alle in Common Lisp programmieren. Eine Antwort gibt Paul Graham.
Dem habe ich noch hinzuzufügen, dass Common Lisp zwar unbestreitbar sehr mächtig ist, aber auf eigenartige Weise etwas schief zusammengesetzt wirkt. Das ist aber kein wirklich starkes Argument, weil mit Scheme und NewLisp weitere Lisp-Dialekte zur Verfügung stehen.
Post bewerten
Freitag, Februar 23, 2007
Groovy: Wie aus Skripten Programme werden
Dabei werden auch einige Highlights von Groovy angesprochen wir Groovy-Beans, Categories, Swing-Builder etc. Besonders schön finde ich, dass durch das Beispiel sehr deutlich wird, wo in Praxis der Nutzen dieser Features liegt.
Post bewerten
Mittwoch, Februar 21, 2007
Lieber bewährt als Leading-Edge
Diesen Ausspruch finde ich wirklich super. Insbesondere in der IT sind wir allzu schnell dabei, jedem Hype und jeder neuen Technologie hinterher zu rennen. Meine persönliche Schlüsselerfahrung dazu ist: Das uralte Cobol-System, an dem ich als Student gearbeitet habe, war deutlich besser strukturiert als die meisten C++- und Java-Systeme, die mir in den 12 Jahren danach über den Weg gelaufen sind.
Post bewerten
Sonntag, Februar 18, 2007
Quasar: gute Sache
Quasar funktioniert damit auch, wenn man agil vorgeht und inkrementellen Entwurf praktiziert - was eher nicht im Sinne der Quasar-Macher war :-)
Ein gutes Buch zum Thema ist "Moderne Software-Architektur. Umsichtig planen, robust bauen mit Quasar." von Johannes Siedersleben.
Post bewerten
REST für Geschäftsanwendungen
Eine interessante Frage ist jetzt natürlich, ob REST genausogut für nichttriviale Geschäftsanwendungen funktioniert. Dazu ist im Internet bisher nicht allzu viel zu finden.
Hier gibt es immerhin ein Gedankenexperiment mit klarem Ausgang dazu.
Wenn irgendjemand selbst Erfahrungen mit REST für Geschäftsanwendungen hat oder Referenzen kennt, würde ich mich über Rückmeldungen dazu freuen.
Post bewerten
Samstag, Februar 17, 2007
Die Wahrheit über SOA...
Am schönsten finde ich: "SOA is not complex. You are just dumb."
Und außerdem ist die Aussage so schön universell. Die funktioniert auch für EJB, verteilte Transaktionen, Web-Services (WS-*) etc.
Post bewerten
Mittwoch, Februar 14, 2007
Die agile Chance
Neben drei Vorträgen zum Thema gibt es Raum für Diskussionen zum Thema. Mehr Informationen gibt es hier.
Post bewerten
Freitag, Februar 09, 2007
Behindern Unittests inkrementellen Entwurf?
"Wenn ich mich bei Unittests sehr stark am Softwaredesign orientiere, was nach meinem Verständnis die klassischen xUnit-Tests machen, dann habe ich das Problem bei Strukturänderungen den Test nachziehen zu müssen.
Wenn ich mich im Unittest an der übergeordneten Funktion orientiere, bekomme ich Schwierigkeiten mit der geforderten Testüberdeckung.
Die XP-Welt propagiert gleichzeitig den Einsatz von Unit-Tests und einer laufenden Weiterentwicklung im Design. Wie passt das zusammen?"
Diese Frage fand ich so interessant, dass ich meine Gedanken dazu mal in einem Whitepaper zusammengeschrieben habe.
Post bewerten
Dienstag, Februar 06, 2007
Training zu Feature-Driven-Development in Hamburg
- Feature-Driven-Development eine ganz andere Perspektive einnimmt als die anderen agilen Methoden wie XP oder Scrum.
- Trainings zu FDD in Deutschland eine echte Rarität sind.
- Jeff FDD (mit)erfunden hat.
Post bewerten
Samstag, Februar 03, 2007
Lean Fast Food
- Produktion des Essens auf Vorrat (Push-Prinzip).
- Produktion des Essens bei Bedarf (Pull-Prinzip).

Seit einigen Jahren gibt es eine Verbesserung bei Kategorie 2: Man muss nicht mehr lange warten. Ein typischer Vertreter ist Subway. Während McDonalds und Konsorten mehrere Kassen nebeneinander am Tresen haben, schleust Subway die Kunden in einer Schlange am Tresen vorbei. Das Subway-Prinzip läuft darauf hinaus, dass man sein Sandwich während des ganzen Entstehungsprozesses begleitet und mit ihm der Kasse immer näher kommt. Dieses Vorgehen hat zwei positive Effekte:
- Man kann mehrfach zwischendurch noch Einfluss nehmen auf sein Sandwich (z.B. welches Brot, welche Salatanteile, welche Soße).
- Man kommt sehr schnell dran und ist dann beschäftigt. Möglicherweise wartet man länger auf sein Essen als bei McDonalds. Es fühlt sich aber kürzer an.

Die Produktionsweise bei McDonalds könnte man als klassisch bezeichnen, die von Subway als Lean. Und man kann eine wichtige Konsequenz für die Kunden agiler (lean) Softwareentwicklung ableiten: Man muss sich den ganzen Entwicklungsprozess über engagieren. Dadurch hat man mehr Einflussmöglichkeiten, muss sich aber eben auch einbringen.
Post bewerten
Dienstag, Januar 30, 2007
Lisp vs. XML
Interessanterweise stören sich dieselben Leute aber nicht an XML. Oder wollen die allen Ernstes behaupten, dieser XML-Code
<html>
<body>
<h1>Eine Überschrift</h1>
<p>Findest Du mich zwischen all dem XML?</p>
</body>
</html>
sei besser lesbar als seine Entsprechung in Lisp
(html
(body
(h1 "Eine Überschrift")
(p "Ich bin ganz leicht zu finden!")))
?
(Für die Erbsenzähler: Der XML-Code benötigt 50% mehr Zeilen und 30% mehr Tastenanschläge - ohne Einrückungen).
Tse, tse...
Post bewerten
Montag, Januar 29, 2007
Warum ich integrierten Lösungen misstraue
Ich fragte mich:
- Was ist allen diesen Lösungen gemeinsam?
- Ist dieses gemeinsame Merkmal der Grund für mein Misstrauen?
- Ist mein pauschales Misstrauen wirklich gerechtfertigt oder bin ich meinen eigenen diffusen Vorurteilen erlegen?
zu 1) Die Gemeinsamkeit der Lösungen liegt in der Integration. Die Lösungen werden damit, besonders gut oder weitgehend integriert zu sein. Das trifft z.B. auf EJBs zu, die verteilte Methodenaufrufe,Transaktionshandling und Security integrieren. Es trifft auf immer mehr Application-Server zu, die sichnicht auf die reine JEE-Technologie beschränken, sondern zusätzlich ESBs (Enterprise-Service-Bus), BPEL, SOAPetc. unterstützen und mit JEE integrieren. Und es trifft auf fast alle kommerziellen Tools zu, die z.B. direkteinen bestimmten Application-Server integrieren.
zu 2) Ja, ich gestehe: Das was die Hersteller als großen Vorteil ihrer Lösung herausstellen, bereitet mirein diffuses Unbehagen.
zu 3) Was also könnte ich - unterbewusst - gegen Integration haben? Integrierte Lösungen nehmen mir dochArbeit ab. Integration hat je nach Geschmacksrichtung unabdingbare die alles andere als wünschenswert sind:Die erste Geschmacksrichtung gibt den monolithischen Lösungen einfach einen neuen Namen, nämlich "integrierteLösung". Bei der zweiten Geschmacksrichtung besteht die Gesamtlösung aus verschiedenen Teilen, die integriertsind. "integriert" bedeutet, dass es mind. eine Abhängigkeit zwischen den Einzelteilen geben muss.
Integrierte Lösungen beider Geschmacksrichtungen führen dazu, dass man die Lösung mehr oder weniger komplett verwenden muss. Auf jeden Fall ist es schwierig, für einen Aspekt der Gesamtlösung eine alternative Einzellösungeinzusetzen. Das ist für kleine Projekte vielleicht noch akzeptabel, für große Projekte ist es eine Katastrophe:Man bindet sich im Grunde für alle Zeit an die Gesamtlösung und hat keine Chance, von neue Entwicklungen am Marktzu profitieren.
Darf man also keine Lösungen einsetzen, die sich "integriert" nennen? Doch, indem man sie deintegriert! Dazu teiltman ein großes Projekt in einzelne Subsysteme auf, die technologisch lose gekoppelt sind. Lose Kopplung bedeutet hier, dass sich die verwendeten Technologien innerhalb eines Subsystems austauschen lassen, ohne dass Änderungenan anderen Subsystemen notwendig werden.
Konkret kann man eine solche technologisch lose Kopplung leicht durch gängige Kopplungstechnologien wie REST,XML-RPC, JSON-RPC oder SOAP erreichen. Dann spielt es für die Kopplung keine Rolle, ob die einzelnen Subsystemeintern EJBs, Hibernate oder Spring verwenden und ob als Programmiersprache Java, Ruby, Cobol oder sonstwas eingesetzt wird.
Post bewerten
Dienstag, Januar 02, 2007
3 Dinge über mich
- Als Schüler habe ich 2 Wochen lang in der Tischlerei meines Vaters gearbeitet (Kunststoff-Fenster zusammenbauen). Wahrscheinlich hat diese Erfahrung den Ausschlag dafür gegeben, dass ich mein Abi doch noch geschafft habe und studieren konnte. Denn: Nach den 2 Wochen war für mich vollkommen klar, dass ich ich nicht einen Tag länger Kunststoff-Fenster zusammenbauen will. Natürlich ist die Arbeit eines ausgebildeten Tischlers abwechslungsreicher, aber das war mir damals nicht klar.
- Ich habe als Schüler zusammen mit Henning angefangen, einen Oberon-Compiler zu programmieren - in Modula-2. Wir haben immerhin den Parser hinbekommen, aber dann waren die Schulferien zu Ende. Interessant, wie man dazu neigt, unsinnges Zeug zu bauen. Gerade der Parser ist der einfache Teil, den man sich schon damals eigentlich aus der Grammatik-Beschreibung generieren ließ.
- Als wir vor 5 Jahren unser Haus bauten, mussten wir beim Urlaub sparen. Daher haben Silke und ich uns gegenseitig mit einem preisgünstigen Ein-Wochen-Urlaub in Deutschland überrascht. Sie führte mich nach Usedom, ich sie nach Fehmarn. Auf Fehmarn gehörte ein Surfkurs zum Urlaub dazu. Anfänglich stand unsere junge Ehe etwas auf der Kippe, weil es - trotz August - bei 13 Grad stürmte und Silke auf gar keinen Fall in die "algige" Ostsee wollte. Trotzdem haben wir den Kurs gemacht und sind seitdem Windsurf-addicted. Schon skurril, dass ein Spar-Versuch dazu führt, dass man bei einem so teuren Hobby landet.
Und jetzt muss ich drei neue Opfer benennen, die etwas über sich veröffentlichen, was keiner weiß: Kai, Bernd und Arne.
Post bewerten






