通過這一年多的艱苦奮戰(zhàn),項(xiàng)目就快接近收官之戰(zhàn)。回首過往一年的開發(fā)歷程,心中不免有些感慨萬千,故寫下這篇BLOG總結(jié)一下經(jīng)驗(yàn)與教訓(xùn),算是兌現(xiàn)上一篇BLOG的諾言。
項(xiàng)目簡介
由于一些商業(yè)上的原因,我不能透露項(xiàng)目的細(xì)節(jié)。不過,我可以與大家分享一下所謂的“架構(gòu)”。之所以給“架構(gòu)”兩字加上引號(hào),是因?yàn)槲也幌腌栉圻@個(gè)神圣的詞匯。在項(xiàng)目開始選用第三方組件(Component)時(shí),由于種種原因,其實(shí)我只有很小選擇余地,所以只能對(duì)著一些官方文檔將這些組件并揍在一起。

圖1 組件圖
經(jīng)驗(yàn)與教訓(xùn)
雖然我們平時(shí)說“成功的經(jīng)驗(yàn),失敗的教訓(xùn)”,但是有時(shí)要區(qū)分兩者并不容易,因?yàn)橛行┦虑殡m稱不上成功,卻也不至于失敗。故請(qǐng)?jiān)试S我暫時(shí)將其混成一談。
#1 分而治之(divide and conquer),重構(gòu)代碼
在項(xiàng)目中當(dāng)復(fù)雜業(yè)務(wù)邏輯變得復(fù)雜時(shí),有的程序員沒有膽量去重構(gòu)舊代碼,而取用保守方式,拼命地添加新的代碼。這樣做的后果就是會(huì)導(dǎo)致代碼量激增,難于維護(hù)。“分而治之”可以幫助我們理清復(fù)雜的業(yè)務(wù),提高代碼可重用性。所以任何時(shí)候,都不要忘記這個(gè)程序基本的方法學(xué)。
#2 盡量不要使用遠(yuǎn)程(Remote)EJB
遠(yuǎn)程EJB給我們帶來很多的問題:部置的復(fù)雜性,由于網(wǎng)絡(luò)傳輸引起的性能問題,EJB安全性問題等。我的同事中有些人堅(jiān)持使用遠(yuǎn)程EJB的原因,他們認(rèn)為只有使用遠(yuǎn)程EJB才實(shí)現(xiàn)群集(Cluster)。其實(shí)這想法是錯(cuò)誤,具體可以參考《Marstering Enterprise JavaBeans》第三版中,第8章“EJB Performance Optimization”中“Choosing Between Local Interfaces and Remote Interfaces”和第19章“Clustering”。
#3 避免在程序中保存狀態(tài)(State)
有的程序員偏愛全局類型變量,而忽略通過參數(shù)和返回值進(jìn)行共享數(shù)據(jù)。狀態(tài)對(duì)程序來說其實(shí)就是一種負(fù)擔(dān),在多線程和分布式的環(huán)境下更是如此。還有,編程的另一原則是盡量縮小變量有效范圍(Scope),大家可以參考一下《Code Complete》中一些建議。
另外,要小心使用靜態(tài)變量,切記要通過final關(guān)鍵字和Collections.unmodifiableXxxx方法(對(duì)于集合類型)使其不可變。如果需要在對(duì)象之間共享狀態(tài),可以考慮使用HttpSession或分布式的緩存如(JBoss Cache等)。
#4 如果使用Hibernate,請(qǐng)確保程序員了解Hibernate中持久化對(duì)象生命周期
在我身邊有很程序員,在使用Hibernate時(shí),沒有花時(shí)間了解持久化對(duì)象生命周期。他們以普通JDBC的編程風(fēng)格編寫Hibernate程序。故出現(xiàn)了如下所示的代碼:
Session session = getSession();
Cat cat = session.load("kitty");
cat.setName("Hello Kitty");
session.saveOrUpdate(cat);
}
雖然上述代碼功能上沒有問題,但是反映了它的作者沒有了解Hibernate的持久化對(duì)象生命周期。這里的session.saveOrUpdate其實(shí)是完全沒必要的。如果你不明白個(gè)中原因,可以參考Hibernate的官方文檔或《Hiberante In Action》的第四章“Working with persistent objects”。
#5 設(shè)計(jì)好你的業(yè)務(wù)對(duì)象模型
我看過很多項(xiàng)目的代碼中其大量存在所謂的PO(Persistent Object)用于ORM和VO(Value Object)或稱為DTO(Data Transfer Object)用于程序之間傳輸數(shù)據(jù),更有甚者,這兩種對(duì)象只是相差一兩個(gè)屬性。這樣的做法的弊端是代碼中充斥大量林林總總的copyXxx的方法,導(dǎo)致程序出現(xiàn)一些不可預(yù)期的行為。
其實(shí),通過對(duì)業(yè)務(wù)對(duì)象分析,尤其是對(duì)象之間的關(guān)系建立,上述問題中的大部分都是可以避免的。
#6 不要單獨(dú)使用JSF
經(jīng)過這兩年過JSF學(xué)習(xí)與使用,我對(duì)JSF是又愛又恨。JSF有不少優(yōu)點(diǎn):
- 類似ASP.NET的事件驅(qū)動(dòng)(Event-Driven)開發(fā)模型,簡化了Web應(yīng)用的開發(fā);
- 通過EL(Expression Language,表達(dá)式語言)雙向值綁定,提高編程效率;
- 基于組件(ASP.NET中稱之控件)的模型,方便第三方進(jìn)行擴(kuò)展。
不過,同樣JSF缺點(diǎn)也不少:
- 保存過多的頁面狀態(tài),而除了Session和Application范圍之外的Managed Bean都是沒有狀態(tài),這個(gè)不對(duì)稱性導(dǎo)致很多問題。所以在很多時(shí)候迫使程序員使用Session范圍的Managed Bean。而過度使用Session會(huì)加大服務(wù)器的內(nèi)存消耗;
- 蹩腳的驗(yàn)證框架等。
所以,在使用JSF時(shí),我們應(yīng)該結(jié)合其它優(yōu)秀的框架如JBoss Seam,RichFaces等,達(dá)到互相取長補(bǔ)短效果。
結(jié)言
上述評(píng)論,僅代表我本人立場:-)。如有錯(cuò)誤,還望各位朋友不吝賜教。