5

純粋にセマンティックの継承であり、動作の継承ではないオブジェクト階層がある場合、実行時の型チェックを行うために、必然的に「instanceof」または「if/else」をあらゆる場所に記述する必要があります。

例えば

オブジェクト階層がある場合

Class Function

Class Average extends Function

Class Sum extends Function

Class Max extends Function

これらのクラスに calculate() というメソッドがある場合、問題はありません。ポリモーフィズムを利用するだけで、この設計は LSP を満たします。

しかし、何らかの理由でこの calculate() メソッドをこの階層に追加したくない場合、これらのオブジェクトは純粋に単純なステートレス オブジェクトであり、意味を表すだけです。

次に、次のコードをどこにでも書く必要があります。

if (function instanceof Average)
//perform average
else if(function instanceof Sum)
//perform sum
else if(function instanceof Max)
//perform max

上記のコードは設計が悪いことを示しています。なぜなら、このコードをあらゆる場所に記述し、この設計は壊れやすく、後で変更するのが難しいからです。数値関数が制限されていて、関数の計算が 1 つの場所にある場合、複雑さによってはこれで問題ないと思います。

私がこれまでに知っていることは、上記のアプローチを解決するには、訪問者パターンを実装することだけが可能な方法であり、訪問者パターンを使用する以外に上記の設計を解決する方法はありますか?

ビジター パターンからわかる問題の 1 つは、ビジター パターンの accept メソッドが値を返さないことです。

4

3 に答える 3

4

コンパイル時にまだタイプがわかっている場合は、ヘルパー クラスを使用できます。

class Function {
}

class Average extends Function {
}

class Sum extends Function {
}

class Max extends Function {
}

class FunctionHelper {
  public Number calculate(Average a) {
    return null;
  }

  public Number calculate(Sum s) {
    return null;
  }

  public Number calculate(Max a) {
    return null;
  }

  public Number calculate(Function a) {
    return null;
  }

}

通常、ヘルパー メソッドは静的にしますが、それに限定されるわけではありません。さまざまな種類のヘルパー クラスを使用して、かなり興味深いことができます。

于 2013-05-21T09:12:25.737 に答える
1

これらのオブジェクトは純粋にプレーンなオブジェクトであり、ステートレス オブジェクトはセマンティックを表すだけです。

通常のオブジェクトの代わりに列挙型を使用したいようです。

次に、ステートメントを使用switchして、すべてのケースを処理したことをコンパイラにチェックさせることができます。

enum Function { Average, Sum, Max }
于 2013-05-21T09:00:03.163 に答える