Frage

Was ist der Java-Äquivalent von Cocoa Delegierten?

(Ich verstehe, dass ich eine Schnittstelle zu einer Klasse übergeben haben, und haben diese Klasse die entsprechenden Methoden aufrufen, aber ich frage mich, ob es eine andere Möglichkeit ist etwas näher an Cocoa / Objective-C informellen Protokolle zu erreichen)

War es hilfreich?

Lösung

Die kurze Antwort ist, es gibt nichts in Java so nah, wie Sie möchten, aber es gibt Alternativen. Der Delegierte Muster ist nicht schwer zu implementieren, es ist nur nicht ganz so bequem wie es mit Objective-C zu tun.

Der Grund, „informelle Protokolle“ work in Objective-C ist, weil die Sprache unterstützt Kategorien , die Ihnen erlauben, Methoden zu bestehenden Klassen hinzuzufügen, ohne sie Subklassen, oder sogar den Zugriff auf den Quellcode haben. So sind die meisten informellen Protokolle sind eine Kategorie auf NSObject. Dies ist eindeutig nicht in Java.

Objective-C 2.0 entscheidet sich für @optional Protokollverfahren, die eine viel saubere Abstraktion ist und für neuen Code bevorzugt, aber noch weiter von einer äquivalent in Java mit.

Ehrlich gesagt, das flexibelste Ansatz ist ein Delegat Protokoll zu definieren, dann haben Klassen alle Methoden implementieren. (Mit modernen IDEs wie Eclipse, das ist trivial.) Viele Java-Schnittstellen eine begleitende Adapter-Klasse, und dies ist ein gemeinsames Konzept für den Benutzer nicht erfordern viele leeren Methoden zu implementieren, aber es schränkt Vererbung, die Code-Design unflexibel macht . (Josh Bloch-Adressen in seinem Buch „Effective Java“). Mein Vorschlag wäre nur zuerst eine Schnittstelle bereitstellen, dann einen Adapter hinzufügen, wenn es wirklich notwendig ist.

Was immer Sie tun, vermeiden eine UnsupportedOperationException für „nicht implementiert“ Methoden zu werfen. Dies zwingt die delegierenden Klasse Ausnahmen für Methoden zu behandeln, die optional sein sollte. Der richtige Ansatz ist es, ein Verfahren zu implementieren, die nichts tut, gibt einen Standardwert, usw. Diese Werte sollten auch für Methoden dokumentiert werden, die keinen Rückgabetyp void haben.

Andere Tipps

Best analog zu einem informellen Protokoll ich denken kann, ist eine Schnittstelle, die auch einen Adapter Klasse Implementierer zu ermöglichen, jede Methode zu vermeiden umzusetzen.

public class MyClass {

    private MyClassDelegate delegate;

    public MyClass () {

    }

    // do interesting stuff

    void setDelegate(MyClassDelegate delegate) {
        this.delegate = delegate;
    }

    interface MyClassDelegate {
        void aboutToDoSomethingAwesome();
        void didSomethingAwesome();
    }

    class MyClassDelegateAdapter implements MyClassDelegate {

        @Override
        public void aboutToDoSomethingAwesome() {
            /* do nothing */
        }

        @Override
        public void didSomethingAwesome() {
            /* do nothing */
        }
    }
}

Dann kann jemand entlang kommen und implementieren nur das, was sie kümmern uns um:

class AwesomeDelegate extends MyClassDelegateAdapter {

    @Override
    public void didSomethingAwesome() {
        System.out.println("Yeah!");
    }
}

Entweder das, oder reine Reflexion calling „bekannt“ Methoden. Aber das ist verrückt.

Es gibt nichts hindert Sie daran, mit dem Delegat Muster in Ihrer Java-Objekte (Es ist einfach nicht eine häufig verwendete Muster in der JDK wie es in Cocoa ist). Nur eine delegate Ivar eines Typs hat, die dann in der Instanz Methoden zu Ihrer WhateverDelegate Schnittstelle entspricht, die Sie delegieren wollen, leiten den Methodenaufruf auf den Delegatobjekt wenn es vorhanden ist. Sie würden wahrscheinlich am Ende mit etwas, das viel wie dieser aussieht, außer in Java anstelle von Obj-C.

Soweit optionale Schnittstellen gehen, das wäre schwieriger. Ich würde vorschlagen, die Schnittstelle, erklärt eine abstrakte Klasse deklariert, die optionalen Methoden als leere Methoden implementiert, und dann Subklassen die abstrakte Klasse, die optionalen Methoden überschreiben, die Sie dieses besondere Objekt implementieren mögen. Es gibt eine potenziell schwerwiegende Einschränkung hier aufgrund des Fehlens von Mehrfachvererbung in Java, aber das ist so nah wie ich einfiel.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top