一部の人々が使用することを好む理由
.setCommandListener(this)
以上
.setCommandListener(new CommandListener(){})
もっと頻繁に?どのような場合に2番目のものを使用する必要がありますか?その理由は? それは単にスタイルの問題だと思いますか、それとも特定の問題がありますか?
「this」を使用する場合は、リスナーをクラスに実装する必要があり、実装されたリスナーのメソッドでクラスのフィールドにアクセスできます。
2 番目のもの (new Listener...) を使用すると、クラス内の他の多くのものにアクセスする必要がない場合、より読みやすいコードになる可能性があります。
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