太多的间接层,这太多了吗?

时间:2009-06-09 07:14:10

标签: .net abstraction

我只是想知道这是否会涉及多个间接层?

Alt text http://img244.imageshack.us/img244/7371/classdiagram1.jpg

我尝试做一些解释。我的想法是,我在COM对象的顶部构建一个API,它只暴露Do和Eval方法。

以前我刚刚将一个IComObject传递给Table类并直接使用它,但这意味着当我尝试测试Table类时,我已经模拟了ICo​​mObject并担心命令被发送到我的表类中的COM对象

基本思想是我有命令运行器负责在COM对象中调用正确的命令,而Table(和其他)对象只是与命令运行器对话,而不必担心正在执行的命令。然后在我的测试中我可以这样做:

Mock<TableCommandRunner> mockrunner = new Mock<TableCommandRunner>();
mockrunner.Setup(run => run.getName("DummyTable")).Returns("FakeName");

Table table = new Table("DummyTable");
//Table.Name just calls commandrunner.getName
Assert.Equal(table.Name,"FakeName");

是否有太多的间接层或者这样可以吗?

注意:我会有更多的类,然后只有Table,Map,Window,Object等等都可以与命令运行者交谈。

3 个答案:

答案 0 :(得分:6)

你需要问的问题是,这个额外的抽象是否解决了你在添加它之前遇到的一些问题,是否是你可以接受的抽象的复杂性?何时抽象是一个非常主观的决定......正如人们常说的那样,抽象几乎可以解决任何问题,但代价是更复杂。

如果您提出这个问题,那么您似乎在质疑这种抽象带来的额外复杂性的价值。考虑到你的图表,它看起来并不复杂,如果它确实解决了你之前遇到的问题......我会说顺其自然。

最终,在必要的时候,你的直觉......抽象,但如果可以,请避免使用。

答案 1 :(得分:2)

我认为这不是太多的抽象层次。您的解决方案看起来非常优雅,因为您只是测试Table类调用正确的ComandRunner函数。您正在测试Table类如何处理CommandRunner,并且已经删除了CommandRunner实现的所有复杂功能,包括IComObject。这就是Mocking的全部意义所在。

答案 2 :(得分:0)

我不太确定,但对我来说,如果有疑问,我总是喜欢提供快捷方便的方法来包装这种抽象。

这样的东西
void runCommand(string cmd) // objects instantiated and used inside

所以,即使我有太多的抽象,仍然有一种直截了当的方式来“去做这件事”。