忍受我...我不认为这太主观但也许我错了。
最近我想分解出一些在我们的BlackBerry应用程序上绘制自定义位图背景的重复代码。
(这个问题并不是关于黑莓的,所以我会在这里提供一些关于BB GUI的细节,以便非BB的Java人可以权衡......)
FullScreen类来自BB API - 它有一个方法paint(Graphics),框架调用它来绘制屏幕和添加到它的任何组件。可以覆盖它来进行自定义绘制 - 比如在任何其他绘制发生之前绘制位图背景(较新的BB API提供Background类但我们的应用程序必须在旧手机上工作)。
我想要一堆具有相同背景的屏幕,每个屏幕都做了一些自定义绘画...这就是我想出的:
abstract public class BGFullScreen extends FullScreen {
Bitmap bg;
public BGFullScreen(Manager mgr, long style) {
super(mgr, style);
bg = Bitmap.getBitmapResource("bg.jpg");
}
abstract protected void innerPaint(Graphics g);
protected void paint(Graphics g) {
g.drawBitmap(new XYRect(0, 0, bg.getWidth(), bg.getHeight()), bg, 0, 0);
innerPaint(g);
super.paint(g);
}
}
然后,每个屏幕将子类化此抽象类并实现innerPaint()。这样,当BB框架调用paint()方法时,每个屏幕都可以在绘制背景后进行自定义绘制(因此任何绘制都发生在背景之上)但是在绘制屏幕的组件之前,当使用FullScreen时。 paint()被调用。
(我想出了这个,因为我在家里一直在研究Common Lisp,我想到我想要做的就像CLOS中的交错方法组合一样)
这是上面抽象类的示例实现:
public class MainAppScreen extends BGFullScreen {
public MainAppScreen() {
super(new VerticalFieldManager(), 0);
// add some components to the screen:
add(new ButtonField(...));
add(...)
}
protected void innerPaint(Graphics g) {
// stuff drawn will be on top of background and under buttons
g.draw(...)
}
}
基本上我想要一个子类来实现一个方法,在它的父实现和祖父母的同一方法的实现之间调用它。我想不出用Java做任何其他方法...
这是一个像Java的人吗?这实际上是非常普遍的,这是一个愚蠢的问题吗?这实际上是可怕的设计吗? (BB专家,我怎么能以其他方式做到这一点?)
编辑添加:这确实如所描述的那样工作 - 绘图按我想要的顺序发生。
是的,不仅是惯用的Java,而且是OO。它被称为template method
这几乎就是Swing的工作原理 - 请参阅JComponent.paintComponent方法。 paint方法调用paintBorder,paintComponent和paintChildren,您可以覆盖paintComponent来实现自己的绘图,而不会干扰标准的Swing组件。
欢迎来到设计模式:你发现的是Template Method。