如果可能的话,我不想讨论这种方法的优点。我相信答案是“不”。但也许有人会让我大吃一惊!
想象一下,您有一个核心小部件类。它有一个方法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 以便它的 calculateHeight 做正确的事情......
public class MyWindowDisplayFactory {
public IWidget createView(Component parent) {
DefaultWidget.class.setMethod("calculateHeight", myCalculateHeight);
return super.createView(parent);
}
}
这就是我可以在 Python、Ruby 等中做的事情。setMethod()
不过,我已经发明了这个名字。对我开放的其他选择是:
- 将方法的代码复制粘贴
createView()
到我自己的继承自工厂类的类中 - 与太大的小部件一起生活
工厂类无法更改 - 它是核心平台 API 的一部分。我尝试对返回的结果进行反射以获取(最终)添加的小部件,但它向下有几个小部件层,并且在某个地方它被用来初始化其他东西,导致奇怪的副作用。
有任何想法吗?到目前为止,我的解决方案是复制粘贴工作,但这是一个需要在升级到更新版本的平台时跟踪父工厂类中的更改的警察,我很想听听其他选项。