作为解析器库的一部分,我有以下对象层次结构:
分析条目||/\/\/\NumericParseEntry字符串ParseEntry
等等。,
这些对象基本上保存数据。然后,我有一组操作,如evaluate(评估值是否通过解析条目标准)、generateSQL(基于解析条目标准生成SQL条件)。
由于单一责任原则,我不想将这些函数添加到特定的解析条目类中,而是希望维护单独的层次结构,为解析条目层次结构实现这些函数。这允许我对多个解析条目重用某个实现。
我想知道如何将操作与对象耦合,这样当我浏览执行某些操作的解析条目的解析表时,我应该能够获得适当的操作对象。
我可以考虑的一种粗略方法是使用一个工厂类来维护解析条目类型与其对应的计算器/SQLgenerator之间的映射。另一种方法是将计算器/sql生成器嵌入为解析条目的数据成员,并在getter中返回它们。
如有任何帮助,我们将不胜感激。
对我来说,这听起来像是访问者模式。你会有EvaluatorVisitor
和SQLGenerationVisitor
,它们将在ParseEntry
s上执行访问操作。ParseEntry
是一个元素,包含accept(Visitor)
操作,NumericParseEntry
和StringParseEntry
将扩展该操作。
因为您使用的是访问者模式,所以"单一责任"原则是免费的。
普通数据对象不是很面向对象。我认为操作(evaluate/generateSQL)实际上是ParseEntry
对象的责任。如果您想重用评估器实现,您仍然可以在ParseEntry
中编写一个Evaluator
并委托给它,例如:
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);
}
}
单一责任原则说,类的更改应该只有一个原因——如果您的更改确实与特定的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
}
我已经成功地使用这种模式实现了复杂案例分析,以实现与您尝试做的类似的事情……您将能够以优雅的方式创建依赖于类型或您选择的任何条件的代码,而无需修改"数据"层次结构。