對J2EE專案的一些體會
對J2EE專案的一些體會[@more@] 1 、認真考慮是否真要使用J2EE
這個很重要,非常重要。J2EE涵蓋的內容大而全,但很多不一定就是具體實際專案需要的。象EJB級的許可權控制,如果你的表現層(大部分專案就是Web server)和應用伺服器不存在信任問題,那麼基本上就不用考慮。又比如伸縮性,如果同時線上最多不超過100個,就沒什麼用處。針對專案的實際情況選擇效費比最合適的解決方案,而不要為了應用先進技術而應用先進技術。
2、選擇合適的分佈模型
提起分佈,很多人可能都會有這樣的設想:server A處理認證,server B處理訂單,server C處理倉儲;如果B的負載太大,那麼再細分一下:錄入、修改部分的EJB部署在server D,統計、分析部分的部署在server E,等等。其實沒有必要,我的體會是:除非業務必須(如分支機構統一透過總部的app server來進行許可權驗證),否則最好將所有的應用全部放在一個app server中,能在一個程式空間內更好(使用home interface),然後進行平行的分佈——即叢集中的所有app server功能上都是等價的。相比前一種垂直(或者網狀)分佈,平行分佈的可靠性、容錯能力、伸縮能力都要更好,同時減少了部署、管理負擔。最重要的是,減少了因為業務邏輯層內部跨程式呼叫引起的開銷,提高了整體效能。然而,如果a、一些業務邏輯必須相互獨立部署、管理,b、負載較為集中地分佈在若干個EJB中,那麼,垂直分佈還是必不可少的。
3、為Entity bean選擇合適的資料儲存方案
首先儘量使用CMP管理資料儲存,尤其是簡單的,大部分業務操作都是插入刪除修改的實體,不然光insert update就夠你忙的了,更不用說資料庫移植問題。其次對於簡單的一對一、一對多關係,如果你的app server沒有實現EJB2.0規範,可以考慮使用O/R對映工具幫助開發,象Cocobase, EJB creator等等,可以提高不少效率。對於複雜的物件儲存,沒辦法,老老實實寫程式碼吧……
4、慎重考慮EJBHome.findByXXX(),listXXX()的實現
設想對一個百萬記錄級的表進行檢索,結果集很可能是上萬條、十萬條,這本身就是一個耗費資源的過程;同時對於檢索到的每一個記錄還要做一次findByPrimarykey,這麼多次跨程式呼叫,開銷可想而知。為什麼有的人覺得用J2EE實現的程式奇慢無比,缺乏仔細的設計就是主要原因之一。
5、使用抽象資料結構傳遞資料
例如,listOrder()返回Collection而不是Vector,insertItems()也是以Collection為引數而不是LinkedList。當然這個實際上與J2EE本身關係不是很大。
6、對Entity bean儘量使用Map來儲存、傳遞屬性
對業務流程沒有很大影響的屬性,象身高體重出生年月之類,最好用一個HashMap來存放,而不要直接用成員變數+getXXX/setXXX。對於ejbCreate也是一樣,十幾個引數的create方法,實現、維護都是代價高昂的。需知實際應用中這些欄位的增減、屬性變化是家常便飯,光維護get/set方法可能就會讓你吐血了。但是,對於對業務流程有關建意義的欄位,例如員工的入職日期決定其休假天數的計算,那麼還是作為成員變數的好。
推薦一個關於EJB設計模式的好地方:
7、分清Entity bean和session bean的職責
Entity bean是實體的物件形式,它的職責應限於自身的儲存,以及對外部提供訪問內部資料的介面(所以我認為它本質上應該屬於資料儲存層)。Entity bean應該儘量避免自己實現有其他Entity bean參與的業務邏輯。例如,訂單的貨款收到以後,將訂單的狀態由“提交”變為“生效”,同時將訂單的金額按照某種規則折算成該客戶的積分。這個業務流程有三個物件參與:客戶,訂單和積分折算策略。那麼,實現流程的方法應該在哪個物件中呢,是客戶還是訂單?都不合適,如果在訂單中,那麼訂單物件需要了解客戶積分屬性的介面及積分折算的介面;如果在客戶物件中也是一樣。耦合度增強就意味著維護難度增大,如果使用者物件的積分介面或者折算策略的介面改變了,那麼改變就會蔓延到訂單物件中。合適的方式是用一個OrderProcessor來管理訂單處理流程,以stateless session bean來實現。OrderProcessor瞭解所有參與訂單處理的物件的介面,它集中管理對訂單的處理流程,如果流程發生變化,訂單生效之前要透過審批,這種變化不會影響到參與流程的實體物件;同樣,參與流程的某個物件介面發生了變化,也不會影響到其他物件。
8、重視表現層的複用
企業軟體的介面,大部分都可以用一些基本元素如grid, tree, page control, form等組合而來。如果能合理採用一些技術對這些元素進行復用,不但有利於降低開發成本,而且也便於統一維護介面風格。對J2EE的表現層,也就是JSP/servlet,可以採用的複用技術不多,基本上就是檔案包含、建立類庫、Tag lig(本質上還是建立類庫,使用起來我覺得還不一定有直接方法呼叫來的方便)等等。還有一些不同於JSP/servlet的表現層框架,如Apache Velocity、Enhydra、WebMacro等等,也可以參考。雖然Java還沒有一個規範的、統一的HTML介面元素類庫,但自己專案內部統一使用某種方案還是可能的。
另外,XML+XSLT也是一種方案。將資料直接用XML形式表現出來,繞過Entity bean,然後再用XSLT模版轉化成最終介面。XML與XSLT之間屬於模式匹配式的鬆散耦合,可以避免強型別語言方法呼叫帶來的引數型別、個數、順序限制,做到徹底地資料與介面分離;同時XML形式的資料集在app server中可以按照合適的方案進行緩衝,避免頻繁訪問資料庫,抵銷XSLT轉換引入的效能負擔。同時XML和XSLT是業界廣泛採納的標準,如果今後採用不同的體系結構(如從J2EE移植到.Net或者相反),表現層的XSLT形式的介面可以重用。JSP或ASP就沒有這種可能。問題在於首先要管理關係型資料到層次型XML資料的對映,其次如果沒有一個好的工具,建立、維護XSLT也是很費時費力的事情。我現在的專案正在朝這個方向努力,希望能做一個象Delphi那樣好用的,基於XSLT的HTML介面控制元件開發、管理、使用環境。
9、充分估計開發的艱辛程度
這個,一言難盡。總之實際需求的變化往往是超乎我們想象的,要在需求分析結束的時候就清晰劃分模組介面幾乎做不到,計劃不如變化。而J2EE體系架構是重量級的框架,雖然app server實現了很多功能,但同時也要求你開發的時候付出額外的代價。對於J2EE專案的資金、時間、人手等資源估計,寧可多不可少,千萬不要簡單認為用了一個weblogic就萬事大吉了。
這個很重要,非常重要。J2EE涵蓋的內容大而全,但很多不一定就是具體實際專案需要的。象EJB級的許可權控制,如果你的表現層(大部分專案就是Web server)和應用伺服器不存在信任問題,那麼基本上就不用考慮。又比如伸縮性,如果同時線上最多不超過100個,就沒什麼用處。針對專案的實際情況選擇效費比最合適的解決方案,而不要為了應用先進技術而應用先進技術。
2、選擇合適的分佈模型
提起分佈,很多人可能都會有這樣的設想:server A處理認證,server B處理訂單,server C處理倉儲;如果B的負載太大,那麼再細分一下:錄入、修改部分的EJB部署在server D,統計、分析部分的部署在server E,等等。其實沒有必要,我的體會是:除非業務必須(如分支機構統一透過總部的app server來進行許可權驗證),否則最好將所有的應用全部放在一個app server中,能在一個程式空間內更好(使用home interface),然後進行平行的分佈——即叢集中的所有app server功能上都是等價的。相比前一種垂直(或者網狀)分佈,平行分佈的可靠性、容錯能力、伸縮能力都要更好,同時減少了部署、管理負擔。最重要的是,減少了因為業務邏輯層內部跨程式呼叫引起的開銷,提高了整體效能。然而,如果a、一些業務邏輯必須相互獨立部署、管理,b、負載較為集中地分佈在若干個EJB中,那麼,垂直分佈還是必不可少的。
3、為Entity bean選擇合適的資料儲存方案
首先儘量使用CMP管理資料儲存,尤其是簡單的,大部分業務操作都是插入刪除修改的實體,不然光insert update就夠你忙的了,更不用說資料庫移植問題。其次對於簡單的一對一、一對多關係,如果你的app server沒有實現EJB2.0規範,可以考慮使用O/R對映工具幫助開發,象Cocobase, EJB creator等等,可以提高不少效率。對於複雜的物件儲存,沒辦法,老老實實寫程式碼吧……
4、慎重考慮EJBHome.findByXXX(),listXXX()的實現
設想對一個百萬記錄級的表進行檢索,結果集很可能是上萬條、十萬條,這本身就是一個耗費資源的過程;同時對於檢索到的每一個記錄還要做一次findByPrimarykey,這麼多次跨程式呼叫,開銷可想而知。為什麼有的人覺得用J2EE實現的程式奇慢無比,缺乏仔細的設計就是主要原因之一。
5、使用抽象資料結構傳遞資料
例如,listOrder()返回Collection而不是Vector,insertItems()也是以Collection為引數而不是LinkedList。當然這個實際上與J2EE本身關係不是很大。
6、對Entity bean儘量使用Map來儲存、傳遞屬性
對業務流程沒有很大影響的屬性,象身高體重出生年月之類,最好用一個HashMap來存放,而不要直接用成員變數+getXXX/setXXX。對於ejbCreate也是一樣,十幾個引數的create方法,實現、維護都是代價高昂的。需知實際應用中這些欄位的增減、屬性變化是家常便飯,光維護get/set方法可能就會讓你吐血了。但是,對於對業務流程有關建意義的欄位,例如員工的入職日期決定其休假天數的計算,那麼還是作為成員變數的好。
推薦一個關於EJB設計模式的好地方:
7、分清Entity bean和session bean的職責
Entity bean是實體的物件形式,它的職責應限於自身的儲存,以及對外部提供訪問內部資料的介面(所以我認為它本質上應該屬於資料儲存層)。Entity bean應該儘量避免自己實現有其他Entity bean參與的業務邏輯。例如,訂單的貨款收到以後,將訂單的狀態由“提交”變為“生效”,同時將訂單的金額按照某種規則折算成該客戶的積分。這個業務流程有三個物件參與:客戶,訂單和積分折算策略。那麼,實現流程的方法應該在哪個物件中呢,是客戶還是訂單?都不合適,如果在訂單中,那麼訂單物件需要了解客戶積分屬性的介面及積分折算的介面;如果在客戶物件中也是一樣。耦合度增強就意味著維護難度增大,如果使用者物件的積分介面或者折算策略的介面改變了,那麼改變就會蔓延到訂單物件中。合適的方式是用一個OrderProcessor來管理訂單處理流程,以stateless session bean來實現。OrderProcessor瞭解所有參與訂單處理的物件的介面,它集中管理對訂單的處理流程,如果流程發生變化,訂單生效之前要透過審批,這種變化不會影響到參與流程的實體物件;同樣,參與流程的某個物件介面發生了變化,也不會影響到其他物件。
8、重視表現層的複用
企業軟體的介面,大部分都可以用一些基本元素如grid, tree, page control, form等組合而來。如果能合理採用一些技術對這些元素進行復用,不但有利於降低開發成本,而且也便於統一維護介面風格。對J2EE的表現層,也就是JSP/servlet,可以採用的複用技術不多,基本上就是檔案包含、建立類庫、Tag lig(本質上還是建立類庫,使用起來我覺得還不一定有直接方法呼叫來的方便)等等。還有一些不同於JSP/servlet的表現層框架,如Apache Velocity、Enhydra、WebMacro等等,也可以參考。雖然Java還沒有一個規範的、統一的HTML介面元素類庫,但自己專案內部統一使用某種方案還是可能的。
另外,XML+XSLT也是一種方案。將資料直接用XML形式表現出來,繞過Entity bean,然後再用XSLT模版轉化成最終介面。XML與XSLT之間屬於模式匹配式的鬆散耦合,可以避免強型別語言方法呼叫帶來的引數型別、個數、順序限制,做到徹底地資料與介面分離;同時XML形式的資料集在app server中可以按照合適的方案進行緩衝,避免頻繁訪問資料庫,抵銷XSLT轉換引入的效能負擔。同時XML和XSLT是業界廣泛採納的標準,如果今後採用不同的體系結構(如從J2EE移植到.Net或者相反),表現層的XSLT形式的介面可以重用。JSP或ASP就沒有這種可能。問題在於首先要管理關係型資料到層次型XML資料的對映,其次如果沒有一個好的工具,建立、維護XSLT也是很費時費力的事情。我現在的專案正在朝這個方向努力,希望能做一個象Delphi那樣好用的,基於XSLT的HTML介面控制元件開發、管理、使用環境。
9、充分估計開發的艱辛程度
這個,一言難盡。總之實際需求的變化往往是超乎我們想象的,要在需求分析結束的時候就清晰劃分模組介面幾乎做不到,計劃不如變化。而J2EE體系架構是重量級的框架,雖然app server實現了很多功能,但同時也要求你開發的時候付出額外的代價。對於J2EE專案的資金、時間、人手等資源估計,寧可多不可少,千萬不要簡單認為用了一個weblogic就萬事大吉了。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10901326/viewspace-965490/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 對於專案中簡單的多條件查詢的一些心得體會
- Linux上部署J2EE專案的過程及安全Linux
- 專案開發中對成長的一些思考
- 對付時間不充足的專案的一些思路
- 雲端專案管理軟體的一些功能?專案管理
- 帶專案的一些體會以及合格的 Leader 應該具備什麼特質?
- 對jquery原始碼中 clean函式的一些體會jQuery原始碼函式
- K專案的一些心得之專案管理篇專案管理
- 對於公司,也是我對軟體行業,軟體專案的五想法行業
- 不會用專案管理軟體,做不成專案經理專案管理
- 專案裡的一些小函式函式
- 使用 Got包的一些體會Go
- docker釋出專案的一些坑Docker
- 專案中使用 TypeScript 的一些感悟TypeScript
- 最近專案重構的一些感想
- 在專案中遇到的一些bug
- 專案0到1的一些感想
- rocketchip開發中的一些體會
- 大學期間承接軟體專案的一些個人觀點
- Angular 專案裡使用 scss 檔案的一些技巧AngularCSS
- 開源對映平臺Mapzen加入了Linux基金會的專案Linux
- 結對專案
- 軟體開發的一些思考及心得體會
- 15款主流專案進度軟體對比
- 專案中常用到的一些方法整理
- 小程式專案中的一些小問題
- 用vue做專案的一些總結Vue
- 2024年初找新SAP專案的幾個體會
- 一些提高開發效率的小體會
- 入門教程的一些學習體會
- 對於goland相對較新一些版本新建專案時沒有go mod模式選項的坑GoLand模式
- 收集的go基礎學習,專案實戰,go-awesome的一些專案Go
- 專家解讀:開源軟體專案是否會被限制出口?
- 對專案管理的一點思考專案管理
- 聊聊springboot專案中使用jackson的一些小技巧Spring Boot
- Laravel 專案上線的一些注意事項Laravel
- js 一些專案中常用的原型方法整理JS原型
- 專案中遇到的一些問題小結
- maven專案遇到的一些問題記錄Maven