No quiero discutir los méritos de este enfoque, solo si es posible. Creo que la respuesta es "no". ¡Pero tal vez alguien me sorprenda!¿Es posible el parche de mono en Java?
Imagine que tiene una clase de widget central. Tiene un método calculateHeight()
, que devuelve una altura. La altura es demasiado grande; esto da como resultado botones (por ejemplo) demasiado grandes. Puede extender DefaultWidget para crear su propio NiceWidget e implementar su propio calculateHeight()
para obtener un tamaño mejor.
Ahora una clase de biblioteca WindowDisplayFactory, instancia el DefaultWidget en un método bastante complejo. Le gustaría usar su NiceWidget. El método de la clase de fábrica se ve más o menos así:
public IWidget createView(Component parent) {
DefaultWidget widget = new DefaultWidget(CONSTS.BLUE, CONSTS.SIZE_STUPIDLY);
// bunch of ifs ...
SomeOtherWidget bla = new SomeOtherWidget(widget);
SomeResultWidget result = new SomeResultWidget(parent);
SomeListener listener = new SomeListener(parent, widget, flags);
// more widget creation and voodoo here
return result;
}
Ese es el trato. El resultado tiene el widget predeterminado en una jerarquía de otros objetos. La pregunta: ¿cómo obtener este método de fábrica para usar mi propio NiceWidget? O al menos obtener mi propio calculateHeight()
allí. Idealmente, me gustaría ser capaz de parchear el mono DefaultWidget de manera que su calculateHeight hizo lo correcto ...
public class MyWindowDisplayFactory {
public IWidget createView(Component parent) {
DefaultWidget.class.setMethod("calculateHeight", myCalculateHeight);
return super.createView(parent);
}
}
Que es lo que podía hacer en Python, Ruby, etc. He inventado el nombre setMethod()
sin embargo. Las otras opciones abiertas para mí son:
- Copiar y pegar el código del método
createView()
en mi propia clase que hereda de la clase de fábrica - Living con widgets que son demasiado grandes
El la clase de fábrica no se puede cambiar; es parte de una API de la plataforma central. Intenté reflexionar sobre el resultado obtenido para acceder al widget que (finalmente) se agregó, pero se trata de varias capas de widgets y en algún lugar se usa para inicializar otras cosas, lo que causa extraños efectos secundarios.
¿Alguna idea? Mi solución hasta ahora es el trabajo de copiar y pegar, pero eso es una salida de policía que requiere el seguimiento de los cambios en la clase principal de fábrica cuando se actualiza a versiones más nuevas de la plataforma, y me gustaría escuchar otras opciones.
Suena bien y posiblemente sea la solución real más cercana. Tal vez un poco exagerado para agregar una dependencia de Spring donde no existía ninguno para la aplicación solo para esta reparación. Es posible que un cargador de clases personalizado no funcione bien con Eclipse RCP, que también utilizo ... – richq
No necesita Spring para hacer AOP, simplemente obtenga AspectJ. También hay un plugin eclipse: http://www.eclipse.org/aspectj/ –