In diesem Abschnitt geht es um Anti Patterns in und um hybris Entwicklung.

Es gibt sicherlich eine Menge guter Design Patterns und davon auch eine Menge für hybris. Doch ganz häufig sehe ich Prinzipien, die immer wieder genutzt und umgesetzt werden, die mir als hybris Consultant und bekennender CCD und TDD Fetischist sehr negativ auffallen.

Da ich gerne bildhaft beschreibe, versuche ich hier geeignete Namen zu finden, die einem die Patterns im Gedächtnis behalten und sie möglichst vermeiden lassen. Auch im Review des Codes anderer lassen sich dann Dinge leichter bezeichnen.

Ähnlichkeiten mit lebenden Personen und Code ist beabsichtigt.

Äpfel und Birnen

Es gibt den Spruch, dass man nicht Äpfel mit Birnen vergleichen solle, weil das eine sozusagen nichts mit dem anderen zu tun hat. Genau dies habe ich als Anti Pattern in hybris entdeckt.

Stellen wir uns vor, wir hätten eine einfache Entität, beispielsweise die Adresse eines Users. Dann gäbe es sicherlich ein AddressModel Objekt als Instanz dieser Adresse.
Sollte der User in der Lage sein, diese Adresse über ein Webformular zu ändern, würde diese geänderte Adresse im besten Sinne als AddressData Objekt an einen Controller weitergeleitet und über diesen an die Fassade.

public void changeAddress(AddressData newAddress) {
   ...
}

Um nun die Liste aller geänderten Attribute zu ermitteln, wurde eine Methode implementiert, die dieses AddressData Objekte gegen das assoziierte AddressModel Objekt verglichen und alle unterschiedlichen Attributnamen in einer Liste gesammelt.

public void changeAddress(AddressData newAddress) {
   AddressModel oldAddress = customerService.getAddress(newAddress.getCustomer());

   // compare now newAddress and oldAddress and save changed attributes
   if (!newAddress.getStreetname().equals(oldAddress.getStreet()) {
      result.add("streetname");
   }
   ...
}

Wenn man diesen Code zu Ende denken mag, kann man sich vorstellen, dass nun einige Blöcke der gleichen Bauart erscheinen. Dabei wurde hier auf entsprechende Validierungen und Null-Prüfungen noch verzichtet.
Irgendwann überlegt man dann, dass es eigentlich ja so etwas wie BeanUtils bzw. PropertyUtils des Apache Common Lang Projekts gibt, was einem hilfen würde, aber egal wie man es dreht und wendet, der Code wird nicht schöner.

Der Grund dafür ist denkar einfach: Wir vergleichen Äpfel (AddressData) mit Birnen (AddressModel).
Viel einfacher wäre das Leben, wir würden die Äpfel erstmal zu Birnen machen und das ist zwar normalerweise nicht, aber eben in hybris möglich: AddressPopulator.
Bevor ich den Vergleich durchführe, populiere ich das AddressData Objekt zu einem AddressModel Objekt und dann nutze ich die org.apache.commons.beanutils.PropertyUtilsBean:

PropertyUtilsBean propUtils = new PropertyUtilsBean();

for (Object propNameObject : map.keySet()) {
	String propertyName = (String) propNameObject;
	Object property1 = propUtils.getProperty(oldAddress, propertyName);
	Object property2 = propUtils.getProperty(newAddress, propertyName);
	if (!property1.equals(property2)) {
		result.add(propertyName);
	}
}