Das Decorator Pattern ist wirklich praktisch!

Mit dem Decorator Entwurfsmuster kann man auf einfache Art eine bestehende Klasse um eine Funktionalität erweitern, ohne diese Klasse verändern zu müssen. Und was ganz cool ist: Man kann auch Decorators von Decorators von Decorators machen, um beliebig viele Zusatzfunktionen ineinander zu verschachteln. Decorateception! (Ob das dann noch übersichtlich ist, ist eine Frage für einen weiteren Blogeintrag).

Das Decorator Pattern zeigte mir auch wieder einmal die Flexibilität, die hinter Interfaces steckt.

Das Grossbuchstaben-Problem

Ich habe eine Applikation, die von einer Klasse Mitarbeiter den Namen holt. Das Doofe ist jetzt aber, dass der erste Buchstabe immer klein geschrieben ist, ich benötige ihn aber gross geschrieben. Und was noch doofer ist: Es ist mir technisch unmöglich, diese Klasse nachträglich zu ändern.

Was kann ich also machen?

decoratorpatterngliffy-problem

Klick mich für das Bild in gross

Die Lösung visualisiert

Die Lösung ist einfach: Ich packe eine neue Klasse MitarbeiterDecorator um die Klasse Mitarbeiter. Und was beinhaltet diese Klasse? Sie implementiert dasselbe Interface Person wie Mitarbeiter. Konkret bedeutet dies, dass die Decoratorklasse diesselben Methoden wie Mitarbeiter implementieren muss. Der Clou dabei ist nun, dass ich im Decorator einen Mitarbeiter erstelle, und in jeder Methode vom Decorator jeweils die gleiche Methode von Mitarbeiter aufrufe.

getName() vom MitarbeiterDecorator ruft also getName() vom Mitarbeiter auf.

Und nun kann ich entweder vor oder nach diesem Methodenaufruf beliebige Funktionen einfügen, um den Namen zu verändern. In diesem Fall füge ich nach dem Holen vom Namen im MitarbeiterDecorator noch eine Logik ein, die sicherstellt, dass der erste Buchstabe gross geschrieben ist.

decoratorpatterngliffy-loesung

Klick mich für das Bild in gross

Lösung in einem Codebeispiel

Die wichtigen Codestücke für dieses Beispiel sind folgende:

1. Der aufrufenden Applikation gebe ich statt einem Mitarbeiter einen MitarbeiterDecorator zurück – in den ich den Mitarbeiter gleich reinsetze, um dessen Methoden aufrufen zu können.

Aus

return mitarbeiter;

wird

return new MitarbeiterDecorator(mitarbeiter);

Die neue Klasse MitarbeiterDecorator sieht dann folgendermassen aus:

public class MitarbeiterDecorator implements Person {

private Mitarbeiter mitarbeiter;

public MitarbeiterDecorator(Mitarbeiter mitarbeiter){
    this.mitarbeiter = mitarbeiter;
}

public String getName(){

    // rufe die Methode der Mitarbeiterklasse auf
    String name = mitarbeiter.getName();

    // Stelle hier sicher, dass der erste Buchstabe gross ist
    name = Character.toUpperCase(name.charAt(0)) 
    + name.substring(1, name.length());

    return name;
}
}

Warum sind hier Interfaces so cool?

Im Codebeispiel sieht man, warum hier Interfaces eine geniale Erfindung sind: Die Aufruferapplikation programmiert (gemäss genereller programmierempfehlungen) gegen das Interface Person. Ich kann nun einfach statt des Mitarbeiters den MitarbeiterDecorator zurückgeben – Da beide Klassen „Personen“ sind, stört das die Aufruferapplikation nicht.

Fazit

Ich hoffe, das Beispiel hat die Genialität des Decorator Pattern darlegen können. Ich möchte hier noch ergänzend sagen, dass man das Pattern auch mit einer abstrakten Klasse statt einem Interface machen kann.

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit deinem WordPress.com-Konto. Abmelden /  Ändern )

Facebook-Foto

Du kommentierst mit deinem Facebook-Konto. Abmelden /  Ändern )

Verbinde mit %s