隨筆-34  評(píng)論-1965  文章-0  trackbacks-0

          通過這一年多的艱苦奮戰(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 組件圖
          圖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)了如下所示的代碼:

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

          雖然上述代碼功能上沒有問題,但是反映了它的作者沒有了解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ò)誤,還望各位朋友不吝賜教。

          posted on 2008-10-25 01:20 Max 閱讀(19223) 評(píng)論(28)  編輯  收藏 所屬分類: 心路歷程

          評(píng)論:
          # re: 項(xiàng)目總結(jié) 2008-10-25 08:23 | 大道自然
          總結(jié)的不錯(cuò).但有些問題即然說明了不好的地方,就要給出個(gè)好的答案.比如hibernate中的saveOrUpdate.等  回復(fù)  更多評(píng)論
            
          # re: 項(xiàng)目總結(jié) 2008-10-25 10:45 | TiGERTiAN
          @大道自然
          處于Persistent狀態(tài)的對(duì)象,調(diào)用saveOrUpdate是不做任何事情的  回復(fù)  更多評(píng)論
            
          # re: 項(xiàng)目總結(jié) 2008-10-25 11:37 | live2map
          我的理解是采用load方法是獲取Persistent狀態(tài)的對(duì)象,然后需要removeCache改版它的狀態(tài),這樣用saveOrUpdate有用,save or update完了后,再put in cache,不知道我的理解對(duì)不,  回復(fù)  更多評(píng)論
            
          # re: 項(xiàng)目總結(jié) 2008-10-25 20:27 | 久城
          先支持下,不錯(cuò)。
          第五點(diǎn)還想請(qǐng)教一下,我們項(xiàng)目中一直都是大量的使用DTO。
          你所說的不可預(yù)期的行為是什么?有什么好的避免的辦法嗎?  回復(fù)  更多評(píng)論
            
          # re: 項(xiàng)目總結(jié) 2008-10-26 12:13 | xiapir
          # re: 項(xiàng)目總結(jié) 2008-10-26 22:23 | 雨奏
          @live2map
          你沒必要這樣做啊:如果一個(gè)對(duì)象處于persistent狀態(tài),你更改了它,Hibernate會(huì)在flush的時(shí)候自動(dòng)把它保存到數(shù)據(jù)庫中的。對(duì)于緩存,Hibernate也會(huì)根據(jù)你制定的策略進(jìn)行同步

          @久城
          個(gè)人認(rèn)為如果使用了Hibernate,確實(shí)沒有必要使用DTO:你把一個(gè)detach的對(duì)象當(dāng)作VO或DTO就可以了嘛  回復(fù)  更多評(píng)論
            
          # re: 項(xiàng)目總結(jié) 2008-10-27 10:20 | 西濱(Ivan Chen)
          其實(shí)作者已經(jīng)說清楚了“這里的session.saveOrUpdate其實(shí)是完全沒必要的。“

          就是可以不用寫這一句,等到session結(jié)束后,Hibernate檢查cat對(duì)象發(fā)生了改變,會(huì)自動(dòng)更新的。  回復(fù)  更多評(píng)論
            
          # re: 項(xiàng)目總結(jié)[未登錄] 2008-10-27 13:35 | abc
          @西濱(Ivan Chen)
          寫個(gè)seam jsf的簡單入門吧!  回復(fù)  更多評(píng)論
            
          # re: 項(xiàng)目總結(jié)[未登錄] 2008-10-28 14:39 | 豬豬
          經(jīng)驗(yàn)不錯(cuò),但說出了就大概解說下。  回復(fù)  更多評(píng)論
            
          # re: 項(xiàng)目總結(jié)[未登錄] 2008-11-03 15:54 | Allen
          關(guān)注中!MAX,如果有機(jī)會(huì),我有很多困惑想得到你的解答!msn:xxrrss1987@live.cn  回復(fù)  更多評(píng)論
            
          # re: 項(xiàng)目總結(jié) 2008-11-03 19:58 | 小易
          關(guān)注!  回復(fù)  更多評(píng)論
            
          # re: 項(xiàng)目總結(jié)[未登錄] 2008-11-05 21:47 | yxl
          希望MAX兄弟能有更好的博文在博客中出現(xiàn),期盼................  回復(fù)  更多評(píng)論
            
          # re: 項(xiàng)目總結(jié) 2008-11-07 20:55 | yeshucheng
          作者提到了session的問題,其實(shí)這里最主要是需要了解hibernate中的三種狀態(tài),這個(gè)最為主要。了解三個(gè)狀態(tài)的差異區(qū)別就知道原因了,呵呵  回復(fù)  更多評(píng)論
            
          # re: 項(xiàng)目總結(jié) 2008-11-07 20:56 | yeshucheng
          題外話,感覺作者的這個(gè)項(xiàng)目也是一個(gè)很怪異的項(xiàng)目。而且感覺這個(gè)項(xiàng)目是在融合或者說兼容其他的項(xiàng)目,這種項(xiàng)目最頭疼。  回復(fù)  更多評(píng)論
            
          # re: 項(xiàng)目總結(jié) 2008-11-11 15:43 | fanwenda
          我支持這個(gè)內(nèi)容
            回復(fù)  更多評(píng)論
            
          # re: 項(xiàng)目總結(jié) 2008-11-11 15:45 | fanwenda
          我知道這個(gè)論壇很好www.bjjypw.com 希望大家都支持

          我支持 www.wdjpw.com
          希望大家支持  回復(fù)  更多評(píng)論
            
          # re: 項(xiàng)目總結(jié) 2008-11-24 10:07 | thematrix
          雖然看不怎么懂,但是還是要頂一下。  回復(fù)  更多評(píng)論
            
          # re: 項(xiàng)目總結(jié) 2008-11-26 16:30 | gqs
          支持作者  回復(fù)  更多評(píng)論
            
          # re: 項(xiàng)目總結(jié)[未登錄] 2008-12-09 15:17 | 三少
          我覺得hibernate的saveOrUpdate最好不用,很容易出錯(cuò)。
          做好save或者是update的判斷就可以了!

          JSF我覺得蠻好的,但是它自己的IOC不夠強(qiáng)大,結(jié)合Spring就好多了!  回復(fù)  更多評(píng)論
            
          # re: 項(xiàng)目總結(jié) 2008-12-11 10:21 | zjielove
          雖然自己能力不高 有些看不懂 還是要頂 哈哈  回復(fù)  更多評(píng)論
            
          # re: 項(xiàng)目總結(jié) 2008-12-15 09:29 | kaig
          問一下你們開發(fā)了一個(gè)什么樣的項(xiàng)目啊(告訴名稱即可,好奇)?但我更希望多一點(diǎn)STRUTS2的交流  回復(fù)  更多評(píng)論
            
          # re: 項(xiàng)目總結(jié)[未登錄] 2008-12-25 14:24 | fungway
          學(xué)習(xí)。。。  回復(fù)  更多評(píng)論
            
          # re: 項(xiàng)目總結(jié) 2009-02-01 15:19 | tigerkin
          @大道自然
          把session可以close或者flush就可以自動(dòng)更新  回復(fù)  更多評(píng)論
            
          # re: 項(xiàng)目總結(jié) 2009-02-20 10:55 | Illu
          希望樓主能對(duì)存在的問題提出更好的解決方案  回復(fù)  更多評(píng)論
            
          # re: 項(xiàng)目總結(jié) 2009-03-09 15:40 | 龍華城
          文章寫的很不錯(cuò),我正在學(xué)struts2 ,謝謝你的文章了.  回復(fù)  更多評(píng)論
            
          # re: 項(xiàng)目總結(jié) 2009-03-19 08:11 | dealry
          我想作者是想引導(dǎo)我們?nèi)タ聪嚓P(guān)的資料,而不是在這里一一灌輸給我們
          非常感謝 您能把自己的經(jīng)驗(yàn)和知識(shí)分享
            回復(fù)  更多評(píng)論
            
          # re: 項(xiàng)目總結(jié) 2009-09-17 10:20 | tsscomcn
          精典,收藏了。  回復(fù)  更多評(píng)論
            
          # re: 項(xiàng)目總結(jié) 2010-04-28 17:26 | zisehefeng
          牛人啊。  回復(fù)  更多評(píng)論
            
          主站蜘蛛池模板: 防城港市| 瑞昌市| 咸阳市| 松阳县| 靖远县| 安平县| 怀仁县| 新田县| 赤城县| 北碚区| 嘉义市| 虹口区| 长丰县| 武夷山市| 平利县| 静乐县| 调兵山市| 吕梁市| 无为县| 伊金霍洛旗| 阿坝县| 邛崃市| 色达县| 余干县| 辽宁省| 隆回县| 河曲县| 德江县| 霞浦县| 河间市| 汉阴县| 辽源市| 子长县| 河南省| 承德市| 横峰县| 乡城县| 太原市| 南汇区| 湖口县| 沙洋县|