设置命令监听器风格偏好疑问

发布于 2024-12-02 20:25:52 字数 201 浏览 0 评论 0原文

为什么有些人喜欢

.setCommandListener(this)

更频繁地

.setCommandListener(new CommandListener(){})

使用?在什么情况下我应该使用第二个,为什么? 我认为这只是风格问题还是有特殊问题?

Why do some people prefer to use

.setCommandListener(this)

over

.setCommandListener(new CommandListener(){})

more often? In what case should I use the second one and why?
I am assuming it's just a matter of style or is there a particular issue?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

廻憶裏菂餘溫 2024-12-09 20:25:52

如果使用“this”,则必须在类中实现监听器,然后可以在监听器的实现方法中访问类的字段。

如果您使用第二个(新侦听器...),那么如果您不需要访问类中的许多其他内容,那么它可能是更具可读性的代码。

If you use "this", you must implement the listener to the class, and then you can access fields of class in the implemented methods of listener.

If you use the second one(new Listener...) then it might be more readable code if you don't need to access many other stuff in your class.

紅太極 2024-12-09 20:25:52

setCommandListener(this) 在“玩具代码”中明显更容易阅读。我认为这就是为什么我看到它在许多入门级教程中使用,而作者只是不想太深入。

看起来初学者程序员只是盲目地从教程中复制这个反模式,而没有给予额外的思考。

根据我的经验,对于更复杂的代码, setCommandListener(new CommandListener(){/*..*/}) 更容易维护和阅读。

另请注意,在两种情况下您都可以访问类的字段 ,后者需要使用 限定这一点

//import javax.microedition.midlet.*;
//import javax.microedition.lcdui.*;

abstract class ListenerTest extends MIDlet {
    protected Display display;

    protected void startApp() {
        display = Display.getDisplay(this);
        Form form = new Form("welcome");
        form.addCommand(new Command("go", Command.OK, 1));
        form.setCommandListener(new CommandListener() {
            public void commandAction(Command c, Displayable d) {
                // qualified this - see JLS 15.8.4
                ListenerTest.this.cmdAction(c, d);
            }
        });
        // display "welcome" screen with "go" command
        display.setCurrent(form);
    }

    protected void pauseApp() { }

    protected void destroyApp(boolean unconditional) {
        notifyDestroyed();
    }

    protected abstract void displayNext();

    private void cmdAction(Command c, Displayable d) {
        // invoke from listener to display next screen
        displayNext();
    }
} // ListenerTest

class NextTest extends ScreenTest {

    protected void displayNext() {
        Form form = new Form("bye-bye");
        form.addCommand(new Command("EXIT", Command.EXIT, 1));
        form.setCommandListener(new CommandListener() {
            public void commandAction(Command c, Displayable d) {
                notifyDestroyed();
            }
        });
        // display "bye-bye" screen with "exit" command
        display.setCurrent(form);
    }
} // NextTest

顺便说一句,我是否提到过以上方法还安全吗?它保证您期望的特定屏幕的侦听器正是您设置的侦听器。

比如说,如果您直接重写 setCommandListener(this) 并运行它,您会注意到奇怪的行为 - 命令“go”现在将退出 midlet,而不是显示下一个屏幕:

    // don't do that
    abstract class ListenerTest extends MIDlet implements CommandListener {
        protected Display display;

        protected void startApp() {
            display = Display.getDisplay(this);
            Form form = new Form("welcome");
            form.addCommand(new Command("go", Command.OK, 1));
            form.setCommandListener(this);
            // display "welcome" screen with "go" command
            display.setCurrent(form);
        }

        protected void pauseApp() { }

        protected void destroyApp(boolean unconditional) {
            notifyDestroyed();
        }

        protected abstract void displayNext();

        public void commandAction(Command c, Displayable d) {
            // invoke from listener... really??? check the subclass
            displayNext();
        }
    } // ListenerTest

    class NextTest extends ScreenTest implements CommandListener {

        protected void displayNext() {
            Form form = new Form("bye-bye");
            form.addCommand(new Command("EXIT", Command.EXIT, 1));
            form.setCommandListener(this);
            // display "bye-bye" screen with "exit" command
            display.setCurrent(form);
        }

        public void commandAction(Command c, Displayable d) {
            // you may not notice but...
            notifyDestroyed();
            // ...this actually overrides superclass implementation
        }
    } // NextTest

setCommandListener(this) is noticeably easier to read in "toy code". I think that's why I've seen it used in many entry level tutorials, where authors just don't want to get too deep.

It also looks like beginner programmers just blindly copy this anti-pattern from tutorials, without giving it additional thought.

For more complicated code though setCommandListener(new CommandListener(){/*..*/}) was in my experience much easier to maintain and read.

Note also that you can access fields of class in both cases, just latter requires use of Qualified this:

//import javax.microedition.midlet.*;
//import javax.microedition.lcdui.*;

abstract class ListenerTest extends MIDlet {
    protected Display display;

    protected void startApp() {
        display = Display.getDisplay(this);
        Form form = new Form("welcome");
        form.addCommand(new Command("go", Command.OK, 1));
        form.setCommandListener(new CommandListener() {
            public void commandAction(Command c, Displayable d) {
                // qualified this - see JLS 15.8.4
                ListenerTest.this.cmdAction(c, d);
            }
        });
        // display "welcome" screen with "go" command
        display.setCurrent(form);
    }

    protected void pauseApp() { }

    protected void destroyApp(boolean unconditional) {
        notifyDestroyed();
    }

    protected abstract void displayNext();

    private void cmdAction(Command c, Displayable d) {
        // invoke from listener to display next screen
        displayNext();
    }
} // ListenerTest

class NextTest extends ScreenTest {

    protected void displayNext() {
        Form form = new Form("bye-bye");
        form.addCommand(new Command("EXIT", Command.EXIT, 1));
        form.setCommandListener(new CommandListener() {
            public void commandAction(Command c, Displayable d) {
                notifyDestroyed();
            }
        });
        // display "bye-bye" screen with "exit" command
        display.setCurrent(form);
    }
} // NextTest

BTW did I mention that above approach is also safer? It guarantees that the listener you expect for particular screen is exactly the one that you set.

Say, if you do a straightforward rewrite to setCommandListener(this) and run it, you'll notice weird behavior - command "go" will now quit the midlet instead of showing next screen:

    // don't do that
    abstract class ListenerTest extends MIDlet implements CommandListener {
        protected Display display;

        protected void startApp() {
            display = Display.getDisplay(this);
            Form form = new Form("welcome");
            form.addCommand(new Command("go", Command.OK, 1));
            form.setCommandListener(this);
            // display "welcome" screen with "go" command
            display.setCurrent(form);
        }

        protected void pauseApp() { }

        protected void destroyApp(boolean unconditional) {
            notifyDestroyed();
        }

        protected abstract void displayNext();

        public void commandAction(Command c, Displayable d) {
            // invoke from listener... really??? check the subclass
            displayNext();
        }
    } // ListenerTest

    class NextTest extends ScreenTest implements CommandListener {

        protected void displayNext() {
            Form form = new Form("bye-bye");
            form.addCommand(new Command("EXIT", Command.EXIT, 1));
            form.setCommandListener(this);
            // display "bye-bye" screen with "exit" command
            display.setCurrent(form);
        }

        public void commandAction(Command c, Displayable d) {
            // you may not notice but...
            notifyDestroyed();
            // ...this actually overrides superclass implementation
        }
    } // NextTest
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文