这是惯用的Java吗?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了这是惯用的Java吗?相关的知识,希望对你有一定的参考价值。

忍受我...我不认为这太主观但也许我错了。

最近我想分解出一些在我们的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

以上是关于这是惯用的Java吗?的主要内容,如果未能解决你的问题,请参考以下文章

在具有可接受/惯用的静态初始化程序的类中使用空静态方法吗?

有人知道下面的代码片段是啥意思吗?

添加指向惯用文本元素的链接

接受 Result<T, E> 作为函数参数是惯用的 Rust 吗?

初始化 Java 对象的 Clojure 惯用方法

这是从片段中获取字符串资源的正确方法吗?