作为代码重构的一部分,我发现了一些我试图删除的代码重复
我有一个如下所示的界面,在一个我无法修改的程序集中。
public interface IArtifact
{
void Accept(IArtifactVisitor visitor);
}
public interface IArtifactVisitor
{
void Visit(Topic topic);
}
在我想重用现有接口的引用程序集中,有相同的函数签名
public interface IArtifact
{
void Accept(IArtifactVisitor visitor);
}
public interface IArtifactVisitor
{
void Visit(Topic topic);
void Visit(NewTopic topic);
}
并且Accept看起来像这样
public void Accept(IArtifactVisitor visitor)
{
visitor.Visit(this);
}
为了删除代码重用,我尝试了以下内容:
public interface MyIArtifact : IArtifact
{
void Accept(MyIArtifactVisitor visitor);
}
public interface MyIArtifactVisitor : IArtifactVisitor
{
void Visit(NewTopic topic);
}
但它的作用是,它迫使我在每个实现类中实现Accept(MyIArtifactVisitor visitor)和Accept(IArtifactVisitor visitor)
有更好的方法吗?
答案 0 :(得分:4)
如果我正确理解您的问题,您只需在界面中指定一个方法签名
public interface MyIArtifactVisitor : IArtifactVisitor
{
void Visit(NewTopic topic);
}
基本上就是这样。所以,如果你想要这个,以及外部接口,那么你会做类似下面的事情
public class MyImplimentingClass : MyIArtifactVisitor, IArtifactVisitor
{
public void Visit(NewTopic topic)
{}
public void Visit(Topic topic)
{}
}
答案 1 :(得分:1)
访问者模式搞砸了,恕我直言,通过接口实现它是没有意义的。实现访问者模式的方式如下:
abstract class Artifact{
internal abstract void Visit(ArtifactVisitor visitor);
}
class Topic : Artifact{
internal override void Visit(ArtifactVisitor visitor)
{
visitor.Visit(this);
}
}
class ArtifactVisitor{
internal virtual void Visit(Artifact artifact)
{
artifact.Visit(this);
}
protected virtual void Visit(Topic topic)
{
}
}
class SomeSpecificTopicVisitor : ArtifactVisitor
{
protected override void Visit(Topic topic)
{
//do something with topics
}
}
从此状态开始,您可以从ArtifactVisitor开始继承您自己的访问者。您只会覆盖实际需要的方法。
访问者模式不是非常可扩展的。仅当一组继承者是固定的并且不会发生显着变化时,它才有用。不过,如果你正确使用它,它将很好地解决你的双重调度问题。