利用模板代碼、開(kāi)發(fā)手冊、自動(dòng)化代碼檢查等最佳實(shí)踐改善項目執行
概要軟件開(kāi)發(fā)是復雜困難的。針對軟件開(kāi)發(fā),我們可能會(huì )在設計觀(guān)點(diǎn),相關(guān)解決方案,軟件模式等方面討論很多很多,但是軟件開(kāi)發(fā)的執行過(guò)程本身卻是一個(gè)需要許多模式和最佳實(shí)踐以節約寶貴時(shí)間的領(lǐng)域。本文展示3項軟件執行領(lǐng)域的最佳實(shí)踐以解決日常軟件項目執行中的問(wèn)題。
版權聲明:任何獲得Matrix授權的網(wǎng)站,轉載時(shí)請務(wù)必保留以下作者信息和鏈接作者:ShriKant Vashishtha
v_gyc(作者的Blog:
http://blog.matrix.org.cn/page/v_gyc)
原文:
http://www.javaworld.com/javaworld/jw-11-2005/jw-1114-j2ee.html譯文:
http://www.matrix.org.cn/resource/article/44/44148_J2EE+Best+Practices.html關(guān)鍵字:J2EE;Best;Practices
雖然在幾乎所有的項目中一些相同的問(wèn)題不斷重復出現,但是我們仍然缺少明確的方法來(lái)解決它們。 在軟件開(kāi)發(fā)的職業(yè)生涯中, 我使用了一些方法來(lái)解決這些重復出現的困擾我的大部分開(kāi)發(fā)項目的問(wèn)題,這些方法真正有助于項目執行效率的提升。本文中,我將與各位分享3項項目執行的最佳實(shí)踐,其中的某幾個(gè)方法有充分的資格可以被認定為模式(pattern)。
· 使用模板代碼
· 編寫(xiě)高效的開(kāi)發(fā)手冊
· 執行自動(dòng)化代碼檢查
使用模板代碼開(kāi)發(fā)者可以從參考簡(jiǎn)單的業(yè)務(wù)用例和復雜的業(yè)務(wù)用例的示例代碼實(shí)現中獲得幫助,編寫(xiě)出有效、高效率的代碼??紤]下面的一些經(jīng)常困擾軟件開(kāi)發(fā)項目的因素:
· 技術(shù)始終在變化,要找到對于新技術(shù)具有使用經(jīng)驗的有競爭力的技術(shù)人員是很困難的事情(譯注: 去做獵頭吧!)。另一方面,開(kāi)發(fā)新手可能不具備編寫(xiě)有效正確代碼的經(jīng)驗。模板代碼為開(kāi)發(fā)者的工作提供了良好的參考,使得學(xué)習新技術(shù)變的相對簡(jiǎn)單。
· 學(xué)習利用新技術(shù)需要時(shí)間,而且如果使用不當可能導致一團混亂,因此強迫開(kāi)發(fā)者自己學(xué)習新技術(shù)不是很好的途徑。 作為替代方法,提供模板代碼作為開(kāi)發(fā)者編碼的參考使得開(kāi)發(fā)者在開(kāi)發(fā)過(guò)程中獲得了學(xué)習新技術(shù)的良好起點(diǎn)。
· 許多項目必須由有限的人員在緊迫的期限內完成。項目團隊中的每個(gè)人都不應該重新造輪子。高級技術(shù)人員可能在設計階段提供幫助,不過(guò)項目進(jìn)行到實(shí)現階段可能就要求程序員自助了。一不留意的小問(wèn)題,到了發(fā)現的時(shí)候可能已經(jīng)造成了混亂。問(wèn)問(wèn)自己,使用Javadoc工具的時(shí)候,有幾次遵循了標準的格式和文檔生成指導方針呢?代碼是否遵循了定義良好的習慣用法和最佳實(shí)踐呢?那么如何貫徹這些良好實(shí)踐呢?此處,可視的模板代碼能夠提供比技術(shù)書(shū)籍或者參考手冊更有效的幫助,因此,應該使用模板代碼。
· 許多軟件項目不僅體積龐大,而且分布式地進(jìn)行開(kāi)發(fā)。有時(shí),項目的執行是同時(shí)在世界上的不同地點(diǎn)展開(kāi)的。作為開(kāi)發(fā)人員你不想看到——當你的項目部分接近完成時(shí),你的代碼的客戶(hù)驚奇的發(fā)現你的代碼沒(méi)有滿(mǎn)足他們的需求。應該在開(kāi)始編寫(xiě)代碼實(shí)現功能前,將示例代碼送給你的客戶(hù)評審,并記錄反饋。這些示例代碼不應該僅僅是類(lèi)似”世界,你好”的程序,應該具有代表性,與實(shí)際編寫(xiě)的代碼很接近。
· 通常開(kāi)發(fā)者都有一堆參考手冊、標準、程序框架等資料,可以在項目中通過(guò)它們來(lái)獲得幫助。但是,即使已經(jīng)完成了設計工作,編碼的風(fēng)格也不是顯而易見(jiàn)的,難以遵守??梢暤哪0宕a可以提供這方面的幫助。除非開(kāi)發(fā)者可以看到真實(shí)的代碼例程,否則他們對當前項目的解釋彼此間可能有些許的出入。 一個(gè)簡(jiǎn)單功能由多個(gè)開(kāi)發(fā)者來(lái)實(shí)現,其實(shí)現方式可能是不同的,甚至可能沒(méi)有一個(gè)與推薦的模擬最佳實(shí)現的方式相同。
模板代碼的實(shí)現首先,召集一組專(zhuān)家(技術(shù)上的和業(yè)務(wù)上的)從目標項目的問(wèn)題域中甄別出簡(jiǎn)單用例和復雜用例各一個(gè),并在現有設計的基礎上分別實(shí)現這兩個(gè)用例。這樣,項目組就擁有了自己的模板代碼。下面列出了一些編寫(xiě)模板代碼的小技巧
· 模板代碼中應該包含立即可用的編譯和部署腳本。否則,在開(kāi)發(fā)的構建階段解決這些問(wèn)題又要浪費不少時(shí)間。
· 項目的基本目錄結構應該準備完畢,并且包含了欲在項目中使用的各種庫。
· 模板代碼應該遵循項目中使用的命名規范、代碼風(fēng)格、其它標準以及應用框架的要求。
· 模板代碼中應該使用定義良好的Javadoc模板(比如、基于Eclipse的Javadoc模板),以幫助開(kāi)發(fā)人員編寫(xiě)javadoc注釋。編寫(xiě)良好的javadoc注釋是很重要的,通常這些注釋可能是代碼維護和再開(kāi)發(fā)團隊的唯一可用的文檔。
· 程序語(yǔ)言中明確的編碼慣用法應該在模板代碼中使用,這有助于開(kāi)發(fā)者編寫(xiě)有效的代碼。
· 模板代碼應該明確定義使用開(kāi)發(fā)框架的標準方法。對于新的開(kāi)發(fā)者來(lái)說(shuō),在項目的初始構建階段編寫(xiě)基于特定框架的實(shí)現類(lèi)是很困難的任務(wù)。示例代碼有助于新的開(kāi)發(fā)者理解框架等概念。即使框架有許多文檔,利用框架進(jìn)行有效率的開(kāi)發(fā)也并不都是很容易。
· 模板代碼應該展示如何利用JUnit或其他測試框架編寫(xiě)測試用例(test cases)。
· 客戶(hù)的技術(shù)團隊應該評審這些模板代碼,這樣他們對于在項目構建階段結束時(shí)的代碼質(zhì)量具有更明確的認識,而不會(huì )在最后時(shí)刻感到意外。
· 模板代碼應該從頭到尾的涵蓋用例,比如從表示層到數據層。
· 對于模板代碼的各種細枝末節應該進(jìn)行一次詳盡的介紹,使得開(kāi)發(fā)者熟悉它們。開(kāi)發(fā)者應該理解在架構的每個(gè)層次需要做那些工作、使用了(或者可能使用)那些編碼慣用法和最佳實(shí)踐,以及為什么使用它們。
使用模板代碼的好處· 開(kāi)發(fā)者獲得開(kāi)始編寫(xiě)代碼的參考
· 客戶(hù)與開(kāi)發(fā)者就項目預期質(zhì)量達成一致,因而避免了通常由于理解差異產(chǎn)生的各種問(wèn)題。
· 開(kāi)發(fā)者擁有了開(kāi)始編碼工作的骨架。
· 開(kāi)發(fā)者更容易掌握并應用項目中使用的開(kāi)發(fā)框架和各種外部API,這有助于提高開(kāi)發(fā)效率。
· 開(kāi)發(fā)者沒(méi)有重新造輪子。大部分的最佳開(kāi)發(fā)實(shí)踐和編碼慣用法都擺在了他們面前,這也可以提高開(kāi)發(fā)效率。
有效的開(kāi)發(fā)手冊假設我們必須完成一個(gè)日常開(kāi)發(fā)人員為30到50人的大項目。不是所有的開(kāi)發(fā)人員都掌握了需要使用的技術(shù)以及遵循的標準。一個(gè)項目可能需要使用很多技術(shù)以及私有的開(kāi)發(fā)框架。這些框架可能在以后的Java企業(yè)項目中使用。有效的在項目間,開(kāi)發(fā)者之間進(jìn)行大量知識的轉移是一個(gè)大挑戰。知識轉移也涉及到如下的一些問(wèn)題:
· 很多大型項目的開(kāi)發(fā)持續很長(cháng)時(shí)間(1到2年)。我們必須正視這樣的事實(shí):軟件行業(yè)具有相當高的離職率,這是基本的現實(shí)也是一個(gè)挑戰。雇用新人可能很容易,但是教授新人項目知識卻又是一項艱巨任務(wù),特別的,考慮到項目的進(jìn)展不能停滯不前。
· 一些開(kāi)發(fā)者可能不具有期望的技術(shù)水平?,F在,適時(shí)的找到掌握技術(shù)的開(kāi)發(fā)者是很困難的。當項目期限很急時(shí),新的開(kāi)發(fā)者沒(méi)有時(shí)間去學(xué)習厚厚的技術(shù)書(shū)籍或者參考手冊。一部分人可能工作敏銳、高效,這樣可以騰出額外時(shí)間來(lái)學(xué)習并應用新的技術(shù),但是不能假定所有人都會(huì )如此。
· 維護一個(gè)構建完畢的軟件項目同樣也是大的挑戰。在開(kāi)發(fā)周期后的代碼維護工作可能是由客戶(hù)的IT團隊執行的。對他們來(lái)說(shuō),熟悉項目的技術(shù)架構并且改動(dòng)代碼以做出改變很困難。如果沒(méi)有定義明確的方式來(lái)傳遞這些知識,那么在維護階段的初期,客戶(hù)IT團隊研讀項目代碼和設計文檔的工作可能會(huì )是很沮喪的經(jīng)歷。
開(kāi)發(fā)手冊應該能夠解決上面提到的問(wèn)題,但是如何編寫(xiě)一個(gè)有效的開(kāi)發(fā)手冊呢?
編寫(xiě)開(kāi)發(fā)手冊下面是一些如何編寫(xiě)開(kāi)發(fā)手冊的提示:
· 開(kāi)發(fā)手冊應該包含全部與搭建開(kāi)發(fā)環(huán)境相關(guān)的必要信息
· 開(kāi)發(fā)手冊的語(yǔ)句應該簡(jiǎn)明易讀。如果閱讀的人發(fā)現手冊很難閱讀,這不是閱讀者、而是手冊編寫(xiě)者的失敗。
· 開(kāi)發(fā)手冊應該包含大量的示例。示例可以有效地表明手冊的內容。
· 請求一位不熟悉項目中所使用的技術(shù)的開(kāi)發(fā)者檢查開(kāi)發(fā)手冊。這樣,如果手冊?xún)劝瑫?huì )造成迷惑或者不明確的內容,可以在其它人使用本手冊前修改這些地方,以使手冊更清晰明確。
· 開(kāi)發(fā)手冊應該在底層設計階段,作為階段任務(wù)的一部分完成。當構建階段開(kāi)始時(shí),開(kāi)發(fā)者可以有效利用本手冊。
· 開(kāi)發(fā)手冊需要包括多少信息呢?如何在信息的多寡中平衡呢?開(kāi)發(fā)者不喜歡厚重的手冊。但是,開(kāi)發(fā)手冊中不能遺漏可以為許多不明確之處提供語(yǔ)境的信息。需要考慮開(kāi)發(fā)者的真正需求,而不是僅僅考慮可以提供的全部信息是什么。使用簡(jiǎn)單的、直截了當的、漸進(jìn)的方式來(lái)編寫(xiě)開(kāi)發(fā)手冊。
· 開(kāi)發(fā)手冊的信息提供方式應該與閱讀者的閱讀直覺(jué)相符,而不該是在各處零落地散布著(zhù)這樣那樣的信息。手冊?xún)热莸慕M織方式應該與現實(shí)中開(kāi)發(fā)項目時(shí)需要閱讀信息的先后步驟一致。 比如,對于Java企業(yè)項目,首先需要搭建開(kāi)發(fā)環(huán)境,然后開(kāi)始表現層和應用數據層的編碼工作。手冊信息也應該以同樣的順序組織。
· 需要明確的是:手冊不能迷惑開(kāi)發(fā)者。比如,開(kāi)發(fā)者在編寫(xiě)Struts框架下的Action類(lèi)時(shí)需要使用特定的Xdoclet標簽,那么開(kāi)發(fā)者應該很清楚項目中使用的各種XDoclet標簽的意義和使用方式。為了查找更詳盡的信息,開(kāi)發(fā)者總是可以參考開(kāi)發(fā)手冊。
下面我們考慮一個(gè)在Java企業(yè)項目中的使用的真實(shí)地開(kāi)發(fā)手冊應該是什么樣的,它應該包含的信息細節如下:
· 開(kāi)發(fā)環(huán)境搭建的細節:當新的開(kāi)發(fā)者加入項目時(shí),必須搭建開(kāi)發(fā)環(huán)境,然后才能開(kāi)始工作。不要認為開(kāi)發(fā)者清楚項目的大小細節。如果項目一起使用了Eclipse和Weblogic開(kāi)發(fā)Web應用,新的開(kāi)發(fā)者可能都不清楚Eclipse或者Weblogic是什么東東。因此,搭建開(kāi)發(fā)環(huán)境的細節信息應該是開(kāi)發(fā)手冊的第一部分。具有基本Java知識的新開(kāi)發(fā)者應該很容易的按照手冊中的這些信息搭建開(kāi)發(fā)環(huán)境。
· 表現層的細節:通常,開(kāi)發(fā)者對某個(gè)用例的實(shí)現從表現層開(kāi)始。開(kāi)發(fā)手冊中應該包含如何創(chuàng )建表現層組件元素的詳細步驟。比如,項目的表現層使用Struts框架,手冊中應該包含如何編寫(xiě)Action類(lèi)和Form類(lèi)的確定步驟。如果項目使用XDoclet來(lái)構建Struts配置文件struts-config.xml和其他配置文件,相應的這些步驟也應該包含在內。JSP的相關(guān)技術(shù)信息也應該如此。應用MVC模式,無(wú)論如何不應該在JSP頁(yè)面中包含任何Java代碼來(lái)實(shí)現業(yè)務(wù)邏輯。但是在實(shí)際開(kāi)發(fā)中如何使用JSTL(JSP標準標簽庫)標簽來(lái)實(shí)現那樣的要求對于初學(xué)者或者是中級開(kāi)發(fā)者可能都是很大的難題。開(kāi)發(fā)手冊中包含一些展示如何在JSP頁(yè)面中使用JSTL標簽的真實(shí)示例可能對這些開(kāi)發(fā)者有些幫助。
· 業(yè)務(wù)層的細節:業(yè)務(wù)邏輯可以應用無(wú)狀態(tài)EJB組件、基于Spring的組件、或者簡(jiǎn)單的原始java對象(plain-old java object)來(lái)實(shí)現。開(kāi)發(fā)手冊中應包含項目中使用的業(yè)務(wù)組件代碼的骨架以及業(yè)務(wù)邏輯實(shí)現的實(shí)際例程
· 數據層的細節:依賴(lài)于項目使用的持久化機制,開(kāi)發(fā)手冊中應該包含JDBC、Hibernate或者任何基于其它框架的DAO(數據訪(fǎng)問(wèn)對象)的信息,包含項目中如何使用此持久化機制的步驟以及最佳實(shí)踐。
· 其它信息:手冊需提供J2EE項目架構各層中使用的各種內部或者外部組件的信息。例如,應該包括日志、郵件、代碼檢查和安全等組件的信息。同樣的,在項目后期,手冊中應該包含一些如何擴展業(yè)務(wù)需求的章節。比如,項目中使用了批處理框架,那么如何為新的批處理需求擴展它呢?
自動(dòng)化代碼檢查代碼檢查是另外一項需處理的事項。當代碼大量生成時(shí),持續的代碼檢查是必須的工作。即使已經(jīng)定義了一套代碼檢查的規則,還是有許多問(wèn)題沒(méi)有辦法在這些規則中描述并加以限制?;趥€(gè)人能力和經(jīng)驗,每個(gè)人都有自己的代碼檢查方式。同時(shí),有些問(wèn)題很微小,無(wú)法進(jìn)行逐行檢查。 如果需要檢查的代碼數量很大,這些微小的問(wèn)題可能會(huì )在一些地方被忽略掉。如果IDE自身產(chǎn)生了錯誤又怎么辦?還好,有些工具可以替代人工代碼檢查來(lái)發(fā)現這些問(wèn)題。
Eclipse IDE的設置有時(shí), 設置IDE的選項可以提供些幫助。比如,你可以配置Eclipse IDE的選項,當代碼中出現問(wèn)題時(shí)顯示警告。下圖是如何在Eclipse中設置Javadoc配置選項的示例。
圖 1. Eclipse Javadoc 設置
選項設置好后,Eclipse會(huì )在出現錯誤時(shí)顯示警告信息,然后開(kāi)發(fā)者可以修改。如果項目標準很?chē)栏?,IDE的警告將升級為錯誤,開(kāi)發(fā)者必須處理這些問(wèn)題。
Jlint 代碼檢查工具類(lèi)似的,可以在Eclipse中使用Jlint工具以發(fā)現代碼中的微小問(wèn)題。下面是在Eclipse中如何使用JLint的方法和步驟:
· 下載jlint的2進(jìn)制版本以及相應的Eclipse插件,解壓縮2進(jìn)制版本到C:\lint目錄,解壓縮插件到Eclipse插件目錄。
· 運行Eclipse, 選擇菜單項Window(窗口)->Preferences(設置)->Java->Jlint,設定jlint.exe的目標位置為C:\jlint\jlint.exe
· 在Eclipse的資源(Resource)視圖中右鍵點(diǎn)擊你的項目,然后選擇jlint選項即可。當一次完整地工作區編譯后,Jlint會(huì )在工作區內可能出現問(wèn)題的地方顯示黃色警告標記。
下圖 顯示了如何在Eclipse中配置Jlint
圖2 Eclipse中Jlint插件的配置
Lint4j 如果不使用IDE,那么可以結合ant使用lint4j發(fā)現代碼中的問(wèn)題。Ant腳本中需要聲明的參數如下:
· lint4j.dist.dir: lint4j的分發(fā)包的安裝目錄
· packages:需要由lint4j檢查的java包名稱(chēng)
· ignorePackages: 不需要由lint4j檢查的java包名稱(chēng)
下面是使用jlint的ant腳本示例:
lint4j的Ant Build腳本
<?xml version="1.0"?>
<project name="Lint4j" default="lint4j" basedir=".">
<property name="lint4j.dist.dir" value="C:/tools/lint4j-0.8.2"/> <!—lint4j包的路徑-->
<property name="lint4j.level" value="5"/> <!—lint4j檢查使用的參數-->
<property name="lint4j.exact" value="false"/> <!—lint4j檢查使用的參數-->
<taskdef name="lint4j" classname="com.jutils.lint4j.ant.Lint4jAntTask">
<classpath>
<pathelement location="${lint4j.dist.dir}/jars/lint4j.jar" /> <!—lint4j包的信息-->
</classpath>
</taskdef>
<target name="lint4j" description="Run Lint4j on your source">
<!—lint4j 忽略不處理的java包 需要檢查的包 其它參數,詳見(jiàn)lint4j文檔 -->
<lint4j ignorePackages="" packages="com.domain.*" level="${lint4j.level}" exact="${lint4j.exact}">
<sourcepath>
<dirset dir=".">
<include name="**/src" />
</dirset>
</sourcepath>
<classpath>
<pathelement location="C:/bea/weblogic81/server/lib/weblogic.jar" />
<fileset dir=".">
<include name="**/*.jar" />
<include name="**/*.zip" />
</fileset>
<fileset dir="ejblib">
<include name="**/*.jar" />
</fileset>
<fileset dir="lib">
<include name="**/*.jar" />
</fileset>
</classpath>
<formatters>
<formatter type="text" />
<formatter type="text" toFile="./target/lint4j.log"/> <!—lint4j報告文件-->
</formatters>
</lint4j>
</target>
</project>
Checkstyle工具代碼檢查的另一個(gè)工具是CheckStyle,它會(huì )依照java開(kāi)發(fā)專(zhuān)家廣泛使用的Java編碼規范來(lái)檢查代碼質(zhì)量??梢越Y合Ant使用(也有Eclipse插件)。CheckStyle的檢查選項是高度可配置的,可以配置成支持任何代碼規范的檢查。它的下載版本中包含了一個(gè)支持Sun編碼規范(Sun’s Coding Conventions)檢查的規則配置文件。 編寫(xiě)Ant腳本使得代碼檢查同編譯過(guò)程一起完成,這樣開(kāi)發(fā)者可以注意到代碼包含的錯誤并改正它們。
結論在軟件開(kāi)發(fā)項目中的需要面對的大部分的普通問(wèn)題是重復出現的。在如今充滿(mǎn)競爭的世界里——縮減開(kāi)發(fā)期限、降低項目成本的壓力很大,想在每個(gè)項目中重新造輪子根本就沒(méi)有時(shí)間。
本文并未對軟件開(kāi)發(fā)執行過(guò)程中會(huì )出現的問(wèn)題都提供了解決方案,只是踏出了前行的一步,其目的是展示最佳軟件開(kāi)發(fā)實(shí)踐和高效工具的使用。了解了這些以及未來(lái)會(huì )學(xué)習到的最佳實(shí)踐和模式,你就對軟件生命周期中容易出現的任何障礙做好了準備。這些也可以使得項目管理者、架構人員和開(kāi)發(fā)者能夠集中精力進(jìn)行“真正”的開(kāi)發(fā),而不是疲于應付開(kāi)發(fā)中出現的各種問(wèn)題。
希望在未來(lái)的軟件開(kāi)發(fā)中,更多的專(zhuān)家會(huì )貢獻并記錄更多的最佳實(shí)踐和模式,軟件開(kāi)發(fā)實(shí)踐作為一門(mén)藝術(shù)的同時(shí)也成為具有更多確定性的一門(mén)科學(xué)。
關(guān)于作者ShriKant Vashishtha是一名技術(shù)架構人員,現供職于印度Tata咨詢(xún)服務(wù)有限公司。作者具有超過(guò)7年的軟件開(kāi)發(fā)經(jīng)驗,曾參與了多個(gè)基于J2EE技術(shù)的大型項目的技術(shù)架構設計。他具有印度Motilal Nehru National Institute of Technology大學(xué)的電機工程學(xué)科的工學(xué)學(xué)士學(xué)位。
資源· SourceForge上的XDoclet項目,代碼生成器
· Eclipse主頁(yè) 開(kāi)源的集成開(kāi)發(fā)環(huán)境平臺
· SourceForge上的Jlint代碼檢查工具項目主頁(yè)
· Lint4j代碼檢查工具的主頁(yè)
· CheckStyle代碼檢查工具的主頁(yè)
· Sun文檔:如何編寫(xiě)javadoc注釋
· 更多關(guān)于Java Enterprise Edition的文章,請瀏覽javaworld’s J2EE主題部分
· 譯注:補充翻譯者日常使用的幾個(gè)代碼質(zhì)量檢查工具 pmd設計/代碼檢查工具 metrics代碼質(zhì)量檢查工具