2

次のシナリオがあるとします。

    abstract class A {
        abstract method1();
        abstract method2();
    }

    class B extends A {
        method1() {
            // implementation 1
        }
        method2() {
            // implementation 3
        }
    }

    class C extends A {
        method1() {
            // implementation 1
        }
        method2() {
            // implementation 4
        }
    }

    class D extends A {
        method1() {
            // implementation 2
        }
        method2() {
            // implementation 4
        }
    }

結論: 同じクラスのいくつかのサブクラスで、異なるメソッドに対して異なるメソッド実装を使用しています。

問題は、異なるサブクラスで同じ実装を使用していることです。私の質問は、これらの一般的な実装をどうするかということです?
それを行う論理的な方法は、別のレベルの抽象化を作成することですが、それは共通の実装を持つ 1 つのメソッドがある場合にのみ機能します (Java には多重継承がないため)。また、最も一般的に使用される実装をスーパークラスに置き、それを他のクラスで別の方法で実装することもできます。ただし、他のクラスの追加によって最も一般的な実装が変更される可能性があるため、私はそうしません。また、スーパークラスでメソッドを抽象化しておきたいと考えています。

「エレガントな方法」で私の問題を解決するパターンはありますか?

4

2 に答える 2

5

継承階層が扱いにくくなるという古典的なOOPの問題に直面しています:-)

私の提案する解決策:

  • 継承よりも構成を優先する-実装を除外して、必要な動作を提供するために「プラグイン」できる個別のオブジェクトにします。基本クラスのメソッドは、定義されたインターフェイスを介して実装プラグインを呼び出すだけです。これは基本的に戦略パターンです。これは非常に堅実なアプローチですが、さまざまな戦略タイプがある場合、過剰なエンジニアリングや定型文が多く発生する可能性があります。
  • プロトタイプベースのモデルを採用する-従来のOOPではなくプロトタイプベースのオブジェクトを使用します。これにより、すべての問題が解決されます。継承階層に固有の制限を回避し、実行時に必要なオブジェクトに実装をコピーするだけで済みます。これは最も急進的なオプションですが、いくつかの大きなメリットをもたらす可能性があります。
  • 実装を静的関数に分解します-この方法で実装を共有できます-まだすべてのオーバーライドを実行する必要があるため、少し面倒ですが、適切な実装への呼び出しを委任するワンライナーになります。多くの場合、これは最も邪魔にならないオプションです。
于 2012-05-23T07:07:20.050 に答える
2

作曲をお勧めします。次のことを考慮してください。

interface I1 {
     method1();
}

abstract class A implements I1{
    abstract method1();
    abstract method2();
}

class CommonOperations implements I1 {
    method1() {
        // implementation 1
    }
}

class B extends A {
    CommonOperations common;

    method1() {
        common.method1();
    }
    method2() {
        // implementation 3
    }
}

class C extends A {
    CommonOperations common;

    method1() {
        common.method1();
    }
    method2() {
        // implementation 4
    }
}

class D extends A {
    method1() {
        // implementation 2
    }
    method2() {
        // implementation 4
    }
}
于 2012-05-23T07:14:15.790 に答える