我有一个类层次结构:
+-- VirtualNode
|
INode --+ +-- SiteNode
| |
+-- AbstractNode --+
|
+-- SiteSubNode
在NodeCollection
上构建的相应INode
类。为了显示NodeCollection
我需要知道每个成员的最终类型。所以我需要一个像这样的函数
foreach (INode n in myNodeCollection)
{
switch(n.GetType())
{
case(typeof(SiteNode)):
// Display n as SiteNode
}
}
现在,这实际上不是面向对象的方式。 您认为在做同样的事情时是否有任何模式或推荐方法?
修改
我已经想过在INode接口中添加Display
或Render
方法。这有将视图耦合到模型的副作用,我真的很想避免。
答案 0 :(得分:1)
我认为你所追求的是visitor pattern。
答案 1 :(得分:1)
当你有一个使用对象类型的select语句时,它是重构多态的主要候选者。
查看Martin Fowler的书Refactoring:
“面向对象代码最明显的症状之一是它相对缺乏切换(或者 case)陈述。 switch语句的问题基本上是重复的问题。经常你 找到分散在不同位置的程序的相同switch语句。如果你添加一个新的 对于switch,你必须找到所有这些switch,语句并更改它们。面向对象 多态的概念为您提供了一种处理这个问题的优雅方法。
大多数时候你会看到一个switch语句,你应该考虑多态性。问题出在哪里 多态性应该发生。通常,switch语句会打开类型代码。你要 承载类型代码值的方法或类。因此,使用Extract Method来提取开关 语句然后移动方法将其放到需要多态的类上。在 那一点你必须决定是否用子类或替换替换类型代码 用状态/策略键入代码。设置继承结构后,可以使用 用多态性替换条件。“
以下是在您的情况下使用多态的一种方法:
在中定义一个抽象方法 AbstractNode的名字就像 显示()。
然后实际实现Display() SiteNode和SiteSubNode中的每一个 类。
然后,当你需要显示这些时 节点,你可以简单地迭代 通过一个包含的集合 AbstractNode类型的项目和调用 每个显示()。
对Display()的调用将会 自动解决到实际 真实的具体实施 该项目的类型。
注意:您也可以移动 AbstractNode的Display()方法 如果是INode接口 将显示VirtualNode。
答案 2 :(得分:0)
如果您可以更改INode接口 - 添加一个返回“视图”的虚拟方法,并在继承的类中覆盖它。
如果你不能改变基本接口 - 为每个类实现扩展方法,并让它们返回每个特定类的“视图”。