Einführung Inhaltsverzeichnis

10. Das Entwurfsmuster Delegate

In allen obigen Beispielen ist das Erzeugen des Thread-Objekts sehr ähnlich. Das Stück Programmcode unterscheidet sich nur an einer einzigen Stelle: Was passiert nach dem Ablauf der Schlafperiode (1 oder 3 Sekunden). Bei den monolithischen Programmen wird die Methode this.tick() aufgerufen, in der MVC-Version model.tick() und view.tick(), in der Observer-Version notifyObservers("Tick") oder notifyObservers(Ereignis.TICK). Es liegt an der Hand, den Code aus dem Konstruktor in eine Methode auszulagern; aber die Übergabe einer Anweisungsfolge oder einer aufzurufenden Methode als Parameter ist in Java nicht vorgesehen. (In anderen Sprachen wie C oder C# ist dies möglich).

In Java kann eine Methode als Parameter nicht übergeben werden, wohl aber ein Objekt, dessen Klasse diese Methode enthält. In verschiedenen Situationen werden verschiedene Objekte übergeben, deren Klassen eine gemeinsame Schnittstelle implementieren.

Dieses Muster können wir folgendermaßen implementieren:

public interface Delegat { // gemeinsame Schnittstelle

   void aktion(); // (formale) Delegatmethode

   long getFrequenz(); }

public class Ticken {

   public static void ticken(final Delegat d) { // gemeinsamer Codeteil

     new Thread() {

        @Override

        public void run() {

           try {

              while (true) {

                Thread.sleep(d.getFrequenz());

                d.aktion(); // unterschiedlicher Codeteil

           } } catch (InterruptedException e) { } } }.start(); } }

Der Aufruf der Methode ticken() aus DigitalUhr und aus KreisUhr erfolgt im Konstruktor:

DigitalUhr() {

   … // Oberfläche aufbauen wie oben

   pack();

    setVisible(true);

   Ticken.ticken(new Delegat() { // Aufruf der Methode mit Delegatparameter

        @Override

        public void aktion() { // aktuelle Delegatmethode

           tick(); }

        public long getFrequenz() {

           return frequenz; } }); }

Der Konstruktor der abstrakten Klasse Control aus der Lösung MVC mit Observer ist wie folgt:

Control(final IModel model) {

   Ticken.ticken(new Delegat() { // Aufruf der Methode mit Delegatparameter

     @Override

     public void aktion() { // aktuelle Delegatmethode

        setChanged();

        notifyObservers("Tick"); }

        public long getFrequenz() {

           return model.getFrequenz(); } }); }

während die Lösung mit generischem Observer unterscheidet sich ähnlich auch nur im Rumpf der Delegatmethode aktion():

   public void aktion() {

     notifyObservers(Ereignis.TICK); }

Mit Hilfe eines Delegats ist es also möglich, gemeinsame Codeteile in eine Methode auszulagern, selbst wenn sie dabei unterschiedliche Codeteile enthalten. Gegebenenfalls kann die Delegatmethode auch parametrisiert werden.

Einführung Inhaltsverzeichnis


Version: 22. April 2012

© Prof. Solymosi, 20102 Beuth-Hochschule für Technik Berlin, Fachbereich VI (Informatik und Medien)

solymosibht-berlin.de