【发布时间】:2016-02-14 08:04:17
【问题描述】:
我的 c# 项目中有一个IComposer 接口:
public interface IComposer
{
string GenerateSnippet(CodeTree tree);
}
CodeTree 是一个基类,其中包含从CodeTree 继承的类List<CodeTree>。例如:
public class VariablesDecleration : CodeTree
{
//Impl
}
public class LoopsDecleration : CodeTree
{
//Impl
}
我可以有几个实现 IComposer 的类,并且在每个类中我都有 GenerateSnippet 循环在 List<CodeTree> 上,基本上是这样:
foreach (CodeTree code in tree.Codes)
{
if (code.GetType() == typeof(VariablesDecleration))
{
VariablesDecleration codeVariablesDecleration = (VariablesDecleration) code;
// do class related stuff that has to do with VariablesDecleration
}
else if (code.GetType() == typeof(LoopsDecleration))
{
LoopsDecleration codeLoopsDecleration = (LoopsDecleration) code;
// do class related stuff that has to do with LoopsDecleration
}
}
我在每个实现IComposer 的类中重复了这个foreach 和if 语句。
我想知道是否有更好的设计模式来处理这种情况。假设 tommrow 我添加了一个继承自 CodeTree 的新类 - 我必须检查所有实现 IComposer 的类并修改它们。
我在考虑访问者设计模式 - 但不确定也不确定是否以及如何实现它。对于这种情况,Visitor 是否是正确的解决方案?
【问题讨论】:
-
@DarshanPatel 语法如果对我来说在这个问题上不重要。我试图理解正确的设计模式,以使代码可读和可维护,同时保持开闭原则。顺便说一句 - switch-case 不适用于类型:switch 表达式或 case 标签必须是 bool、char、string、integral、enum 或相应的可空类型
-
访客很可能是对的。您能否提供有关 IComposer 实现的更多详细信息(类的名称、它与 CodeTree 基类的关系等)?我不清楚。
-
有一个通用的重构策略模式,即用多态调用替换 if 语句(在类型上)。 refactoring.com/catalog/replaceConditionalWithPolymorphism.html 但是,在 Narayana 的回答中,您说“将此逻辑移至数据类型不是一种选择”——这就是为什么我们需要有关具体 Composers 的更多信息(在您的代码中)。
标签: c# design-patterns visitor-pattern