2

一部の人々が使用することを好む理由

.setCommandListener(this)

以上

.setCommandListener(new CommandListener(){})

もっと頻繁に?どのような場合に2番目のものを使用する必要がありますか?その理由は? それは単にスタイルの問題だと思いますか、それとも特定の問題がありますか?

4

2 に答える 2

1

「this」を使用する場合は、リスナーをクラスに実装する必要があり、実装されたリスナーのメソッドでクラスのフィールドにアクセスできます。

2 番目のもの (new Listener...) を使用すると、クラス内の他の多くのものにアクセスする必要がない場合、より読みやすいコードになる可能性があります。

于 2011-09-06T04:01:32.513 に答える
0

setCommandListener(this)「トイコード」の方が格段に読みやすい。それが、作成者があまり深く入りたくない多くの初心者レベルのチュートリアルで使用されているのを見た理由だと思います。

また、初心者のプログラマーは、このアンチパターンをチュートリアルから盲目的にコピーして、それ以上考えずにいるようにも見えます。

より複雑なコードの場合setCommandListener(new CommandListener(){/*..*/})、私の経験では、保守と読み取りがはるかに簡単でした。

また、どちらの場合でもクラスのフィールドにアクセスできることに注意してください。後者の場合は修飾された 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

ところで、上記のアプローチもより安全だと言いましたか?特定の画面に期待するリスナーが、設定したものとまったく同じであることを保証します。

たとえば、 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
于 2011-09-06T12:37:30.130 に答える