标题可能不太具有描述性,但我想不出更好的标题。我很抱歉。
所以,我在这里遇到的问题是我现在遇到过几次的问题。它实际上与设计模式和原则有关,只要您的语言中有 OO 工具,它就与语言无关。我将带您了解当前遇到的问题,因为如果没有实际示例,很难解释问题所在。
所以,我在这里使用一些类来描述逻辑语句。想想这样的事情:
condition = new And(new Equals("x", 5),
new EqualsOrOver("y", 20));
现在这一切都是花花公子,但是当我想使用这个类系统时问题就来了。现在,我正在制作一个需要将条件转换为 SQL WHERE 子句的系统。
我可以通过多种方式做到这一点,但似乎都没有遵守开放/封闭原则。例如,我可以让Database
类解析条件并将其设为 SQL。问题是,通过这种方式,我无法Condition
在不需要更改 my 的情况下扩展 my Database
,因此我们没有遵循 Open/Closed。
另一种方法——在这里看起来很合乎逻辑——是在toSQL()
my s.s 中添加一个函数Condition
。但是,在这种情况下,我无法将我的数据库换成一个(只是为了命名)使用 XML 的数据库,它不希望 SQL 格式的条件。
我过去解决这个问题的一种方法是使用工厂。在这种情况下,工厂方法看起来像这样:
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);
}
}
这不是那么好,但它会减少对打开/关闭的违反。
现在,您可以很好地继承您的数据库。你也只需要对你的工厂进行子类化,并且你还必须为你的工厂创建一堆新的Condition
类Database
。你也可以在 Condition 类上发挥你的魔力。您可以创建一个新Condition
的 s,但您也必须为每个创建伴随类Database
。最后,您将不得不修改您的工厂。
这是迄今为止我们看到的最小的违规行为,但我们仍然违反了 Open/Closed。但事实上,我宁愿完全不违反它。有没有办法在坚持打开/关闭的同时做到这一点?