通過這一年多的艱苦奮戰,項目就快接近收官之戰。回首過往一年的開發歷程,心中不免有些感慨萬千,故寫下這篇BLOG總結一下經驗與教訓,算是兌現上一篇BLOG的諾言。

項目簡介

由于一些商業上的原因,我不能透露項目的細節。不過,我可以與大家分享一下所謂的“架構”。之所以給“架構”兩字加上引號,是因為我不想玷污這個神圣的詞匯。在項目開始選用第三方組件(Component)時,由于種種原因,其實我只有很小選擇余地,所以只能對著一些官方文檔將這些組件并揍在一起。

圖1 組件圖
圖1 組件圖

經驗與教訓

雖然我們平時說“成功的經驗,失敗的教訓”,但是有時要區分兩者并不容易,因為有些事情雖稱不上成功,卻也不至于失敗。故請允許我暫時將其混成一談。

#1 分而治之(divide and conquer),重構代碼

在項目中當復雜業務邏輯變得復雜時,有的程序員沒有膽量去重構舊代碼,而取用保守方式,拼命地添加新的代碼。這樣做的后果就是會導致代碼量激增,難于維護。“分而治之”可以幫助我們理清復雜的業務,提高代碼可重用性。所以任何時候,都不要忘記這個程序基本的方法學。

#2 盡量不要使用遠程(Remote)EJB

遠程EJB給我們帶來很多的問題:部置的復雜性,由于網絡傳輸引起的性能問題,EJB安全性問題等。我的同事中有些人堅持使用遠程EJB的原因,他們認為只有使用遠程EJB才實現群集(Cluster)。其實這想法是錯誤,具體可以參考《Marstering Enterprise JavaBeans》第三版中,第8章“EJB Performance Optimization”中“Choosing Between Local Interfaces and Remote Interfaces”和第19章“Clustering”。

#3 避免在程序中保存狀態(State)

有的程序員偏愛全局類型變量,而忽略通過參數和返回值進行共享數據。狀態對程序來說其實就是一種負擔,在多線程和分布式的環境下更是如此。還有,編程的另一原則是盡量縮小變量有效范圍(Scope),大家可以參考一下《Code Complete》中一些建議。

另外,要小心使用靜態變量,切記要通過final關鍵字和Collections.unmodifiableXxxx方法(對于集合類型)使其不可變。如果需要在對象之間共享狀態,可以考慮使用HttpSession或分布式的緩存如(JBoss Cache等)。

#4 如果使用Hibernate,請確保程序員了解Hibernate中持久化對象生命周期

在我身邊有很程序員,在使用Hibernate時,沒有花時間了解持久化對象生命周期。他們以普通JDBC的編程風格編寫Hibernate程序。故出現了如下所示的代碼:

    public void myDao() {
        Session session 
= getSession();
        Cat cat 
= session.load("kitty");
        cat.setName(
"Hello Kitty");
        session.saveOrUpdate(cat);
    }
列表1 代碼示例

雖然上述代碼功能上沒有問題,但是反映了它的作者沒有了解Hibernate的持久化對象生命周期。這里的session.saveOrUpdate其實是完全沒必要的。如果你不明白個中原因,可以參考Hibernate的官方文檔或《Hiberante In Action》的第四章“Working with persistent objects”。

#5 設計好你的業務對象模型

我看過很多項目的代碼中其大量存在所謂的PO(Persistent Object)用于ORM和VO(Value Object)或稱為DTO(Data Transfer Object)用于程序之間傳輸數據,更有甚者,這兩種對象只是相差一兩個屬性。這樣的做法的弊端是代碼中充斥大量林林總總的copyXxx的方法,導致程序出現一些不可預期的行為。

其實,通過對業務對象分析,尤其是對象之間的關系建立,上述問題中的大部分都是可以避免的。

#6 不要單獨使用JSF

經過這兩年過JSF學習與使用,我對JSF是又愛又恨。JSF有不少優點:

  • 類似ASP.NET的事件驅動(Event-Driven)開發模型,簡化了Web應用的開發;
  • 通過EL(Expression Language,表達式語言)雙向值綁定,提高編程效率;
  • 基于組件(ASP.NET中稱之控件)的模型,方便第三方進行擴展。

不過,同樣JSF缺點也不少:

  • 保存過多的頁面狀態,而除了Session和Application范圍之外的Managed Bean都是沒有狀態,這個不對稱性導致很多問題。所以在很多時候迫使程序員使用Session范圍的Managed Bean。而過度使用Session會加大服務器的內存消耗;
  • 蹩腳的驗證框架等。

所以,在使用JSF時,我們應該結合其它優秀的框架如JBoss Seam,RichFaces等,達到互相取長補短效果。

結言

上述評論,僅代表我本人立場:-)。如有錯誤,還望各位朋友不吝賜教



開心過好每一天。。。。。