Domanda

Qual è l'equivalente Java dei delegati Cocoa?

(Capisco che posso avere un'interfaccia passata a una classe e che quella classe chiami i metodi appropriati, ma mi chiedo se c'è un altro modo per ottenere qualcosa di più vicino ai protocolli informali di Cocoa / Objective-C)

È stato utile?

Soluzione

La risposta breve è che non c'è nulla in Java così vicino come vorresti, ma ci sono alternative. Il modello delegato non è difficile da implementare, non è altrettanto conveniente come farlo con Objective-C.

La ragione "protocolli informali" lavorare in Objective-C è perché il linguaggio supporta categorie , che ti consente di aggiungere metodi a classi esistenti senza sottoclassarli o addirittura avere accesso al codice sorgente. Pertanto, la maggior parte dei protocolli informali sono una categoria su NSObject. Ciò è chiaramente impossibile in Java.

Objective-C 2.0 opta per i metodi del protocollo @optional, che è un'astrazione molto più pulita e preferita per il nuovo codice, ma anche per avere un equivalente in Java.

Onestamente, l'approccio più flessibile è definire un protocollo delegato, quindi le classi implementano tutti i metodi. (Con IDE moderni come Eclipse, questo è banale.) Molte interfacce Java hanno una classe adattatrice di accompagnamento, e questo è un approccio comune per non richiedere all'utente di implementare molti metodi vuoti, ma limita l'eredità, il che rende la progettazione del codice poco flessibile . (Josh Bloch affronta questo problema nel suo libro "Efficace Java".) Il mio suggerimento sarebbe di fornire prima solo un'interfaccia, quindi aggiungere un adattatore se è veramente necessario.

Qualunque cosa tu faccia, evita di lanciare un UnsupportedOperationException per " unimplemented " metodi. Ciò impone alla classe delegante di gestire le eccezioni per i metodi che dovrebbero essere facoltativi. L'approccio corretto è quello di implementare un metodo che non fa nulla, restituisce un valore predefinito, ecc. Questi valori dovrebbero essere ben documentati per i metodi che non hanno un tipo di ritorno vuoto.

Altri suggerimenti

Il miglior analogo a un protocollo informale che mi viene in mente è un'interfaccia che ha anche una classe di adattatori per consentire agli implementatori di evitare l'implementazione di ogni metodo.

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 */
        }
    }
}

Quindi qualcuno può venire e implementare semplicemente le cose che gli interessano:

class AwesomeDelegate extends MyClassDelegateAdapter {

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

O quello, o pura riflessione che chiama "noto" metodi. Ma è pazzesco.

Non c'è nulla che ti impedisca di usare il modello delegato nei tuoi oggetti Java (non è solo un modello comunemente usato nel JDK come in Cocoa). Basta avere un ivar delegate di un tipo conforme all'interfaccia whateverDelegate , quindi nei metodi dell'istanza che si desidera delegare, inoltrare la chiamata del metodo sull'oggetto delegato se esiste . Probabilmente finiresti con qualcosa che assomiglia molto a this , tranne in Java invece di Obj-C.

Per quanto riguarda le interfacce opzionali, sarebbe più difficile. Suggerirei di dichiarare l'interfaccia, dichiarare una classe astratta che implementa metodi opzionali come metodi vuoti e quindi sottoclassare la classe astratta, sovrascrivendo i metodi opzionali che vuoi che questo particolare oggetto attui. C'è un limite potenzialmente grave qui a causa della mancanza di ereditarietà multipla in Java, ma è il più vicino possibile.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top