8

我正在阅读 O'Reilly 的“Programming Android”一书,并试图从第 99 页开始围绕“Overrides and Callbacks”部分展开思考。他们将此作为良好代码的示例:

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
    }
}
4

2 回答 2

2

由于缺乏可扩展性而导致的反模式

在可扩展性方面,它们的相似之处在于这两种方法都可以让子类TextChangeListener通过覆盖轻松地修改现有的handleTextChange; 但它们的不同之处在于,唯一的方法#2 也使子类可以轻松地添加 TextChangeListener的,而无需修改现有的(继承的)。

即使超类使用方法#1,子类仍然可以TextChangeListener使用方法#2 添加新的;但是,如果我们谈论的是一般使用的模式,那么一致使用方法#2 将比一致使用方法#1 提供更多的可扩展性。

于 2012-12-05T15:06:38.067 回答
2

我不喜欢第二种形式,因为类实现接口是一种技巧,而不是因为类自然是接口的子类型。

第二种形式对于简单的情况是可以管理的,所以除非它变得太乱,否则没关系。

在 Java 8 中,我们可以以更好的语法使用第一种形式:

    textBox.addTextChangedListener(this#handleTextChange);  // method reference
于 2012-12-05T15:52:59.090 回答