C#泛型: 消除Visitor模式的循环依赖, 以及无聊的Accept方法
2010-03-15 23:37
399 查看
前几天跟Yuan Ye Pair的时候发现了这个方法
1. 经典的Visitor模式(循环依赖)
这里面 Document依赖于DocumentVisitor, DocumentVisitor依赖于WordDocument和ExcelDocument, 而WrodDocument等又依赖于Document
这样 Document->DocumentVisitor->WordDocument->Document->...循环依赖2. 经典的解依赖Visitor模式(Down Cast)
3. 消除无聊Accept()方法的Visitor模式
上面的Accept方法几乎千篇一律, 遵循相同的模式. 里面无非就是类型计算, 可以利用C#的泛型支持将之消除
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) { } }
相关文章推荐
- C#泛型: 消除Visitor模式的循环依赖, 以及无聊的Accept方法
- 消除VISITOR模式中的循环依赖
- OpenCL优化方法-消除访问内存数组引起的循环依赖关系
- python基础===文件对象的访问模式,以及计数循环的使用方法
- 关于npm无法安装依赖包以及安装包缓慢的解决方法
- 【BETA】Mac技巧之查看苹果电脑 Mac OS X 系统是否开启 64 位运算,以及设置 32/64 位模式的方法
- yii2 commands模式以及配置crontab定时任务的方法
- 使用ffmpeg循环推流(循环读取视频文件)方法以及局限
- 读书笔记之工厂方法模式以及简单工厂模式
- python pandas消除空值和空格以及 Nan数据替换方法
- 模式识别初体验——模式识别中要处理的问题以及使用的方法
- java设计模式之工厂方法模式以及简单工厂模式还有抽象工厂模式
- windows xp 系统下安装完oracle后,设置归档模式的过程以及方法!
- 循环队列的判断满、空的三种方法以及具体代码实现(数组实现)
- ios - 图片自动轮播定时器(NSTimer)以及消息循环模式简介
- Android中Calendar与Date的区别以及消除时区对日期操作影响的方法
- 再谈STM32的CAN过滤器-bxCAN的过滤器的4种工作模式以及使用方法总结
- ubuntu安装依赖:0.8.1-1ubuntu4.4 正要被安装以及vm nested解决方法
- 解析PHP跳出循环的方法以及continue、break、exit的区别介绍
- aar依赖初试, 使用android studio制作aar包以及依赖方法