【說明】
引用了組里面的一架構(gòu)師的文章,寫的很好的,尤其是偏于抽象的部分。希望對新手有用。
使用CommonNavigator開發(fā)資源管理器--模型篇
在基礎(chǔ)篇中,已經(jīng)通過例子初步說明了,如何基于CNF制作一個簡單的資源管理器,但很多開發(fā)人員并不理解,樹上的結(jié)點是如何得到的,這就涉及到CNF的模型。在詳述CNF的模型之前,需要先對Tree所使用的模型進(jìn)行描述。
對于早期習(xí)慣C/S開發(fā)的程序員來說,對于SWT中的Tree并不陌生,可以通過相應(yīng)的TreeItem來創(chuàng)建子結(jié)點,但是這并不是一種好的設(shè)計和使用方式,它大大的增加了模型與UI之間的耦合度,所以在Swing中,使用了TreeNode來描述樹模型,而Eclipse則通過JFace提供了ITreeContentProvider接口來描述樹模型。這兩種方式有異曲同工之處,大家可以看一下這兩個接口,就會發(fā)現(xiàn)兩者非常之雷同,最大的區(qū)別在于前者通過userObject持有真實的數(shù)據(jù),而后者則是由TreeItem的getData來持有,在使用的時候,才會由相應(yīng)的TreeViewer傳給ITreeContentProvider,從結(jié)構(gòu)來說,后者是一個純粹的控制類,而TreeNode則是更靈活一些,可以作為一個控制類,也可以作為一個模型體,所以相對而言,TreeNode更加靈活一些,但從本質(zhì)上而言,兩者并無區(qū)別。
表面上看來,一個TreeViewer將會擁有一個ITreeContentProvider用來取得樹狀的數(shù)據(jù)模型,進(jìn)而呈現(xiàn)出來,但CNF中的樹卻更加靈活,在基礎(chǔ)篇中,展現(xiàn)的圖中,卻表示可以通過擴展點org.eclipse.ui.navigator.navigatorContent來添加新的結(jié)點,而且這些與資源并沒有本質(zhì)的關(guān)系,它可以與一個具體的文件或者目錄資源綁定,也可以與多個具體的文件或者目錄綁定,還可以是一個與文件或者目錄無關(guān)的模型。那么現(xiàn)在來看一下CNF到底做了哪些事情,使得它的模型擴展如此容易呢?
首先啟動Eclipse32.,然后創(chuàng)建一個新的工作區(qū),再將CNF相關(guān)的代碼以插件的形式導(dǎo)入到這個工作區(qū)中,開始我們的分析過程。
講到這里,要提到Eclipse提供的一個接口IWorkbenchAdapter和IWorkbenchAdapter2,這兩個接口是有一點點怪的,因為從設(shè)計的角度來看,它將模型與展現(xiàn)層混合在一起,違反常見的設(shè)計準(zhǔn)則,但從另一個角度來講,它可以減少用戶擴展的內(nèi)容,有利于用戶開發(fā)。由此可見設(shè)計準(zhǔn)則并不是一成不變的,很多時候,它也要在易用性和合理性方面做出適當(dāng)?shù)耐讌f(xié)。這一點也可以在我們自己的設(shè)計中加以考慮,設(shè)計并不是要偏向哪一個方向,恰恰相反,設(shè)計是要在多者之間,如易用性,穩(wěn)定性,合理性之間取得一個平衡點,而不是在各方面都做到完美。
另外ITreeContentProvider有一個方法getParent(Object parent),它是用來為一個指定結(jié)點找到相應(yīng)的父親結(jié)點,從而便于查找和定位,而這個方法卻被很多人所忽視,開發(fā)人員經(jīng)常會習(xí)慣性的直接返回null,而且也不會出現(xiàn)什么錯誤,但這個方法其實卻是一個非常有用的方法,開發(fā)人員在使用Java資源管理器的時候,有一個經(jīng)常使用的功能就是LinkWithEditor,這個功能經(jīng)常是用來在資源管理器上定位當(dāng)前打開的文件,這個功能如此之重要,以至于CNF專門為此定義了一個org.eclipse.ui.navigator.linkHelper來支持該功能。所以請根據(jù)實際情況,來實現(xiàn)這個方法,否則就無法正確的實現(xiàn)相應(yīng)的功能。
以上對TreeViewer的模型進(jìn)行了簡單的介紹和分析,接下來就看一下CNF是如何處理樹模型從而獲得如此高的靈活性。
CNF很好的利用了代理模式,它自身并沒有提供模型的能力,所以它將提供模型的能力仍然交給外部擴展點提供的類,它會根據(jù)當(dāng)前要處理的結(jié)點,以及每個擴展點的表達(dá)式,來找出能夠處理當(dāng)前結(jié)點的ITreeContentProvider實例,然后再將這些實例返回的子結(jié)點放入相應(yīng)的Set中,最終以數(shù)組的方式返回給TreeViewer,從表面上來看,可能很難理解正常情況下,每個TreeViewer只有一個ITreeContentProvider的模型接口,如何能夠從多個實例中取得模型呢?就是由NavigatorContentServiceContentProvider這個代理類完成模型的組合功能。
因此只要提供自己的ITreeContentProvidre實現(xiàn),然后通過擴展點掛入,即可將各種真實或者虛擬的模型掛入系統(tǒng)。
本博客中的所有文章、隨筆除了標(biāo)題中含有引用或者轉(zhuǎn)載字樣的,其他均為原創(chuàng)。轉(zhuǎn)載請注明出處,謝謝!