您的位置:首页 > 编程语言 > C#

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

2010-03-15 23:37 399 查看
前几天跟Yuan Ye Pair的时候发现了这个方法
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)
        {
        }
    }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐