2

パーサーライブラリの一部として、次のオブジェクト階層があります。

             ParseEntry
                 |
                 |
                / \
               / \
              / \
NumericParseEntry StringParseEntry

等。、

これらのオブジェクトは基本的にデータを保持します。次に、evaluate(値が解析エントリ基準に合格するかどうかを評価するため)、generateSQL(解析エントリ基準に基づいてSQL条件を生成するため)などの一連の操作があります。

単一責任の原則により、これらの関数を特定の解析エントリクラスに追加したくないので、解析エントリ階層にこれらの関数を実装する個別の階層を維持したいと思います。これにより、特定の実装を複数の解析エントリに再利用できます。

ある操作を実行している解析エントリの解析テーブルを参照しているときに、適切な操作オブジェクトを取得できるように、操作をオブジェクトと結合する方法を考えていました。

私が考えることができる大まかな方法​​の1つは、解析エントリタイプとそれに対応するエバリュエーター/SQLgeneratorの間のマップを維持するファクトリクラスを持つことです。もう1つの方法は、evaluator / sqlジェネレーターを解析エントリのデータメンバーとして埋め込み、それらをゲッターに返すことです。

これを即興で行うための助けをいただければ幸いです。

4

3 に答える 3

2

これは私にはビジターパターンのように聞こえます。あなたが持っているだろうしEvaluatorVisitorSQLGenerationVisitorそれはsの訪問操作を持っているでしょうParseEntryParseEntryは、拡張する操作を含む要素です。accept(Visitor)NumericParseEntryStringParseEntry

ビジターパターンを使用しているため、単一責任の原則は無料です。

于 2012-07-15T11:07:43.407 に答える
1

私はこのパターンをうまく使用して、複雑なケース分析を実装して、あなたがやろうとしていることと同様のことを実装しました...タイプや選択した条件に応じて、エレガントな方法でコードを作成できます。 「データ」階層の変更。

于 2012-07-15T05:19:13.550 に答える
1

プレーンデータオブジェクトは、あまりオブジェクト指向ではありません。操作(evaluate / generateSQL)は確かにオブジェクトの責任であると私は主張しParseEntryます。エバリュエーターの実装を再利用する場合でも、Evaluatorinを作成しParseEntryて、それに委任することができます。次に例を示します。

public class NumericParseEntry extends ParseEntry {
  private Evaluator evaluator = ...;
  private SQLGenerator sqlGenerator = ...;

  public bool evaluate(Object value) {
    return evaluator.evaluate(this, value);
  }

  public String generateSQL() {
    return sqlGenerator.generateSQL(this);
  }
}

単一責任の原則では、クラスを変更する理由は1つだけである必要があります。変更が実際に特定のものに関連している場合はParseEntry、クラスを変更しても問題はありません。


また、継承を使用して、個別のEvaluator/Generatorクラスを完全に削除することを検討できます。例えば:

public class NumericParseEntry extends ParseEntry {
  // put common logic for numeric entries here
}

public class IntegerParseEntry extends NumericParseEntry {
  // put specialized code for handling integers
}

public class FloatParseEntry extends NumericParseEntry {
  // put specialized code for handling floating-point
}
于 2012-07-15T04:54:51.080 に答える