Question Équivalent Java des délégués Cocoa / protocoles informels Objective-C?


Quel est l'équivalent Java des délégués Cocoa?

(Je comprends que je peux avoir une interface transmise à une classe et que cette classe appelle les méthodes appropriées, mais je me demande s'il existe un autre moyen de réaliser quelque chose de plus proche des protocoles informels de Cocoa / Objective-C)


13
2017-07-30 23:27


origine


Réponses:


La réponse courte est qu'il n'y a rien en Java aussi proche que vous le souhaitez, mais il existe des alternatives. Le modèle de délégué n'est pas difficile à implémenter, il n'est tout simplement pas aussi pratique que de le faire avec Objective-C.

La raison pour laquelle les "protocoles informels" fonctionnent en Objective-C est que le langage prend en charge catégories, qui vous permettent d’ajouter des méthodes aux classes existantes sans les sous-classer, ou même d’avoir accès au code source. Ainsi, la plupart des protocoles informels sont une catégorie sur NSObject. Ceci est clairement impossible en Java.

Objective-C 2.0 opte pour les méthodes de protocole @optional, ce qui est une abstraction beaucoup plus propre et préférable pour le nouveau code, mais encore plus loin d'avoir un équivalent en Java.

Honnêtement, l'approche la plus flexible consiste à définir un protocole de délégué, puis à demander aux classes d'implémenter toutes les méthodes. (Avec les IDE modernes comme Eclipse, cela est trivial.) De nombreuses interfaces Java sont accompagnées d'une classe d'adaptateurs, ce qui est une méthode courante pour ne pas impliquer beaucoup de méthodes vides, mais restreint l'héritage. . (Josh Bloch aborde cette question dans son livre "Effective Java".) Je suggère de ne commencer par fournir qu’une interface, puis d’ajouter un adaptateur si cela est vraiment nécessaire.

Quoi que vous fassiez, évitez de lancer un UnsupportedOperationException pour les méthodes "non implémentées". Cela force la classe délégante à gérer les exceptions pour les méthodes qui doivent être facultatives. L'approche correcte consiste à implémenter une méthode qui ne fait rien, renvoie une valeur par défaut, etc. Ces valeurs doivent être bien documentées pour les méthodes sans type de retour vide.


8
2017-07-31 03:00



Le meilleur analogue à un protocole informel auquel je peux penser est une interface qui possède également une classe d'adaptateurs pour permettre aux développeurs de ne pas implémenter chaque méthode.

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

Alors, quelqu'un peut venir et simplement mettre en œuvre ce qui compte pour lui:

class AwesomeDelegate extends MyClassDelegateAdapter {

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

Soit ça, soit pure réflexion appelant des méthodes "connues". Mais c'est fou.


5
2017-07-31 01:15



Rien ne vous empêche d'utiliser le modèle de délégué dans vos objets Java (Il ne s'agit pas d'un motif couramment utilisé dans le JDK, comme c'est le cas dans Cocoa). Juste avoir un delegate ivar d'un type conforme à votre WhateverDelegate interface, puis dans vos méthodes d'instance que vous souhaitez déléguer, transférez l'appel de méthode sur l'objet délégué s'il existe. Vous allez probablement vous retrouver avec quelque chose qui ressemble beaucoup à ce, sauf en Java au lieu d'Obj-C.

Pour les interfaces optionnelles, cela serait plus difficile. Je suggérerais de déclarer l'interface, en déclarant une classe abstraite qui implémente des méthodes facultatives comme méthodes vides, puis en sous-classant la classe abstraite, en remplaçant les méthodes facultatives que cet objet particulier doit implémenter. Il y a une limitation potentiellement grave en raison du manque d'héritage multiple en Java, mais cela est aussi proche que possible.


2
2017-07-31 00:26