Question

Existe-t-il un moyen d’émuler les mixins ou les traits en java? En gros, j'ai besoin d'un moyen de faire de l'héritage multiple pour pouvoir ajouter une logique métier commune à plusieurs classes

Était-ce utile?

La solution

Je voudrais encapsuler toute la logique métier dans une nouvelle classe BusinessLogic et faire en sorte que chaque classe ayant besoin de BusinessLogic passe des appels à la classe. Si vous avez besoin d'une hiérarchie unique enracinée pour vos classes effectuant des appels vers BusinessLogic , vous devrez également créer une interface ( BusinessLogicInterface ?)

En pseudo-code:

interface BusinessLogicInterace
{
    void method1();
    void method2();
}

class BusinessLogic implements BusinessLogicInterface
{
    void method1() { ... }
    void method2() { ... }
}

class User 
    extends OtherClass 
    implements BusinessLogicInterface
{
    BusinessLogic logic = new BusinessLogic();

    @Override
    void method1() { logic.method1(); }

    @Override
    void method2() { logic.method2(); }
}

Ce n’est pas la plus belle implémentation qui permette de contourner un manque d’héritage multiple et elle devient assez lourde lorsque l’interface comporte de nombreuses méthodes. Très probablement, vous voudrez peut-être essayer de repenser votre code pour éviter d’avoir besoin de mixins.

Autres conseils

Pas comme vous voulez le faire. Effective Java vous recommande de "privilégier la composition à l'héritage". Ce qui signifie que vous déplacez la logique commune vers d'autres classes et déléguez. C’est ainsi que l’on évite le manque d’héritage multiple en java.

L’objet-puriste vous remue-t-il aujourd’hui?

Vous pensez pouvoir faire avec un peu de programmation orientée composite?

Ensuite, vous recherchez une Apache Polygene (anciennement Qi4J ou Zest);)

La réponse de Java à l'héritage multiple est la possibilité d'implémenter plusieurs interfaces. Bien sûr, cela signifie que vous obtiendrez les déclarations de méthode, mais pas la logique.

Vous pouvez essayer d’émuler les mixins par composition: votre classe Java pourrait définir des variables de membre représentant d’autres classes exécutant une logique d’entreprise commune.

Lors de la conception des classes Java, je n'ai pas trouvé le manque d'héritage multiple de style C ++ pour empêcher la conception de mon architecture. Vous trouverez le moyen de réaliser ce que vous voulez faire.

QI4J vous permet d'utiliser des mixins

Vous pouvez exploiter le fait que les interfaces permettent aux classes imbriquées (automatiquement publiques statiques) de conserver l'implémentation par défaut des méthodes d'interface encapsulées dans l'interface elle-même. C'est à dire. déplacez la classe BusinessLogic de l'exemple d'Alex B dans l'interface.

Cela ressemble à la façon dont Scala génère le code JVM pour les traits, comme expliqué ici Comment les traits Scala sont-ils compilés en bytecode Java?

Ce faisant, l'exemple devient:

interface BusinessLogicInterface {
    void method0();

    class DefaultImpl {
        private DefaultImpl() {
        }

        public static void method1(BusinessLogicInterface self) { ... }
        public static void method2(BusinessLogicInterface self) { ... }
    }

    void method1();
    void method2();
}

class User extends OtherClass implements BusinessLogicInterface {
    @Override
    void method0() { ... }

    @Override
    void method1() { BusinessLogic.defaultImpl.method1(this); }

    @Override
    void method2() { BusinessLogic.defaultImpl.method2(this); }
}

Notez que nous transmettons un objet du type d'interface en tant que "self". paramètre. Cela signifie que la logique applicative peut utiliser d'autres méthodes abstraites (method0). Cela peut être très utile pour créer un trait avec des méthodes abstraites orthogonales entre elles et un utilitaire "extension". méthodes qui peuvent être mises en œuvre en termes de ces méthodes orthogonales.

L’inconvénient est que chaque interface doit copier / coller le code de délégation standard. Un autre modèle souvent utilisé en Java sans cet inconvénient (mais avec moins de cohésion et moins de méthode OO pour appeler les méthodes) consiste à créer une classe avec le nom au pluriel comme interface contenant les méthodes statiques, utilisée dans la classe de l'utilitaire Collections.

Il est assez facile de mettre en œuvre une prise en charge de mixin / traits simple en java en utilisant CGLib / javassit. Vous pouvez consulter l'instance ici pour petit exemple. Une solution plus complète et prête à l'emploi pourrait être trouvée: ici

À partir de Java-8, les méthodes d'interface par défaut ont été ajoutées. Ceci, combiné à l'héritage multiple d'interfaces en Java, devrait permettre une sorte de mixin. Il est clair que les interfaces doivent fonctionner indépendamment. Donc, il y aura des limitations importantes.

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