Я не хочу обсуждать достоинства этого подхода, просто если это возможно. Я считаю, что ответом будет «нет». Но, может быть, меня кто-нибудь удивит!
Представьте, что у вас есть базовый класс виджетов. У него есть метод calculateHeight()
, который возвращает высоту. Высота слишком велика - это приводит к, скажем, слишком большим кнопкам. Вы можете расширить DefaultWidget, чтобы создать свой собственный NiceWidget, и реализовать собственный calculateHeight()
, чтобы получить более хороший размер.
Теперь библиотечный класс WindowDisplayFactory создает экземпляр DefaultWidget довольно сложным методом. Вы хотели бы, чтобы он использовал ваш NiceWidget. Метод фабричного класса выглядит примерно так:
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;
}
Вот и все. Результат имеет DefaultWidget глубоко внутри иерархии других объектов. Вопрос - как заставить этот фабричный метод использовать мой собственный NiceWidget? Или, по крайней мере, получить мой собственный calculateHeight()
там. В идеале я хотел бы иметь возможность сделать патч для DefaultWidget так, чтобы его CalculayHeight делал все правильно ...
public class MyWindowDisplayFactory {
public IWidget createView(Component parent) {
DefaultWidget.class.setMethod("calculateHeight", myCalculateHeight);
return super.createView(parent);
}
}
Что я мог бы сделать в Python, Ruby и т. Д. Я изобрел имя setMethod()
. Другие варианты, открытые для меня:
- Копирование и вставка кода метода
createView()
в мой собственный класс, который наследуется от фабричного класса
- Жизнь с слишком большими виджетами
Фабричный класс изменить нельзя - он является частью API базовой платформы. Я попытался отразить возвращенный результат, чтобы добраться до виджета, который (в конечном итоге) был добавлен, но он находится на нескольких слоях виджетов и где-то используется для инициализации других вещей, вызывая странные побочные эффекты.
Есть идеи? Мое решение до сих пор - задание копирования-вставки, но это копирование, которое требует отслеживания изменений в родительском фабричном классе при обновлении до более новых версий платформы, и мне было бы интересно услышать другие варианты.