




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、前言Jive是一個開放的Java源代碼項目。其目標是建設(shè)一個開放結(jié)木的,強壯的,易于擴展的基于JSP的論壇。在其設(shè)計目標的指導(dǎo)下,其結(jié)構(gòu)設(shè)計得非常得好,融合了很多新的觀念,比如DesignPattern,可更換的Skin,可插入Plug等等。詳細解讀其源代碼對于理解這些新的設(shè)計上的概念是很有裨益的。如果你對DesignPattern和Java語言有一定的了解,但是還是會時常迷惑于其中的話,不妨研究研究Jive源代碼,一定會對其中的很多概念有更7入的理解。這篇文章源于我的Jive源代碼研究筆記,希望能夠提綱挈領(lǐng),帶領(lǐng)大家進入到這個美好的世界。當然,如果沒有時間仔細地看源代碼的話,看看這篇文章,我
2、想也是會有一些幫助的。再開始之前,需要指出的是,Jive中對DesignPattern的應(yīng)用,并沒有拘禮與GOF書中所給出的實現(xiàn)方法,而是有許多變通的地方。一方面,我想是由于具體的實際需要,另一方面,我想這也是設(shè)計觀念進化的結(jié)果吧。因而,這些變通的地方,將是我講解的重點。整體結(jié)構(gòu)概敘基于一個OO的設(shè)計原則:面向接口編程,而不是針對實現(xiàn)編程。Jive在設(shè)計的時候,把其大部分的基本對象都設(shè)計為接口或者抽象類。在Jive中,基本的接口有Forum,ForumMessage,ForumThread,Group,User,Authorization和Query。我們可以很容易的從這些接口的名字來知道他們
3、的功用,下面的類圖給出了這些類之間的一些靜態(tài)關(guān)系:圖1:Jive整體關(guān)系你可能會有疑問,為什么會都是接口呢?這是基于擴展性考慮的。在Jive給出的實現(xiàn)中,所有的這些接口,F(xiàn)orum,ForumMessage,User等等,都使用數(shù)據(jù)庫來實現(xiàn)的,一條消息,或者一個用戶對應(yīng)于數(shù)據(jù)庫中的一條消息Jive使用了DbForum,DbForumMessage,DbUser等類來實現(xiàn)這些接口,通過JDBC來操作數(shù)據(jù)庫,使之作為論壇的底層支撐。然而,有時候,或許我們并不想使用數(shù)據(jù)庫,比如我們想只是使用文件系統(tǒng)來作為論壇的底層支撐,這時候,我們需要做的只是編碼實現(xiàn)了Forum等等接口的諸如FileFroum,F
4、ileForumMessage等對象,然后嵌入Jive中即可,原有的任何代碼都可以不用改變!這就是面向接口編程的威力了!下面來看看具體的設(shè)計和編碼。AbstractFactory模式和可擴展性如果要實現(xiàn)較好的可擴展性,AbstractFactory模式確實是一件利器。如上面所說,如果要創(chuàng)建的Forum接口的不同實現(xiàn),而又不想更改代碼的話,就需要用到抽象工廠了。再Jive中,AuthorizationFactory類是一個抽象類,用來創(chuàng)建Authorization對象。這是一個抽象工廠,可以通過不同的子類來創(chuàng)建不同的Authorization對象。這個工廠的實現(xiàn)方法是:在Authorizatio
5、nFactory中使用一個privatestatic變量factory,用來引用具體的抽象工廠的實例:privatestaticAuthorizationFactoryfactory=null;用一個privatestatic的String,來指明具體的抽象工廠的子類類名:privatestaticStringclassName="com.coolservlets.forum.database.DbAuthorizationFactory"然后是用一個privatestatic的loadAuthorizationFactory方法來給這個factory變量賦值,生成具體的抽
6、象工廠類:privatestaticvoidloadAuthorizationFactory()if(factory=null)synchronized(className)if(factory=null)StringclassNameProp=PropertyManager.getProperty("AuthorizationFactory.className");if(classNameProp!=null)className=classNameProp;tryClassc=Class.forName(className);factory=(AuthorizationF
7、actory)c.newInstance();catch(Exceptione)System.err.println("Exceptionloadingclass:"+e);e.printStackTrace();factory變量,然這個在static的getAuthorization方法返回一個Authorization的過程中,先初始化工廠類后用factory的createAuthorization方法來創(chuàng)建:publicstaticAuthorizationgetAuthorization(Stringusername,Stringpassword)throwsUn
8、authorizedExceptionloadAuthorizationFactory();returnfactory.createAuthorization(username,password);)不同的子類有不同的createAuthorization方法的實現(xiàn)。比如在DbAuthorizationFactoryAuthorizationFactory的數(shù)據(jù)庫實現(xiàn)子類中,createAuthorization方法是這樣實現(xiàn)的:publicAuthorizationcreateAuthorization(Stringusername,Stringpassword)throwsUnauthor
9、izedExceptionif(username=null|password=null)thrownewUnauthorizedException();)password=StringUtils.hash(password);intuserID=0;Connectioncon=null;PreparedStatementpstmt=null;trycon=DbConnectionManager.getConnection();pstmt=con.prepareStatement(AUTHORIZE);pstmt.setString(1,username);pstmt.setString(2,p
10、assword);ResultSetrs=pstmt.executeQuery();if(!rs.next()thrownewUnauthorizedException();)userID=rs.getInt(1);)catch(SQLExceptionsqle)System.err.println("ExceptioninDbAuthorizationFactory:"+sqle);sqle.printStackTrace();thrownewUnauthorizedException();)finallytrypstmt.close();catch(Exceptione
11、)e.printStackTrace();trycon.close();catch(Exceptione)e.printStackTrace();returnnewDbAuthorization(userID);在這個類中,可以看到抽象類和具體的子類之間的關(guān)系,它們是如何協(xié)作的,又是如何劃分抽象方法和非抽象方法的,這都是值得注意的地方。一般的,抽象方法需要子類來實現(xiàn),而抽象類中的非抽象方法應(yīng)該所有子類所能夠共享的,或者可是說,是定義在抽象方法之上的較高層的方法。這確實是一個抽象工廠的好例子!雖然實現(xiàn)的方法已經(jīng)和GOF中給出的實現(xiàn)相差較遠了,但思想沒變,這兒的實現(xiàn),也確實是要巧妙的些。還有就是靜
12、態(tài)方法的使用,使得這個類看起來有些Singleton的意味。這使得對于AbstractFactory的創(chuàng)建變得簡單。下面的類圖給出了這個AbstractFactory的實現(xiàn)的總體情況:圖2:AbstractFactory模式的實現(xiàn)類圖在AuthorizationFactory中定義的其它方法,涉及到具體的如何創(chuàng)建Authorization,都是作為abstract方法出現(xiàn),具體實現(xiàn)留給子類來完成。這樣,在需要生成一個Authorization的時候,只需要調(diào)用AuthorizationFactory的靜態(tài)方法getAuthorization就可以了,由子類實現(xiàn)了具體的細節(jié)。其它的,如同上面講到
13、的,在創(chuàng)建Forum的時候用的ForumFactory,具有同上面一樣的實現(xiàn),這就是模式之所以稱為模式的所在了。Proxy模式和權(quán)限控制Proxy模式的功能有很多,比如遠程代理,用來給遠程對象提供一個本地代表;虛代理,用來為創(chuàng)建開大開銷的對象提供緩沖,等等。在Jive中使用的是保護代理,為被保護的對象提供權(quán)限控制。我們都知道在一個論壇中,權(quán)限的控制是必須的,否則論壇就很可能會被搞得一團糟。Jive中引入Proxy對象,Authorization接口以及權(quán)限描敘屬類來提供對論壇的保護。以ForumFactory為例,一個額外的ForumFactoryProxy來處理權(quán)限認證的工作,它為某一個Fo
14、rumFactory提供了一個代理,保證只有授權(quán)的用戶才能夠存取ForumFactory的某些操作。實際上ForumFactory在這兒不僅僅只是一個生成Forum的類的,它更像是一個Forum的管理類。提供了添加,刪除,枚舉等等一系列的功能,而有些功能不是什么樣的人都可以使用的,因而引入了另外的一個代理類來處理權(quán)限的問題。當然,代理類需要繼承ForumFactory,以使方法簽名一致:ForumFactoryProxyextendsForumFactory在它的構(gòu)造方法中,就提供了一個ForumFactory對象,這是需要被代理的對象;一個Authorization對象,提供用戶信息;還有一
15、個ForumPermissions,提供認證信息:publicForumFactoryProxy(ForumFactoryfactory,Authorizationauthorization,ForumPermissionspermissions)this.factory=factory;this.authorization=authorization;this.permissions=permissions;一般的代理過程都是這樣的,在訪問某個方法之前,必須接受權(quán)限的檢查,以createForum為例:publicForumcreateForum(Stringname,Stringdescr
16、iption)throwsUnauthorizedException,ForumAlreadyExistsExceptionif(permissions.get(ForumPermissions.SYSTEM_ADMIN)ForumnewForum=factory.createForum(name,description);returnnewForumProxy(newForum,authorization,permissions);elsethrownewUnauthorizedException();下面給出這個模式的類圖:圖3:Proxy模式的類圖這個模式的實現(xiàn)基本上和GOF中所給出的實
17、現(xiàn)一致。在Jive中,幾乎所有的接口,F(xiàn)orum,ForumMessage,ForumThread等等,都會有一個相應(yīng)的Proxy對象來進行權(quán)限控制。而在創(chuàng)建具體的對象的時候,都是用相應(yīng)的Proxy對象來代替原有的對象返回的。例如在ForumFactory的getInstance()方法中需要返回一個Forum的時候,Jive是這樣做的:publicstaticForumFactorygetInstance(Authorizationauthorization)ForumFactoryProxyproxy=newForumFactoryProxy(factory,authorization,f
18、actory.getPermissions(authorization);returnproxy;下一頁因而,所有被創(chuàng)建的對象實際上都是Proxy對象,抽象工廠保證了沒有權(quán)限驗證的對象根本不會客戶所得到,它們只會在Proxy的內(nèi)部扮演角色,而永遠不會被外部對象所存取,這樣,就從根本上保證了論壇的安全。Decorator模式和過濾器一般的在OO設(shè)計中,而外功能的添加是通過繼承來實現(xiàn)的,但是繼承有的時候不夠靈活,而且當功能的組合很多的時候,繼承的子類就會成幾何級數(shù)增長,使得類多的難以控制。正是基于這樣的考慮,Decorator模式得以誕生。Decorator模式相當于封裝了某個特定的操作,當某個又
19、卷需要這個操作的時候,加上這個Decorator即可。并且,多個Decorator還可以組合,以提供更多的功能。在Jive中,Decorator模式應(yīng)用在一些過濾器(Filter)中。FNter提供對ForumMessage對象內(nèi)容的重新構(gòu)造。比如,當一個ForumMessage對象流過一個名為FilterCodeHighlight的過濾器后,存在于消息中的所有Java源代碼文本,會被重新構(gòu)造為具有語法高亮顯示的消息。在比如,當經(jīng)過了語法高亮修飾的消息再流過一個名為FilterHtml的過濾器后,消息中的HTML片斷會被注釋可以在HTML內(nèi)部顯示文本,這樣就防止了用戶輸入了HTML控制標簽后,
20、使得頁面顯示不正常的問題。Jive中,所有的過濾器繼承于一個抽象類ForumMessageFilter,而ForumMessageFilter又實現(xiàn)了ForumMessage接口。也就是說,每一個過濾器實際上也是一個ForumMessage對象。ForumMessageFilter中還封裝一個ForumMessage對象。進行過濾的方法很簡單,使用的是getBody(),比如在FilterCodeHighlight這個類中:publicStringgetBody()returnhighlightCode(message.getBody();highlightCode是一個private方法,實
21、施具體的過濾的細節(jié)。getBody()方法實際上是定義在ForumMessage接口中的,當調(diào)用過濾器的getBody()方法時,就能夠得到結(jié)構(gòu)重整后的ForumMessage對象了。這個對象可以被其他客戶引用,也可以在傳遞給另外的過濾器,實施進一步的操作。在實現(xiàn)一個具體的消息的過濾的時候,在Forum中有addForumMessageFilter(),applyFilters()方法,用來實現(xiàn)對過濾器的應(yīng)用。對一個Forum,使用addForumMessageFilter()方法添加一個Filter的時候,并沒有指定一個具體的Message,而只是一個規(guī)則(Filter中封裝了過濾規(guī)則),然
22、后applyFilter()方法中,實施這些規(guī)則:publicForumMessageapplyFilters(ForumMessagemessage)/Loopthroughfiltersandapplythemfor(inti=0;i<filters.length;i+)message=filtersi.clone(message);returnmessage;過濾器的clone()方法,為過濾器復(fù)制消息體。這個方法的使用,分離了在過濾器中對于消息體和過濾規(guī)則的初始化過程,這也是一個值得借鑒的技巧!圖4:Decorator模式的類圖我們可以看到Decorator模式實際上和Proxy
23、模式是很相近的,但是它們代表兩個不同的功能含義。Proxy模式提供一個對象的控制,而Decorator模式則是為對象提供額外的功能。Iterator模式和論壇的瀏覽Iterator模式用來分離數(shù)據(jù)結(jié)構(gòu)和遍歷算法,降低兩者之間的耦合度,以使得同一個數(shù)據(jù)結(jié)構(gòu)用不同的算法遍歷時,仍能夠具有相同的接口,另一方面,Iterator模式使得當改換遍歷算法后,不需要更改程序的代碼。在Java的JDK中本身就定義有一個Iterator接口,在Iterator接口中僅僅定義了三個方法,hasNext()判斷是否遍歷完最后一個元素,next()方法返回要遍歷的數(shù)據(jù)結(jié)構(gòu)中一個對象,remove()則刪除當前對象。J
24、ive中使用IteratorProxy抽象類繼承了這一接口。這兒Proxy的含義和上面一樣,也就是說,這個IteratorProxy出了會實現(xiàn)Iterator的遍歷功能外,還會有代理權(quán)限控制的功能。對于論壇中的基本對象Forum,ForumThread,ForumMessage,Group,User都有相應(yīng)的遍歷器。比如對應(yīng)于Forum接口有ForumIteratorProxy對象。這個ForumIteratorProxy遍歷器就相當于一個封裝了一系列Forum對象的集合類,通過定義好的接口hasNext()和next()可以方便的遍歷這個集合,而并不需要知道是如何遍歷這個集合的。遍歷的算法可
25、能很簡單,也可能很復(fù)雜,但是對于外部的客戶而言,這并沒有任何的區(qū)別。而對于論壇中具體的遍歷方法,這取決于具體的實現(xiàn),在Jive中給出的是數(shù)據(jù)庫的實現(xiàn)。我們就以MessageIteratorProxy為例,來講解Iterator模式的用法。DbThreadIterator對象實現(xiàn)了Iterator接口,是對于一個Thread中所有Message的遍歷器,我們來看看它是如何實現(xiàn)的。hasNext()判斷在這個Thread中是不是還有下一條Message:publicbooleanhasNext()if(currentIndex+1>=messages.length)returnfalse;)
26、returntrue;)next()方法從數(shù)據(jù)庫中取出與在這個Thread中的下一條Message:publicObjectnext()throwsjava.util.NoSuchElementExceptionForumMessagemessage=null;if(nextMessage!=null)message=nextMessage;nextMessage=null;)elsemessage=getNextMessage();if(message=null)thrownewjava.util.NoSuchElementException();)returnmessage;)這樣,通過對
27、數(shù)據(jù)庫的操作,DbThreadIterator實現(xiàn)了對一個Thread中所有Message遍歷的方法。再ForumThread接口中有messages()方法,返回在這個Thread中的所有Message的一個遍歷器(Iterator),實際上也就是返回了一個Message的集合:publicIteratormessages();在DbForumThread中實現(xiàn)了這個方法:publicIteratormessages()returnnewDbThreadIterator(this);從DbForumThread的messages。方法中所返回的就是這個Thread中所有Message的一個遍歷器,通過這個遍歷器,我們就
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 外科護士長個人述職報告范文
- 2025年幼兒園疫病信息報告計劃
- 抖音短視頻新媒體運營職責(zé)
- 零成本智能硬件營銷方案范文
- 以市場機制為翼鑄博物館核心產(chǎn)品之魂
- 以實驗探究為翼展初中生物創(chuàng)新之翔:創(chuàng)新能力培養(yǎng)實踐與探索
- 醫(yī)療行業(yè)一體機培訓(xùn)心得體會
- 壓瘡護理流程優(yōu)化小組職責(zé)
- 專升本學(xué)科交叉學(xué)習(xí)心得體會
- 注塑機設(shè)計說明書
- 實訓(xùn)實驗室安全準入管理制度
- 2014電氣裝置安裝工程低壓電器施工及驗收規(guī)范
- 初中英語時間表達法省公開課金獎全國賽課一等獎微課獲獎?wù)n件
- 消防改造工程技術(shù)標書樣本
- 數(shù)字化轉(zhuǎn)型數(shù)據(jù)架構(gòu)設(shè)計方法論及案例
- 足球教練員管理制度范文
- 無人機技術(shù)在消防救援中的應(yīng)用
- 《項目回款管理》課件
- 農(nóng)產(chǎn)品包裝與運輸技術(shù)
- 大學(xué)美育(第二版) 課件 第十三單元:數(shù)字媒體藝術(shù) 課件
評論
0/150
提交評論