Question

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

(Je comprends qu'une interface peut être 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)

Était-ce utile?

La solution

La réponse courte est qu’il n’ya rien en Java aussi proche que vous le voudriez, mais il existe des alternatives. Le modèle de délégué n’est pas difficile à mettre en œuvre, il n’est tout simplement pas aussi pratique que de le faire avec Objective-C.

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

Objective-C 2.0 opte pour les méthodes de protocole @optional, une abstraction beaucoup plus propre et préférée pour le nouveau code, mais encore plus difficile d’avoir un équivalent en Java.

Honnêtement, l’approche la plus flexible est de définir un protocole de délégué, puis de faire en sorte que les classes implémentent toutes les méthodes. (Avec les IDE modernes comme Eclipse, cela est simple.) De nombreuses interfaces Java sont accompagnées d'une classe d'adaptateur. Il s'agit d'une approche courante pour ne pas obliger l'utilisateur à implémenter un grand nombre de méthodes vides, mais elle restreint l'héritage, ce qui rend la conception de code inflexible. . (Josh Bloch en parle dans son livre "Effective Java".) Je suggérerais de ne fournir qu'une interface en premier lieu, puis d'ajouter un adaptateur si c'est vraiment nécessaire.

Quoi que vous fassiez, évitez de lancer une UnsupportedOperationException pour " unimplemented " méthodes. Cela oblige la classe délégante à gérer les exceptions pour les méthodes qui devraient être facultatives. L’approche appropriée 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 qui n’ont pas de type de renvoi vide.

Autres conseils

Le meilleur analogue à un protocole informel auquel je puisse penser est une interface qui possède également une classe d'adaptateur permettant 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 */
        }
    }
}

Ensuite, quelqu'un peut venir et mettre en œuvre les éléments qui les intéressent:

class AwesomeDelegate extends MyClassDelegateAdapter {

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

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

Rien ne vous empêche d'utiliser le modèle de délégué dans vos objets Java (ce modèle n'est tout simplement pas utilisé dans le JDK comme dans Cocoa). Ayez simplement un ivar delegate d'un type conforme à votre interface WhateverDelegate , 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 obtiendrez probablement quelque chose qui ressemble beaucoup à this , sauf dans Java au lieu de Obj-C.

Pour ce qui est des interfaces optionnelles, ce serait plus difficile. Je suggérerais de déclarer l'interface, une classe abstraite qui implémente des méthodes facultatives en tant que méthodes vides, puis de sous-classer la classe abstraite, en remplaçant les méthodes facultatives que vous souhaitez que cet objet particulier implémente. Le manque d'héritage multiple en Java est potentiellement une grave limitation, mais c'est aussi proche que je pourrais en arriver.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top