Domanda

C'è un modo per emulare mixin o tratti in Java? fondamentalmente, ho bisogno di un modo per fare l'ereditarietà multipla in modo da poter aggiungere la logica aziendale comune a diverse classi

È stato utile?

Soluzione

Vorrei incapsulare tutta la logica aziendale in una nuova classe BusinessLogic e fare in modo che ogni classe che necessita di BusinessLogic effettui chiamate alla classe. Se hai bisogno di un'unica gerarchia radicata per le tue classi che effettuano chiamate a BusinessLogic , dovrai creare anche un'interfaccia ( BusinessLogicInterface ?)

In pseudo-codice:

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(); }
}

Questa non è l'implementazione più bella per ovviare alla mancanza di eredità multipla e diventa piuttosto ingombrante quando l'interfaccia ha molti metodi. Molto probabilmente, vorrai provare a riprogettare il tuo codice per evitare la necessità di mixin.

Altri suggerimenti

Non nel modo in cui vuoi farlo. Java efficace ti consiglia di " Favorire la composizione sull'ereditarietà " ;. Ciò significa che si sposta la logica comune in altre classi e delegato. Ecco come aggirare la mancanza di eredità multipla in Java.

Oggi il purista-oggetto si agita in te?

Pensi di poter fare con un po 'di programmazione orientata al composito?

Allora, signore, state cercando Apache Polygene (precedentemente Qi4J o Zest);)

La risposta di Java all'ereditarietà multipla è la capacità di implementare più interfacce. Ovviamente, questo significa che otterrai le dichiarazioni del metodo, ma non la logica.

Potresti provare ad emulare i mixin per composizione: la tua classe Java potrebbe definire variabili membro che rappresentano altre classi che eseguono una logica aziendale comune.

Nel progettare le classi Java, non ho trovato la mancanza di ereditarietà multipla in stile C ++ per inibire la progettazione della mia architettura. Troverai un modo per ottenere ciò che vuoi fare.

QI4J ti consente di utilizzare i mixin

È possibile sfruttare il fatto che le interfacce consentono alle classi nidificate (automaticamente statiche pubbliche) di mantenere l'implementazione predefinita dei metodi dell'interfaccia incapsulati all'interno dell'interfaccia stessa. Cioè sposta la classe BusinessLogic dell'esempio di Alex B all'interno dell'interfaccia.

Questo è simile al modo in cui Scala genera il codice JVM per i tratti come spiegato qui Come vengono compilati i tratti Scala in bytecode Java?

In questo caso l'esempio diventa:

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); }
}

Nota che passiamo un oggetto del tipo di interfaccia come " self " parametro. Ciò significa che la logica aziendale può utilizzare altri metodi astratti (metodo0). Questo può essere molto utile per creare un tratto con metodi astratti che sono tutti ortogonali tra loro e utilità "estensione". metodi che possono essere implementati in termini di questi metodi ortogonali.

Lo svantaggio è che ogni interfaccia deve copiare / incollare il codice di delega della caldaia. Un altro modello spesso usato in Java senza questo inconveniente (ma con meno coesione e meno modo OO per chiamare i metodi) è quello di creare una classe con il nome plurale come interfaccia contenente i metodi statici, che viene utilizzato nella classe di utilità Collections.

L'implementazione del supporto semplice per mixin / tratti in Java usando CGLib / javassit è abbastanza semplice. Puoi dare un'occhiata ad esempio qui per piccolo esempio. È possibile trovare una soluzione più completa e pronta per l'uso: qui

A partire da Java-8, sono stati aggiunti i metodi di interfaccia predefiniti. Questo, insieme all'eredità multipla di interfacce in Java, dovrebbe consentire una sorta di mixin. Chiaramente le interfacce devono funzionare in modo indipendente. Quindi, ci saranno limiti significativi.

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