setting command listener style preferences doubt
Why do some people prefer to use
.setCommandListener(this)
over
.setCommandListener(new CommandListener(){})
more of开发者_如何学运维ten? 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?
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.
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
精彩评论