8

O'Reillyの「ProgrammingAndroid」の本を読んでいて、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.
    }
}

2つ目がはるかに読みやすいことを除けば、2つの機能の違いはわかりません。どちらもTextViewを受け取り、オーバーライドするハンドラー関数を実装します。2つ目は、このようなもので拡張するのと同じくらい簡単ではないでしょうか?

public class AnotherModel extends MyModel {
    @Override
    void handleTextChange(Editable s) {
         // another implementation
    }
}
4

2 に答える 2

2

クラスがインターフェイスのサブタイプであるためではなく、クラスがインターフェイスをトリックとして実装するため、2 番目の形式は好きではありません。

単純な場合は第2形態で対応できるので、よほど面倒でなければOKです。

Java 8 では、より良い構文で最初の形式を使用できます。

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

an anti-pattern due to lack of extensibility

Extensibility-wise, they're similar in that both approaches let a subclass easily modify the existing TextChangeListener by overriding handleTextChange; but they're different in that only approach #2 also makes it easy for a subclass to add a new TextChangeListener without modifying the existing (inherited) one.

Even if the superclass uses approach #1, the subclass could still add a new TextChangeListener by using approach #2; but if we're talking about the pattern to use in general, then a consistent use of approach #2 will afford more extensibility than a consistent use of approach #1.

于 2012-12-05T15:06:38.067 に答える