以前的幾次帖子中,我們都談到了在UI平臺的設(shè)計過程中常常會使用的一種設(shè)計模式,就是封裝,但是封裝是一種極難把握的模式,而且,單單使用封裝往往也起不到任何設(shè)計效果,有時還會畫蛇添足,那么,大師們是怎么使用封裝的呢,我們看看Java領(lǐng)域的例子。
Swing是
由Sun的優(yōu)秀科學(xué)家和Netscape的杰出設(shè)計師共同創(chuàng)造出來的卓越的架構(gòu)。它一生下來就擁有皇族血統(tǒng),但注定一生都不會取得王位。現(xiàn)在崇拜
Eclipse設(shè)計架構(gòu)的人比較多(包括我),隨之而來的是對Swing的批評聲也很多(不包括我),其實這是一種錯誤的認識,就像
Smalltalk是一種很優(yōu)秀但使用較少的語言,VB和Foxpro則屬于那種天生拙劣但使用廣泛的語言。Swing比Eclipse架構(gòu)早出來好幾
年,后者從前者那里吸取了不少的經(jīng)驗,也借鑒了很多模式,才會有今天的成就。而直到今天Swing仍然有很多值得我們學(xué)習(xí)的地方。
再說封
裝,打開JButton的源代碼就會發(fā)現(xiàn),JButton沒有往可憐的Windows界面上畫上任何一筆,換句話說,整個類里面一行繪圖代碼都沒有,這是
為什么?因為JButton是一個Controller的變種,繪圖組件由另一個類提供,這個類以UI名字結(jié)尾,在內(nèi)部包中,且繪圖器在不同的界面風(fēng)格
下、不同的操作系統(tǒng)、甚至不同的語種下面有不同的實現(xiàn)。這使得JButton類四兩撥千斤,憑一個不變的框架同時實現(xiàn)了跨平臺和可插拔風(fēng)格。至于它的一些
顯示參數(shù),別著急,既然有C有V不可能沒有M啊,ButtonModel類負責維護JButton的參數(shù)。
我們再看卓越的Eclipse,Eclipse比其這種封裝來說就要復(fù)雜的多了,我們分成六個環(huán)節(jié)來講。
1。Eclipse將Windows的繪制方法包裝成SWT,這種包裝很原始,但是很有效,因為Java不好調(diào)用Win32API,所以這一步實現(xiàn)了跨平臺。需要注意的是,這種包裝應(yīng)該屬于簡單的分層,Eclipse編寫了一個操作系統(tǒng)的Facade,OS類,這個類的win32版的源代碼有2734行,顯然是個龐然大物啦。
2。Eclipse把SWT當作它的基本組件來重用,(就好像這是別人寫的東西),它把SWT的組件繼續(xù)包裝成JFace,JFace采用真正意義上的 MVC模式,比起緊湊的SWT來要活潑一點。JFace把SWT當成它的View,把Provider的實現(xiàn)當作它的Model,把自己包里的可控的帶有組件邏輯的Viewer類當成Controller。
3。由于SWT被設(shè)計用來繪制窗體組件,按照管理,應(yīng)該有一個包被用來繪制二維圖形,這個工作就交給Draw2D來完成,它被放置在GEF包中,和SWT 處在一個層次。需要注意的是,Draw2D與SWT的組織機制不同(見前面的文章)。
4。Eclipse繼續(xù)封裝,因為JFace只解決了高級組件的問題,并不能直接放在Workbench里面用,所以Eclipse制作了Workbench包,這個包把Viewer封裝成ViewPart,它認為Viewer是繪制器,而ContentProvider是Model,所以,像之前的幾次一樣,ViewPart變成了Controller。
5。有了ViewPart也就有了EditorPart,這兩種Part都有可能要顯示Form表單(一
種類似HTML的界面),表單上的控件——理所當然,是由
SWT實現(xiàn)的——與一般意義上的控件有很大的不同,這種不同主要體現(xiàn)在展現(xiàn)方式和事件通知上。Eclipse采取的方式是另做一套內(nèi)部實現(xiàn),包裝SWT實
現(xiàn),比如SWT有一個Button,表單包也有一個表單Button,與Button通過一個Toolkit類轉(zhuǎn)換。這種方式就是設(shè)計模式中提到的
Proxy。
6。現(xiàn)在我們再看看需要繪二維圖的EditorPart,這個部分是通過GEF來實現(xiàn)的,GEF是比JFace和Workbench更嚴格的MVC,它再EditorPart的基礎(chǔ)上再包裝一次,將策略等控件業(yè)務(wù)與控件繪制分離。
今
天我得到的最重要的一個結(jié)論,就是封裝是相對的,MVC也是相對的,因此在JFace看來是Controller的東西在Workbench來看可能是
View,這可能導(dǎo)致在設(shè)計時的大量爭議。今天的另一個收獲是發(fā)現(xiàn)了封裝也有幾類,我能想到的應(yīng)該有Facade封裝、Proxy封裝、MVC封裝三種,
你還能想到更多的嗎?
做軟件的泡泡