除了使用层次结构之外,是否有更好的方法来显示对象?

时间:2008-10-09 10:18:15

标签: c# design-patterns

我有一个类层次结构:

        +-- VirtualNode
        |
INode --+                  +-- SiteNode
        |                  |
        +-- AbstractNode --+
                           |
                           +-- SiteSubNode

NodeCollection上构建的相应INode类。为了显示NodeCollection我需要知道每个成员的最终类型。所以我需要一个像这样的函数

foreach (INode n in myNodeCollection)
{
    switch(n.GetType())
    {
        case(typeof(SiteNode)):
        // Display n as SiteNode
    }
}

现在,这实际上不是面向对象的方式。 您认为在做同样的事情时是否有任何模式或推荐方法?

修改
我已经想过在INode接口中添加DisplayRender方法。这有将视图耦合到模型的副作用,我真的很想避免。

3 个答案:

答案 0 :(得分:1)

我认为你所追求的是visitor pattern

答案 1 :(得分:1)

Polymorphism:

当你有一个使用对象类型的select语句时,它是重构多态的主要候选者。

查看Martin Fowler的书Refactoring

“面向对象代码最明显的症状之一是它相对缺乏切换(或者 case)陈述。 switch语句的问题基本上是重复的问题。经常你 找到分散在不同位置的程序的相同switch语句。如果你添加一个新的 对于switch,你必须找到所有这些switch,语句并更改它们。面向对象 多态的概念为您提供了一种处理这个问题的优雅方法。

大多数时候你会看到一个switch语句,你应该考虑多态性。问题出在哪里 多态性应该发生。通常,switch语句会打开类型代码。你要 承载类型代码值的方法或类。因此,使用Extract Method来提取开关 语句然后移动方法将其放到需要多态的类上。在 那一点你必须决定是否用子类或替换替换类型代码 用状态/策略键入代码。设置继承结构后,可以使用 用多态性替换条件。“

以下是在您的情况下使用多态的一种方法:

  1. 在中定义一个抽象方法 AbstractNode的名字就像 显示()。

  2. 然后实际实现Display() SiteNode和SiteSubNode中的每一个 类。

  3. 然后,当你需要显示这些时 节点,你可以简单地迭代 通过一个包含的集合 AbstractNode类型的项目和调用 每个显示()。

  4. 对Display()的调用将会 自动解决到实际 真实的具体实施 该项目的类型。

  5. 注意:您也可以移动 AbstractNode的Display()方法 如果是INode接口 将显示VirtualNode。

答案 2 :(得分:0)

如果您可以更改INode接口 - 添加一个返回“视图”的虚拟方法,并在继承的类中覆盖它。

如果你不能改变基本接口 - 为每个类实现扩展方法,并让它们返回每个特定类的“视图”。