Pregunta

¿Hay alguna manera de emular mixins o rasgos en Java? básicamente, necesito una forma de hacer herencia múltiple para poder agregar lógica de negocios común a varias clases

¿Fue útil?

Solución

Encapsularía toda la lógica empresarial en una nueva clase BusinessLogic y haría que cada clase que necesita BusinessLogic realice llamadas a la clase. Si necesita una única jerarquía rooteada para sus clases que realice llamadas a BusinessLogic , también deberá crear una interfaz ( BusinessLogicInterface ?)

En pseudocódigo:

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

Esta no es la implementación más bonita para evitar una falta de herencia múltiple y se vuelve bastante engorrosa cuando la interfaz tiene muchos métodos. Lo más probable es que desee probar y rediseñar su código para evitar la necesidad de mixins.

Otros consejos

No es la forma en que quieres hacerlo. Java eficaz recomienda que "favorezca la composición sobre la herencia". Lo que significa que mueve la lógica común a otras clases y delega. Así es como se evita la falta de herencia múltiple en Java.

¿Te está revolviendo el purista de objetos hoy?

¿Crees que podrías hacer con una pequeña programación orientada a compuestos?

Entonces usted, señor, está buscando Apache Polygene (anteriormente Qi4J o Zest);)

La respuesta de Java a la herencia múltiple es la capacidad de implementar múltiples interfaces. Por supuesto, esto significa que obtendrá las declaraciones del método, pero no la lógica.

Podría intentar emular mixins por composición: su clase Java podría definir variables miembro que representen otras clases que realicen alguna lógica comercial común.

Al diseñar clases Java, no he encontrado la falta de herencia múltiple de estilo C ++ para inhibir el diseño de mi arquitectura. Encontrará una manera de lograr lo que quiere hacer.

QI4J le permite usar mixins

Puede explotar el hecho de que las interfaces permiten que las clases anidadas (estáticas públicas automáticas) mantengan la implementación predeterminada de los métodos de interfaz encapsulados dentro de la propia interfaz. Es decir. mover la clase BusinessLogic del ejemplo de Alex B dentro de la interfaz.

Esto es similar a la forma en que Scala genera el código JVM para las características como se explica aquí ¿Cómo se compilan los rasgos de Scala en el bytecode de Java?

Al hacer esto, el ejemplo se convierte en:

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

Tenga en cuenta que pasamos un objeto del tipo de interfaz como '' self '' parámetro. Esto significa que la lógica de negocios puede usar otros métodos abstractos (method0). Esto puede ser muy útil para crear un rasgo con métodos abstractos que son ortogonales entre sí y con la utilidad "extensión". métodos que pueden implementarse en términos de estos métodos ortogonales.

El inconveniente es que cada interfaz debe copiar / pegar el código de delegación estándar. Otro patrón usado a menudo en Java sin este inconveniente (pero con menos cohesión y menos forma de llamar a los métodos) es crear una clase con el nombre plural como la interfaz que contiene los métodos estáticos, esto se usa en la clase de utilidad Colecciones.

Implementar soporte simple de mixin / rasgos en java usando CGLib / javassit es bastante fácil. Puede echar un vistazo, por ejemplo, aquí para pequeño ejemplo Puede encontrar una solución más completa y lista para usar: aquí

A partir de Java-8, se agregaron métodos de interfaz predeterminados. Esto, junto con la herencia múltiple de interfaces en Java, debería permitir algún tipo de mezcla. Claramente, las interfaces tienen que operar de forma independiente. Por lo tanto, habrá limitaciones significativas.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top