É possível fazer o patch do macaco em Java?
Não quero discutir os méritos dessa abordagem, apenas se for possível. Eu acredito que a resposta seja "não". Mas talvez alguém me surpreenda!
Imagine que você tem uma classe de widget principal. Tem um métodocalculateHeight()
, que retorna uma altura. A altura é muito grande - isso resulta em botões (digamos) muito grandes. Você pode estender o DefaultWidget para criar seu próprio NiceWidget e implementar seu própriocalculateHeight()
para retornar um tamanho melhor.
Agora, uma classe de biblioteca WindowDisplayFactory, instancia DefaultWidget em um método bastante complexo. Você gostaria que ele usasse seu NiceWidget. O método da classe de fábrica se parece com isso:
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;
}
Este é o acordo. O resultado possui o DefaultWidget dentro de uma hierarquia de outros objetos. A questão - como obter esse método de fábrica para usar meu próprio NiceWidget? Ou pelo menos pegue o meucalculateHeight()
lá. Idealmente, eu gostaria de poder fazer um patch em macaco no DefaultWidget, para que o seu CalculeHeight fizesse a coisa certa ...
public class MyWindowDisplayFactory {
public IWidget createView(Component parent) {
DefaultWidget.class.setMethod("calculateHeight", myCalculateHeight);
return super.createView(parent);
}
}
Que é o que eu poderia fazer em Python, Ruby, etc. Eu inventei o nomesetMethod()
Apesar. As outras opções abertas para mim são:
createView()
método em minha própria classe que herda da classe de fábricaViver com widgets grandes demaisA classe de fábrica não pode ser alterada - faz parte de uma API da plataforma principal. Tentei refletir sobre o resultado retornado para chegar ao widget que (eventualmente) foi adicionado, mas há várias camadas de widget abaixo e em algum lugar é usado para inicializar outras coisas, causando efeitos colaterais estranhos.
Alguma ideia? Até agora, minha solução é o trabalho de copiar e colar, mas isso exige um rastreamento das alterações na classe de fábrica pai ao atualizar para versões mais recentes da plataforma, e eu estaria interessado em ouvir outras opções.