以前的几次帖子中,我们都谈到了在UI平台的设计过程中常常会使用的一种设计模式,就是封装,但是封装是一种极难把握的模式,而且,单单使用封装往往也起不到任何设计效果,有时还会画蛇添足,那么,大师们是怎么使用封装的呢,我们看看Java领域的例子。
Swing是
由Sun的优秀科学家和Netscape的杰出设计师共同创造出来的卓越的架构。它一生下来就拥有皇族血统,但注定一生都不会取得王位。现在崇拜
Eclipse设计架构的人比较多(包括我),随之而来的是对Swing的批评声也很多(不包括我),其实这是一种错误的认识,就像
Smalltalk是一种很优秀但使用较少的语言,VB和Foxpro则属于那种天生拙劣但使用广泛的语言。Swing比Eclipse架构早出来好几
年,后者从前者那里吸取了不少的经验,也借鉴了很多模式,才会有今天的成就。而直到今天Swing仍然有很多值得我们学习的地方。
再说封
装,打开JButton的源代码就会发现,JButton没有往可怜的Windows界面上画上任何一笔,换句话说,整个类里面一行绘图代码都没有,这是
为什么?因为JButton是一个Controller的变种,绘图组件由另一个类提供,这个类以UI名字结尾,在内部包中,且绘图器在不同的界面风格
下、不同的操作系统、甚至不同的语种下面有不同的实现。这使得JButton类四两拨千斤,凭一个不变的框架同时实现了跨平台和可插拔风格。至于它的一些
显示参数,别着急,既然有C有V不可能没有M啊,ButtonModel类负责维护JButton的参数。
我们再看卓越的Eclipse,Eclipse比其这种封装来说就要复杂的多了,我们分成六个环节来讲。
1。Eclipse将Windows的绘制方法包装成
SWT,这种包装很原始,但是很有效,因为Java不好调用Win32API,所以这一步实现了跨平台。需要注意的是,这种包装应该属于简单的分层,Eclipse编写了一个操作系统的Facade,OS类,这个类的win32版的源代码有2734行,显然是个庞然大物啦。
2。Eclipse把SWT当作它的基本组件来重用,(就好像这是别人写的东西),它把SWT的组件继续包装成
JFace,JFace采用真正意义上的 MVC模式,比起紧凑的SWT来要活泼一点。JFace把SWT当成它的View,把Provider的实现当作它的Model,把自己包里的可控的带有组件逻辑的Viewer类当成Controller。
3。由于SWT被设计用来绘制窗体组件,按照管理,应该有一个包被用来绘制二维图形,这个工作就交给
Draw2D来完成,它被放置在GEF包中,和SWT 处在一个层次。需要注意的是,Draw2D与SWT的组织机制不同(见
前面的文章)。
4。Eclipse继续封装,因为JFace只解决了高级组件的问题,并不能直接放在Workbench里面用,所以Eclipse制作了
Workbench包,这个包把Viewer封装成ViewPart,它认为Viewer是绘制器,而ContentProvider是Model,所以,像之前的几次一样,ViewPart变成了Controller。
5。有了ViewPart也就有了EditorPart,这两种Part都有可能要显示
Form表单(一
种类似HTML的界面),表单上的控件——理所当然,是由
SWT实现的——与一般意义上的控件有很大的不同,这种不同主要体现在展现方式和事件通知上。Eclipse采取的方式是另做一套内部实现,包装SWT实
现,比如SWT有一个Button,表单包也有一个表单Button,与Button通过一个Toolkit类转换。这种方式就是设计模式中提到的
Proxy。
6。现在我们再看看需要绘二维图的EditorPart,这个部分是通过
GEF来实现的,GEF是比JFace和Workbench更严格的MVC,它再EditorPart的基础上再包装一次,将策略等控件业务与控件绘制分离。
今
天我得到的最重要的一个结论,就是封装是相对的,MVC也是相对的,因此在JFace看来是Controller的东西在Workbench来看可能是
View,这可能导致在设计时的大量争议。今天的另一个收获是发现了封装也有几类,我能想到的应该有Facade封装、Proxy封装、MVC封装三种,
你还能想到更多的吗?
做软件的泡泡
posted on 2005-03-23 01:26
Brian Sun 阅读(2153)
评论(0) 编辑 收藏 所属分类:
软件