dev*_*r82 8 c# design-patterns visitor
我的IComposerc#项目中有一个界面:
public interface IComposer
{
string GenerateSnippet(CodeTree tree);
}
Run Code Online (Sandbox Code Playgroud)
CodeTree是一个基类,包含一个List<CodeTree>继承自的类CodeTree.例如:
public class VariablesDecleration : CodeTree
{
//Impl
}
public class LoopsDecleration : CodeTree
{
//Impl
}
Run Code Online (Sandbox Code Playgroud)
我可以有几个实现的类,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
}
}
Run Code Online (Sandbox Code Playgroud)
我在每个实现的类中重复这些foreach和if语句IComposer.
我想知道是否有更好的设计模式来处理这种情况.让我说tommrow我添加了一个继承自的新类CodeTree- 我将不得不遍历所有实现IComposer和修改它们的类.
我在考虑访问者设计模式 - 但不确定并且不确定是否以及如何实现它.访客是否为这种情况提供了正确的解决方案?
移动与内部特定类相关的实现,VariablesDecleration并LoopsDecleration提供一个抽象实现CodeTree.然后在你的循环中,简单地在CodeTree中调用该方法,而不用if ... else检查.
public class VariablesDecleration : CodeTree
{
//Impl
public void SomeStuff()
{
//... specific to Variables
}
}
public class LoopsDecleration : CodeTree
{
//Impl
public void SomeStuff()
{
//... specific to Loops
}
}
public class CodeTree : ICodeTree
{
void SomeStuff();
}
foreach (CodeTree code in tree.Codes)
{
code.SomeStuff();
}
Run Code Online (Sandbox Code Playgroud)
根据评论,你可能需要这样的东西:
public interface IComposer
{
string DoStuff();
}
public class LoopComposer1 : IComposer
{
string DoStuff(){ .. }
}
public class VariableComposer1 : IComposer
{
string DoStuff(){ .. }
}
public class ComposerCollection
{
private IEnumerable<IComposer> composers;
string GenerateSnippet()
{
foreach(var composer in composers)
{
composer.DoStuff();
}
...
...
}
}
Run Code Online (Sandbox Code Playgroud)
当然,现在关系已经颠倒了,你的代码树或它的创建者必须为它定义作曲家集合.