2012-07-15 51 views
2

作为一个解析器库的一部分,我的对象层次结构如下:耦合对象层次和操作

 
      ParseEntry 
       | 
       | 
       /\ 
      / \ 
      / \ 
NumericParseEntry StringParseEntry 

等,

这些对象基本保存数据。然后,我有一组操作,比如评估(评估值是否通过解析条目标准),generateSQL(根据解析条目生成SQL条件)。

由于单一职责原则,我不想将这些函数添加到特定的分析条目类,并且想要维护为分析条目层次结构实现这些功能的单独层次结构。这允许我为一个以上的解析条目重用某个实现。

我想知道如何将操作与对象耦合,以便在浏览解析表的解析表执行某些操作时,我应该能够获得相应的操作对象。

我能想到的一个原始方法是拥有一个工厂类,它在解析条目类型及其相应的评估器/ SQLgenerator之间维护映射。另一种方法是将评估程序/ sql生成器嵌入为解析条目的数据成员,并将其返回到getter中。

对此即兴创作任何帮助将不胜感激。

回答

1

普通数据对象不是非常面向对象的。我认为操作(evaluate/generateSQL)确实是ParseEntry对象的责任。如果你想重用评估实现,你仍然可以组成一个EvaluatorParseEntry,并委托给它,例如:

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 
} 
+0

感谢您的意见。我同意这样的观点:这些操作本质上应该在特定的语法分析类中实现。我喜欢你的想法,将评估代码移到单独的层次结构中,并通过合成将它们包含在解析条目中。 – Vikdor 2012-07-16 06:28:34

1

我已经成功地使用这种模式Implementing Complex Case Analysis实施类似的东西,你正在尝试做的......你就可以创建代码依赖于类型或无论您选择的条件以一种很好的方式,不用修改“数据”层次结构。

+0

感谢您的输入。虽然我个人并不倾向于使用框架来解决我的问题,但这是我通过你了解的一个很好的参考资料,可能对未来有所帮助。再次感谢! – Vikdor 2012-07-16 06:29:28

2

对我来说这听起来像是Visitor Pattern。您将有EvaluatorVisitorSQLGenerationVisitor哪些将有访问操作ParseEntry s。 ParseEntry元素包含accept(Visitor)操作,其中NumericParseEntryStringParseEntry将延伸。

因为您使用的是访客模式,所以单一职责原则是免费的。

+0

感谢您的输入。我也同意在概念上这些操作可能是访问者。但是我面临的问题是在Java中使用Generics在解析条目接口中使用accept方法的签名来实现它,以便在解析条目的什么评估者之间具有较强的键入。 – Vikdor 2012-07-16 06:26:55