É 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:

Copiando e colando o código docreateView() método em minha própria classe que herda da classe de fábricaViver com widgets grandes demais

A 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.

questionAnswers(9)

yourAnswerToTheQuestion