C#泛型: 消除Visitor模式的循環相依性, 以及無聊的Accept方法

來源:互聯網
上載者:User

 

前幾天跟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)        {        }    }

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.