Composite模式和树形结构的讨论

banq 05-11-22
                   

最近在使用Jdon框架做JiveJdon3,碰到一个老问题,主题帖和回帖之间是树形结构关系,现在碰到两种方案:

1. 采取Composite模式封装复杂的树形结构,这样外界要访问一个主题贴需要树形遍历时,由Composite内部来树形算法来遍历,外界只要告诉要怎样的结果即可。
优点:封装了树形结构的遍历算法,外界客户端无需自行进行帖子的树形结构相关判断代码。
缺点:对树形结构的操作有各种各样,而且以后可能有新增新的操作,这可能涉及修改Composite模式的Component接口。
Composite模式:http://www.jdon.com/designpatterns/composite.htm

这种采取Composite模式封装树形结构遍历的方法,为防止新增新的操作改动接口,可引入访问者模式,下面这篇文章谈到了用C++实现Composite模式+Visitor模式解决树形结构封装算法:
http://members.home.nl/r.f.pels/articles/misc/C++PatternsAndTreesSeparatingKnowledge.html
它主要讨论了如何分离树形结构的不同类的对象和用户界面的树形结构表现这两个方面。


2.不采取Composite模式进行树形结构封装,就象原来Jive一样,给每个主题贴提供一个TreeWalker对象,这样外界如果要遍历这个主题贴时,自己通过TreeWalker去遍历树形结构。
优点:比较符合模型编程,ForumThread主题贴是一个模型,里面提供一个自身树形结构遍历,非常开放,外界客户端有新的操作,只要得到模型ForumThread就可以了。
缺点:TreeWalker提供的树形结构遍历方法有限,有可能不能满足新的操作或新的功能的需要。

有过这方面考虑的人可一同讨论一下。

                   

1
banq
2005-11-23 14:38

这条题目其实应该算非常难的一道题,涉及到GoF模式中两个较不常用的模式,而且又解决了日常编程中经常碰到的对象树形结构问题,请真正大牛的人来解决这个实际问题吧。我原意洗耳恭听。是显示您真正水平的时候了。

whatavery
2005-11-25 16:56

在这里回复是不是也太不知天高地厚了,因为和banq老师的水平差的不是一点半点了。

我认为TreeWalker是优于Composite,我在用Composite的时候更倾向于那种隐性的树模式。至使连有些客户并在UI上并看不出来。但是这种替代结构我一直不敢特别肯定他的整和/扩展程度,而需要结合其他模式如Visitor,Adapter等来扩展。

所谓替代结构,如
Polymorphism把if/switch Refactoring掉
Iterator把for Refactoring掉
Composite把纯tree Refactoring掉
等等

对于这些很纯的tree,我认为类似于TreeModel/DefaultTreeModel这种封装型的才是最好扩展的。而Composite在增加系统复杂度的情况下实现,表面上看结构是清楚的,但效率和扩展度,都没直接的tree封装来的痛快。

因为和banq老师差的水平太多,所以只提供一个投票性的意见,我是第一次发帖子。谢谢banq老师写了那么多精彩的文章,其实我回帖不是目的,只是来景仰一下banq老师

鲁中正气
2005-11-26 20:40

所谓替代结构,如
Iterator把for Refactoring掉
Composite把纯tree Refactoring掉

好!好!口诀阿。
不过,Polymorphism把if/switch Refactoring掉
除了Polymorphism还可以用其他方式吧

banq
2005-11-29 16:10

whatavery这方面是有一定研究。

TreeWalker/TreeModel和Composite相比,要简单直接多。

Composite模式是一种内敛式样或者趋向闭合的模式,该模式是将以前在客户端中实现的代码强制收回,这对一个Open开放结构有所伤害。

因此,一般使用Composite模式都要结合Visitor模式,但是,
使用Composite+Visitor模式带来缺点是:对访问者进行了一定限制,例如可能只是需要一个帖子集合,必须将将这段代码变成一个访问者类。

但是,如果单纯使用TreeWalker/TreeModel,TreeModel中只封装了常见的树操作,万一有新的特殊树操作,需要更改TreeModel接口,而且TreeWalker客户端会拥有自己对树结构遍历的代码,需要增加新功能或维护时,都需要维护者对这个树了解,可维护和可拓展差。

现在,我采用的方案是:TreeWalker/TreeModel和Composite+Visitor两个结合,我通过TreeWalkerService以服务形式向外提供常见的树操作,而TreeWalkerService内部的实现是通过Composite+Visitor实现的。当在组件层以后需要有新的树结构操作时,使用Composite+Visitor实现。

也就是说:Composite+Visitor在组件层封装了树形结构,这样在组件层各处就没有零星散落的涉及树形结构操作的代码,如果你需要将这组树形结构数据转化为XML,那么做一个Visitor方法即可。如果在表现层需要操作树形结构,只能通过TreeWalkerService了。

这样做到通用和定制,简单和复杂实现一定的统一。
以上只是个人观点,欢迎讨论。





3Go 1 2 3 下一页