浏览 3355 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-09-11
http://www.meteortl.org)优势列表中的主控Iterator模式优势具体指什么。
有朋友问我MeteorTL(buaawhl的帖子已经分析很多: http://www.iteye.com/topic/21293 我再补充的说一下: Visitor模式使用最多的时候是处理合成模式的树结构, 估计是受[GoF95]的影响,书中提倡将树结构的表示与逻辑分开, 这样不同的Visitor对同一树结构可以做不同的事,以达到重用及扩展, 如:将一个模板解析成树后,针对同一树结构表示,EvaluationVisitor可以输出模板结果, BackupVisitor可以备份树,CountVisitor可以统计树中的节点... 这种思想很好,但实际中,如果以Visitor风格导出API,API很难理解,也很难使用, 因为扩展方很被动,并不是每一次使用树都是要做遍历操作的, 而且,Visitor通常会很大,因为它要处理所有节点类型,通常是用很多类型重载的visit方法, 再者,往往最后都是,整个系统只有一个Visitor,因为Visitor的实现很复杂, 其实Visitor模式的优势Iterator模式都能作到, 如果改用Iterator模式,可以使用解释器模式的层级调用, 在主控函数中回调Handler,以及发布访问前后Event,再加上个AOP拦截器链, 扩展者可以只Handle某一个节点类型的处理,也可通过监听事件处理周边事物,或者通过AOP统一处理所有节点, 灵活性远远超过Visitor模式, 如:FreeMarker, Velocity都使用了Visitor模式,扩展性是极其受限的,这可能是由于它们都使用JavaCC作为解板工具,而JavaCC生成Visitor模式的解析代码,有点被迫使用。 而MeteorTL(http://www.meteortl.org)则使用Iterator模式,在扩展性方面就很有优势。 节点的扩展是经常用到的,举个例对比一下: Visitor模式的: public class NodeHandler { public static final int DO_BODY = 1; ... // 因为Node是被动的,所以返回一个数字控制Visitor的遍历路线, // 除非只作正规的前序遍历,就能满足你所有的需求,则可以不返回值, public int handle() { // 返回1,继续访问内部节点 // 返回2,继续访问下一兄弟节点 // 返回3,表示重复当前节点 // 返回4,表示跳过后面所有节点 // ... } } 看到上面的方式,估计写过JSP Tag Lib的朋友印象深刻,doStrat, doEnd就是这么做的。 调用者(JSP引擎相当于调用者)也很费神,要一个个判断状态位,if...else...估计是一大堆。 如果你的需求超过了上面的1, 2, 3, 4...,那就没办法,等新版本发布可能会有:-) Iterator模式的: public class NodeHandler { // 每个节点持有自己的子节点,解析树时置入 Node[] childNodes; public void handle() { // 1.如果要忽略子节点,直接将函数留空 // 2.如果要运行字节点 handleChildNodes(); // 3.如果要迭代子节点n次 for (int i = 0, i < n; i ++) { handleChildNodes(); } } private void handleChildNodes() { for(int i = 0, n = childNodes.length; i < n; i ++) { childNodes[i].handle(); } } } 调用者只需要调用根节点的handle(),根节点将调用其所有子节点,层级调用下去就完成了遍历,需不需要调用下级节点完全是主控的。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2008-01-12
对楼主的项目不熟悉。
Visitor模式确实很不好,Visitor接口要依赖于被访问的各个具体子类,请楼主讲解一下Iterator模式如何替代Visitor模式并允许被访问接口新增子类的,谢谢! |
|
返回顶楼 | |