`
chelsea
  • 浏览: 112155 次
  • 来自: ...
社区版块
存档分类
最新评论

C#泛型: 消除Visitor模式的循环依赖, 以及无聊的Accept方法

    博客分类:
 
阅读更多

1. 经典的Visitor模式(循环依赖)

 

    public interface Document

    {

        void Accept(DocumentVisitor visitor);

    }

 

    public class WordDocument : Document

    {

        public void Accept(DocumentVisitor visitor)

        {

            visitor.Visit(this);

        }

    }

 

    public class ExcelDocument : Document

    {

        public void Accept(DocumentVisitor visitor)

        {

            visitor.Visit(this);

        }

    }

 

    public interface DocumentVisitor

    {

        void Visit(WordDocument wordDocument);

        void Visit(ExcelDocument excelDocument);

    }

 

这里面 Document依赖于DocumentVisitor, DocumentVisitor依赖于WordDocument和ExcelDocument, 而WrodDocument等又依赖于Document

这样 Document->DocumentVisitor->WordDocument->Document->...循环依赖

 

2. 经典的解依赖Visitor模式(Down Cast)

 

    public interface Document

    {

        void Accept(DocumentVisitor visitor);

    }

 

    public class WordDocument : Document

    {

        public void Accept(DocumentVisitor visitor)

        {

            if (visitor is WordDocumentVisitor)

            {

                ((WordDocumentVisitor)visitor).Visit(this);

            }

        }

    }

 

    public class ExcelDocument : Document

    {

        public void Accept(DocumentVisitor visitor)

        {

            if (visitor is ExcelDocumentVisitor)

            {

                ((ExcelDocumentVisitor)visitor).Visit(this);

            }

        }

    }

 

    public interface DocumentVisitor

    {

        //空接口, 依赖在这里断掉了

    }

 

    public class ExcelDocumentVisitor : DocumentVisitor

    {

        public void Visit(ExcelDocument excelDocument)

        {

 

        }

    }

 

    public class WordDocumentVisitor : DocumentVisitor

    {

        public void Visit(WordDocument wordDocument)

        {

        }

    }

 

3. 消除无聊Accept()方法的Visitor模式

 

上面的Accept方法几乎千篇一律, 遵循相同的模式. 里面无非就是类型计算, 可以利用C#的泛型支持将之消除

 

    public interface Document

    {

        void Accept(DocumentVisitor visitor);

    }

 

    public abstract class VisitableDocument<T> : Document where T : VisitableDocument<T>

    {

        public void Accept(DocumentVisitor visitor)

        {

            var interfaces = visitor.GetType().GetInterfaces();

 

            foreach (var type in interfaces)

            {

                if (type.GetGenericArguments().Contains(typeof(T)))

                {

                    ((DocumentVisitor<T>)visitor).Visit((T)this);

                }

            }

        }

    }

 

    public class WordDocument : VisitableDocument<WordDocument>

    {

        //不需要自己实现Accept, 基类已经实现

    }

 

    public class ExcelDocument : VisitableDocument<ExcelDocument>

    {

        //不需要自己实现Accept, 基类已经实现

    }

 

    public interface DocumentVisitor

    {

        //空接口

    }

 

    public interface DocumentVisitor<T> : DocumentVisitor where T : VisitableDocument<T>

    {

        //泛型, 依赖在这里断掉了

        void Visit(T document);

    }

 

    public class PrintDocumentVisitor : DocumentVisitor<WordDocument>, DocumentVisitor<ExcelDocument>

    {

        public void Visit(WordDocument wordDocument)

        {

        }

 

        public void Visit(ExcelDocument excelDocument)

        {

        }

    }


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics