Ab und zu besuche ich mit meinem Kleinen einen Indoor-Spiellpatz. Vor einiger Zeit war es die Jolo Berlin Kinderwelt.

Jolo befindet sich in Kreuzberg nahe Flughafen Tempelhof und hat einen Kunden-Parkplatz (kostenpflichtig), ist aber auch gut mit der U-Bahn zu erreichen. Der Eingang befindet sich im ersten Stock. Die Preise sind OK.

Der Kleinkinderbereich, der uns interessiert hat, ist durchaus großzügig ausgestattet: Ballpool, kleine Rutsche, Hüpfbälle, Wippe, Bobby-Cars, ein kleines Haus, eine Art Kriechtunnel und kleinere Spielsachen. Eine Hüpfburg steht auch im Bereich. Ebenfalls in der Nähe sind einige Computer-Bildschirme, an denen die Kinder Spiele wie Memory spielen oder malen können.

Die Einrichtung ist sauber, wir fühlten uns wohl. Zwei Stunden Spielzeit waren schnell vorbei. Hier kommen wir gerne noch mal her.

Kürzlich wurde Version 2.0 von JAMon veröffentlicht. JAMon ist eine kleine, für Java-Anwendungen nützliche Monitoring-Bibliothek.

In Version 1 gab es die Möglichkeit, Ausführungszeiten von Code programmatisch zu messen:

  1. Monitor m = MonitorFactory.start("berechnung");
  2. BerechnungsModul.berechne();
  3. m.stop();

misst die Ausführungszeit der berechne-Methode. Das interessante hierbei ist

  1. Statistiken werden über die Ausführungszeiten (genauer: Ausführungsdauer) erstellt (Summe, Mittelwert, Standardabweichung und sogar Einteilung in bestimmte Klassen),
  2. Ausführungszeiten werden Namen gegeben (hier „berechnung“) und
  3. Die Statistiken können als HTML-Report ausgegeben (programmatisch oder per JSP).

Damit ist schon viel getan, u.a.:

  • in Webanwendungen kann ich einen Servletfilter erstellen, der die Ausführungsdauer aller (oder nur bestimmter) Aufrufe misst (dies hat bei geringem Aufwand großen Nutzen),
  • Aufrufe an „externe Systeme“ (z.B. Datenbank, Web-Services oder Betriebssystem) können gemessen werden
  • anhand der Messergebnisse kann der Entwickler abschätzen, ob eine Optimierung notwendig ist
  • anhand der Messergebnisse (z.B. im Vergleich zum Vortag) kann der Betrieb abschätzen, ob sich das System derzeit aussergewöhnlich verhält.

In Version 2 (ein komplettes Redesign) kommt hinzu, dass ich nicht nur Zeiten messen kann, sondern beliebige Einheiten. Ich kann z.B. eine Statistik über die Trefferzahl einer Suche führen:

  1. int treffer = Suche.ausfuehren(...)
  2. MonitorFactory.add("treffer","anzahl",treffer);

fügt die Trefferzahl dem Statistikeintrag „treffer“, die in der Einheit „anzahl“ gemessen wird, zu. Bisher habe ich nur noch nicht herausgefunden, wie man Klassen (im Sinne von „Unterteilung des Wertebereiches“) für nutzerdefinierte Einheiten definieren kann.
Alles in allem ein Tool, welches einen großen Nutzen bringt. Das Spring-Framework unterstützt JAMon.

Picture this: after we had moved an old app from an old server to a new one, we kept getting „I/O Exception: Broken Pipe“ now and then from our database connections. In the new environment, database lives on a different server than our app (as opposed to the old environment). Is there something wrong with the network?

My suspects turned out right: it’s the firewall between app and database. It drops „unused“ tcp connections after an hour. For some security reasons, this cannot be changed.

As our apps is rather old, some parts of it still do not use a connection pool and so there are db connnections that „linger“ around unused for an hour and are used thereafter – bang, I/O exception.

So watch out for that and use a connection pool. Possibly one that can shrink (i.e. throw away unused connections).

Die letzten Wochen habe ich „Domain-Driven Design“ von Eric Evans gelesen (bei Lehmanns, Amazon). Ich finde, dieses Buch ist für Software-Entwickler sehr empfehlenswert, die sich des objektorientierte Programmiermodells bedienen.

Im Buch geht es darum, wie man gute Objektmodell für Fachdomänen erstellt (daher Domain-driven). Da es sich um ein ganzes Buch zu diesem Thema handelt, fängt es gar nicht erst bei „Substantive sind potentielle Klassen“ an, wie es sonst doch recht üblich in OO-Büchern ist. Evans stellt Patterns vor, die ganz unterschiedlichen Scope haben (von „Entities“ bis „Systemmetapher“) und stellt diese Patterns auch in Zusammenhang zueinander.

Das Ziel von domain-driven design sind „Deep Models“, d.h. Modelle und deren Implementierung (!!!), die aus der vertieften Analyse der Domäne entstehen. Ihr Mehrwert ist ein tiefes Verständnis der Domäne durch die Entwickler, eine größere Übereinstimmung im Wissen der Entwickler und Fachleute, verbesserte Wartbarkeit und vereinfachte Erweiterbarkeit.

Ganz klar wird allerdings herausgestellt, dass domain-driven design kein „must-have“ ist, sondern das es auch Alternativen gibt.

Domain-driven design bedeutet nicht up-front design, sondern: Modell und Implementierung gehören zusammen; das Modell benötigt das Feedback durch die Implementierung. Es wird durch vertiefende Kenntnis (das ist ein Prozess!) der Entwickler über die Domäne gewonnen, Refactoring überträgt neu gewonnene Kenntisse auf das Modell und damit die Implementierung.

Highlights für mich sind:

  • Unterscheidung zwischen Entities und Value Objects
  • Layers – so habe ich mir das schon immer vorgestellt
  • Ubiquitous Language – eine gemeinsame (Fach-)Sprache ist Voraussetzung für gute Kommunikation
  • Intention-Revealing Interfaces – verbessert Lesbarkeit des Codes, damit Wartbarkeit und Verständlichkeit
  • Bounded Context – in welchem Kontext gilt ein Modell überhaupt (davon kann es in einer Anwendung mehrere geben)
  • Responsibility Layers – Verantwortlichkeiten innerhalb eines Objektmodell in Schichten aufteilen

Das Buch kann man auch bei Safari online lesen.

about references. Memory leaks are still possible – if an object has a „reachable“ reference (whatever that is in your context) it won’t be garbage collected. You still have to think about who references your objects and how long.

For instance, in my current project using Java Swing, someone said

  1. getCurrentFocusManager().addKeyEventDispatcher(this)

in a constructor. Then we got reports OutOfMemory-Error. A simple

  1. getCurrentFocusManager().removeKeyEventDispatcher(this);

solved this issue.

It’s harder than you think!