タイトルはあまり説明的ではないかもしれませんが、私はより良いものを考えることができませんでした。ごめんなさい。
ですから、私がここで抱えている問題は、私が今何度か遭遇した問題です。それは本当にデザインパターンと原則に関するものであり、あなたの言語にOO機能がある限り、言語に依存しません。実際の例なしでは問題が何であるかを説明するのは難しいので、私が抱えている現在の問題について説明します。
したがって、ここではいくつかのクラスを使用してロジックステートメントを記述しています。次のようなことを考えてください。
condition = new And(new Equals("x", 5),
new EqualsOrOver("y", 20));
さて、これはすべてダンディですべてですが、このクラスシステムを使用したいときに問題が発生します。現在、条件をSQLWHERE句に変換する必要があるシステムを作成しています。
私はこれをいくつかの方法で行うことができましたが、オープン/クローズの原則に準拠しているものはないようです。たとえば、Database
クラスに条件を解析させてSQLにすることができます。Condition
問題は、このように、変更せずに拡張できないためDatabase
、Open/Closedをフォローしていないことです。
別の方法(ここでは論理的に見えるでしょう)はtoSQL()
、私のに関数を追加することCondition
です。ただし、その場合、データベースを(名前を付けるためだけに)XMLを使用し、SQL形式の条件を必要としないデータベースと交換することはできません。
私が過去にこの問題を回避した1つの方法は、工場を使用することでした。この場合のファクトリメソッドは次のようになります。
turnIntoSQLCondtion(Condition c)
{
if (c instanceof Equals)
{
return new SQLEquals(c);
}
else if (c instanceof EqualsOrOver)
{
return new SQLEqualsOrOver(c);
}
else if (c instanceof And)
{
return SQLAnd(c);
}
}
これはそれほど良いことではありませんが、Open/Closedの違反を減らすことができます。
これで、データベースを適切にサブクラス化できます。ファクトリもサブクラス化する必要があり、同様にCondition
固有のクラスの新しい束を作成する必要がありますDatabase
。また、Conditionクラスで魔法をかけることもできます。新しいを作成することはできCondition
ますが、それぞれのコンパニオンクラスも作成する必要がありますDatabase
。最後に、工場を変更する必要があります。
これはこれまでに見た中で最小の違反ですが、まだOpen/Closedに違反しています。しかし、実際のところ、私はそれをまったく侵害したくありません。ずっと開いた/閉じたままでこれを行う方法はありますか?