我正在阅读O'Reilly的“Programming Android”一书,我正试图从第99页开始围绕“覆盖和回调”部分。他们将此作为优秀代码的示例:
public class MyModel {
public MyModel(TextView textBox) {
textBox.addTextChangedListener(
new TextWatcher() {
public void afterTextChanged(Editable s) {
handleTextChange(s);
}
// ...
}
void handleTextChange(Editable s) {
// do something with s, the changed text.
}
}
后来由于缺少可扩展性封装而将其称为反模式:
public class MyModel implements TextWatcher {
public MyModel(TextView textBox) {
textBox.addTextChangedListener(this);
}
public void afterTextChanged(Editable s) {
handleTextChange(s);
}
// ...
void handleTextChange(Editable s) {
// do something with s, the changed text.
}
}
我没有看到两者之间的功能差异,除了第二个更具可读性。两者都采用TextView,并实现一个处理函数来覆盖。难道第二个不会像这样容易扩展吗?
public class AnotherModel extends MyModel {
@Override
void handleTextChange(Editable s) {
// another implementation
}
}
答案 0 :(得分:2)
由于缺乏可扩展性而导致的反模式
可扩展性方面,它们相似,因为两种方法都允许子类通过覆盖TextChangeListener
轻松修改现有handleTextChange
;但它们的区别在于,只有方法#2还可以让子类轻松添加 new TextChangeListener
,而无需修改现有的(继承的)。
即使超类使用方法#1,子类仍然可以使用方法#2添加新的TextChangeListener
;但是如果我们谈论一般使用的模式,那么一致使用方法#2将提供比一致使用方法#1更多的可扩展性。
答案 1 :(得分:2)
我不喜欢第二种形式,因为类实现了一个接口作为技巧,而不是因为该类自然是接口的子类型。
对于简单的情况,第二种形式是可以管理的,所以除非它太乱,否则它是可以的。
在Java 8中,我们可以使用更好的语法第一种形式:
textBox.addTextChangedListener(this#handleTextChange); // method reference