Modern C++ Design 笔记 第十章 Visitor

从开始学习设计模式的时候,就有一个概念,visitor是一个鸡肋模式.由于visitor模式对于类结构稳定性的要求非常高,所以其实自己感觉在现实生活中的运用很少.(在现实中一般总可以,或者总趋向于添加一个虚函数接口了事).

当然visitor不止现在这个问题,另一个突出的问题就是循环依赖.这对于C++来说,或者说对于OO来说都是一个尴尬的问题,在<<C++ coding standard>>中也提及了"第22条 尽量减少定义性依赖。避免循环依赖  "而其中的例子恰恰就是这个visitor.

 

现在让我们来揭开这块visitor的遮羞布,最开始,我们先看看传统的visitor的UML图.

general visitor

我们可以清楚的从这个图上看到这几点依赖:

1. DocElement作为元素的基类依赖于DocElementVisitor的基类

2. DocElementVisitor依赖于DocElement的所有派生类包括Paragraph和RasterBitmap

3. 所有的DocElement的派生类当然依赖与DocElement类!

就这样一个环出现了!!!所以在这里直观的想法就是这样一个模式有点不make sense. 就是基于这样的一个考虑,在这一章里面,作者非常乐意分享一下他的Acyclic visitor.注意这个Acyclic的意思就是不循环的.

当然在展开书中的实现之前,先看看普通的是实现是怎么样的. Robert C. Martin帮助我们找到了症结,给出了解决方案. 其实我们直观的想法就是如果这个Visitor可以不包含所有的visit(ELement& ele)(派生类)的接口,或者说在只在Visitor这个类里面不出现就非常好了! 而这里的解决方案也确实用到了这样的想法.

acyclic visitor

这里的方案就是DocStatus不从DocElementVisitor继承下来,而是同时也从RasterBitmapVisitor和ParagraphVisitor继承下来,那就是说, 也就是说在Paragraph在accept的时候,把visitor&转化成了ParagraphVisitor,当然你在ParagraphVisitor里面可以很从容的让他访问DocStats的VisitParagraph接口实现(因为在ParagraphVisitor这个函数是纯虚函数).这样兜了一个大圈子找到了DocStats的对应函数.至少现在的结构消除了循环的依赖,可以看到的是DocElementVisitor不再需要任何一个具体的Visitorxxx的接口,而只是一个纯虚析构函数的申明.

 

之后给出的一个acyclic visitor的模板实现完全参照了这样的想法.里面的亮点就在于这个函数实现:

 

 

 

这个protected函数只需要派生类都有DEFINE_VISITABLE()的宏定义就可以直接调用.

另一点值得注意的就是这个最后一句return ReturnType(); 这个在文中有些CatchAll模板的策略我们就不展开了,为一个不喜欢的且不是很成功模式说了这么多似乎有点多了:)

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值