接口继承层次结构

时间:2016-04-29 16:35:06

标签: c# oop design-patterns

作为代码重构的一部分,我发现了一些我试图删除的代码重复

我有一个如下所示的界面,在一个我无法修改的程序集中。

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)

有更好的方法吗?

2 个答案:

答案 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开始继承您自己的访问者。您只会覆盖实际需要的方法。

访问者模式不是非常可扩展的。仅当一组继承者是固定的并且不会发生显着变化时,它才有用。不过,如果你正确使用它,它将很好地解决你的双重调度问题。