Blog

Transformers – verwandelbare Objekte

In meinem vorangehenden Beitrag habe ich die Möglichkeiten der Predicates aus commons-collection vorgestellt. Predicates erlauben, auf einfache Art und Weise Aussagen über Objekte zu überprüfen und dadurch ein wiederverwendbares  Regelwerk zu implementieren. Sie haben jedoch eine Einschränkung: Ein konkretes Predicate bezieht sich auf einen konkreten Type (z.B. Predicate). Die Wiederverwendung wird dadurch erschwert.

Hier kommen Transformer ins Spiel, ebenfalls aus dem commons-collection Frameworks, das wieder in seiner generischen Erweiterung zum Einsatz kommt.

(Es ist zu hoffen, dass nach der Verabschiedung von commons-lang 3 auch commons-collections 4 künftig wieder direkt von apache nutzbar wird.)

Ein Transformer ist ein einfaches generisches Interface, das genau eine Methode definiert: transform().

public AToBTransformer implements Transformer<A,B> {
  public B transform(A a) {
    return ...; // z.B. a.getB(), oder new B(a), oder ...
  }
}

Mit Hilfe der Util-Klasse ChainedTransformer können auch komplexere Transformationen aus Basis-Transformern zusammengesetzt werden.

Transformer<A,C> aToC = ChainedTransformer.getInstance(new ABTransformer(), new BCTransformer));

Wie spielt das nun mit unseren in Predicates formulierten Regeln zusammen? Unter Verwendung eines Transformers kann ein Predicate, das wir für die Prüfung eines Kunden entwickelt haben, auch für die Prüfung einer Bestellung verwendet werden. Dabei greifen wir zurück auf die Regel „Kunde ist älter als 18“, die im ersten Teil dieses Blogs erstellt worden ist.

// eine Bestellung, die eine Referenz auf einen Kunden hält
public class Order {
   public Customer getCustomer() {...};
}

// eine "null-safe" Transformation der Order auf den Kunden
public class OrderToCustomer implements Transformer<Order, Customer> {
   public Customer transform(Order order) {return order.getCustomer(); }
}

// Wurde die Bestellung von einem volljährigen Kunden in Auftrag gegeben?
boolean isAdult = TransformedPrediacte.getInstance(
                       new OrderToCustomer(),
                       new CustomerIsAdult()).evaluate(order);

Wir konnten somit die bestehende Regelvalidierung einfach auf eine weitere Klasse übertragen, indem wir das Ausgangsobjekt auf den Eingangstypen unseres Predicates transformiert haben.

Fazit: Die Verwendung von Transformern und Predicates erlaubt das Herunterbrechen von Validierungen auf ihre kleinsten Einheiten (im o.g. Fall böte sich z.B. an, die Überprüfung des Kunden in „transformiere Kunde nach Geburtstag“ und „vergleiche Geburtstag mit Zieldatum“ herunterzubrechen). Das Ergebnis sind gut getestete, lesbare und wiederverwertbare Einheiten für die logischen Aussagen meiner Geschäftsregeln.

Holisticon AG — Teile diesen Artikel

Über den Autor

Jan Galinski ist Senior Consultant bei der Holisticon AG und seit vielen Jahren als Architekt und Entwickler in agilen Kundenprojekten unterwegs. Er ist ein leidenschaftlicher Prozessautomatisierer und BPM-Craftsman, am liebsten mit Camunda BPM. Als Contributor zu zahlreichen Open Source Projekten aus den Bereichen BPM und JEE gibt er seine Erfahrung und Wissen gerne weiter. 2016 wurde er mit dem Camunda Community Award ausgezeichnet.

Ein Kommentar

Antwort hinterlassen