開發維護大型 Java 專案的建議
假設你是正在開發和維護一個包含2000個類並使用了很多框架的Java開發者。你要如何理解這些程式碼?在一個典型的Java企業專案小組中,大部分能夠幫你的高階工程師看起來都很忙。文件也很少。你需要儘快交付成果,並向專案組證明自己的能力。你會如何處理這種狀況?這篇文字為開始一個新專案的Java開發者提供了一些建議。
1、不要試圖一下子搞懂整個專案
好好考慮一下,為什麼理解專案程式碼是第一位的?大部分情況是你被要求修復一個bug或者加強系統已有功能。你要做的第一件事情不是理解整個專案的架構。當對專案進行維護時,這樣(理解整個專案架構)可能會對你造成巨大的壓力。
即便是有著10年可靠程式設計經驗的Java開發者可能也沒有理解專案的核心工作機制,儘管他們可能已經在這個專案工作超過一年(假設他們並非原始開發人員)。比如,對於認證機制或事務管理機制。
他們是怎麼做的?他們對於自己負責的部分非常瞭解,並且能夠交付價值給小組。每天的交付價值遠比了解一些以後還不確定有沒有的東西重要的多。
2、關注於盡快交付價值
那我是否定了你對於專案架構理解的熱情了麼?完全不。我只是要求你儘早的交付價值,一旦你開始一個專案,搭建了開發環境,你就不應該花一兩週時間才交付什麼,無論他的規模大小。假如你是一個有經驗的程式設計師卻兩週都沒有任何交付,你的經理怎麼會知道你是真的在工作還是在看新聞。
所以交付可以使大家都輕鬆起來。不要認為你能夠做有價值的交付前必須理解整個專案。這是完全錯誤的。加一段javascript的驗證程式碼對業務就很有價值,經理能夠通過你的交付達到對你的信任。這樣能夠向上級領導證明你的貢獻以及員工價值。
日復一日,在你不斷修復bug及增強功能之後,就能夠慢慢開始理解專案架構。不要低估對系統方方面面理解時需要花費的時間。花3-4天理解認證機制,2-3天理解事物管理。這些都是依靠之前的相似專案的經歷,但關鍵還是要花時間才能透徹的理解。要在日常工作中擠出時間,不要向經理要求特定的時間來做這些。
找找專案是否有一些不斷維護的單元測試用例。有效的單元測試用例是理解大型專案程式碼的很好途徑。單元測試能夠幫助理解程式碼片段,包括一個單元的外部介面(單元如何被呼叫以及返回內容)及其內部實現(除錯單元測試比除錯整個實際用例簡單許多)。
你如果能夠很好的理解一些內容,寫一些筆記,或者畫一些類圖、時序圖、資料模型圖,以便你或日後其他的開發者維護。
3、維護大型專案所必須的技能
你能從事當前的工作,必然已經具有良好的java技術。我們來談談能夠讓你在新專案中良好表現的其他技能。大部分時間,你在專案中的任務是修復bug和增強功能。
有兩項很重要的技能能夠協助你維護大型專案程式碼。
3.1能夠迅速發現需要的類
在任何維護活動中,無論是修復bug或增強功能,第一個動作就是識別出當前修復或增強的用例中呼叫的類。當你定位到需要修復或增強的類/方法,就已經完工了一半。
3.2能夠分析變更的影響
當你在完成必要的修改或增強工作後,最重要的就是要確認你的修改沒有破壞程式碼的其他部分。你要用你的java技術及對其他框架的理解找出變更可能影響的部分。下面有兩個簡單的例子詳細描述了最後提及的情況:
a)當類A的equals()方法變更後,呼叫一個保護A例項的List的contains()方法時就會被影響到。若Java知識不夠,很難考慮到這樣的影響。
b)在一個web專案中,我們假設“user id”儲存在session中。一個新入程式設計師可能在“user id”中加入一些資訊作為bug修復的方法,但是卻不知道會影響到那些關聯“user id”的用例。
當你提高了如上兩個技能,儘管你對專案不是非常瞭解,但大部分的維護任務會變得簡單很多。若你修復一個bug,你會定位並修復這個bug,並且保證變更不會破壞專案的其他部分。若你增強或加入一個特性,基本上你只需要模仿現有的特性使用相似的設計。
在一個線上銀行專案中,為什麼“檢視賬戶摘要”和“檢視交易歷史”的設計需要巨大的差別呢?如果你理解了“檢視賬戶摘要”的設計,完全可以模仿開發出“檢視交易歷史”的功能。
就修復bug和增強來說,你不必完全理解所有2000個類的工作內容和程式碼如何執行來推動系統。你若有上面的技能,就能很快定位需要修改的程式碼的部分,使用良好的java和框架技能修復,保證變更不會破壞專案的其他部分並交付,儘管你可能只知道一小部分專案的設計。
4、使用工具找到需要的變更內容以及變更產生的影響
繼續我們儘快交付的主題,你應當尋找那些能夠通過儘量少的瞭解專案但能幫助你儘快實施交付的工具作為輔助。
4.1 迅速發現需要變更內容的工具
無論是修復bug還是系統增強,首先都要找到該用例呼叫的你需要修改的類及方法。基本有兩種方式理解一個用例的工作方式,靜態程式碼分析和執行時分析。
原始碼分析統計掃描所有程式碼並且展示類之間的關係。市場上有很多裝置與工具。比如:Architexa, AgileJ, UModel, Poseidon等。
所有的靜態程式碼分析工具缺點在於無法確切展示用例中類或方法的執行時呼叫情況。因此Java新加入了特性,如回撥機制(callback patterns)。如靜態分析工具無法推斷出當頁面提交按鈕被點選時哪個Servlet被呼叫了。
執行時分析工具能夠展示類和方法在用例執行時的狀態。工具包括:MaintainJ, Diver,jSonde,Java Call Tracer等。這些工具可以捕獲執行時的堆疊狀態,並以此為一個用例生成序列圖和類圖。
序列圖展示了該用例在執行時所有呼叫的方法。若你在修復一個bug,那這個bug很可能就是這些被呼叫的方法之一。
若你在增強已有功能,利用序列圖理解呼叫流程然後再修改。可能是新增一個驗證,修改DAO等。
若你在新增功能,找到一些相似的特性,利用序列圖理解呼叫流程然後模仿開發新功能。
要小心挑選執行時分析工具。資訊過多是這類工具的主要問題。選擇一些提供簡單過濾無效資訊並能夠方便的檢視各種檢視的工具。
4.2 迅速發現需要變更內容的工具
若單元測試有效,可以通過執行單元測試發現變更有沒有破壞其他測試用例。有效維護並且覆蓋大型企業應用的單元測試還是比較少的。下面有一些針對該情況的工具。
仍然是有兩種技術靜態程式碼分析和執行時分析可以使用。市場中有很多靜態程式碼分析工具可用。如:Lattix, Structure101, Coverity, nWire and IntelliJ’s DSM。
給定一個變更後的類,上述工具均可識別對該類存在依賴的類的集合。開發者需要根據這些資訊“猜測”可能產生影響的用例,因為這些工具無法展示執行時類之間的呼叫關係。
市 場上的可以用於執行時影響分析的工具並不多,除了MaintainJ。MaintainJ先捕獲在一個用例中呼叫的所有類和方法。當所有用例的上述資訊都被捕獲之後,就很容易發現類的變更對用例的影響。MaintainJ能夠有效工作的前置條件就是專案的所有用例都應當先執行一遍,以便能夠獲得執行時的依 賴關係。
總之,目前你在迅速準確分析變更影響方面,還是可以從工具中獲得有限的幫助。首先根據需要實施一些影響分析,然後根據自己或小組其他高階成員評審來判斷變更的影響。你可能需要上面提到的工具對你的判斷進行反覆確認。
5、對上述內容的兩個忠告
5.1不要降低程式碼質量
為了快速交付,所以沒有全盤理解架構,但絕不能以降低程式碼質量為條件。下面是一些你可能因為只考慮快速交付而引發的程式碼質量問題。
因 為修改程式碼涉及到很多的依賴,所以新增程式碼相對而言風險較小。例如,有5個用例都呼叫了某個方法。為了改進某個用例,你需要修改這個方法的實現。最簡單的 做法就是複製這個方法,重新命名,然後在改進的用例中呼叫新方法。千萬不要這麼做。程式碼冗餘絕對是非常有害的。嘗試對方法進行包裝或者重寫,甚至是直接修 改,然後重新測試所有用例,通常停下來想一想,然後親手去實施,是一個比較好的方式。
另一個例子是將“private”方法改為“public”,使得別的類也可以呼叫。儘量不要將非必須的部分暴露出來。假如為了更好的設計需要重構,就應當著手去做。
大部分應用都有確定的結構和模式來實施。修復或增強程式時,確認你沒有偏離這樣的模式。若對約定不確定,請其他的高階開發者來稽核你的變更。若你必須做一些違背約定的實施,儘量放置於一個規模較小的類中(一個200行程式碼的類中的私有函式應當不會影響應用的整體設計)
5.2 不要停止深入理解專案架構
按 照文章列出的方式,假設你能夠在對專案瞭解較少的情況下進行交付並以此持續下去,可能你會停止對專案架構的深入瞭解。這樣從長遠角度來說對你的職業生涯沒有幫助。當你的經驗增加時,你應當承擔比較大的模組任務。如構建一個完整的新特性或者修改專案的一些基礎設計等較大的改進。當你能夠做這些改進時,你對項 目的整體架構應該相當瞭解。文中列舉的方法是讓你在最短的時間內提升自己,而不是阻止你完整理解整個專案。
6、 結論
整篇文章集中在對專案進行必要了解的前提下進行快速交付。你可以在不降低程式碼質量的前提下這麼做。
若修復一個bug,迅速定位並修復。有必要可以使用執行時分析工具。若新增一個特寫,可以尋找相似特寫,理解流程(有必要使用工具)並編寫。
或許這些聽起來很簡單,但是實用嗎?當然。但前提是你有良好的java技術以及對框架足夠了解才能先修改程式碼,然後對變更影響進行分析。對變更影響的分析比實施變更需要更多的技巧。你可能需要高階開發人員協助你分析變更影響。
大約有50%的IT可操作預算用於簡單的bug修復和功能增強。根據文中的建議,對於維護活動中的經費的節省應當還是很有幫助的。
相關文章
- 開發維護大型專案的Java的建議Java
- 給開發維護大型專案開發者的建議
- 維護大型開源專案,是怎樣的體驗?
- 推薦一些維護大型 Python 專案的工具Python
- 建立和維護大型Vue.js專案的10個最佳實踐Vue.js
- 如何構建大型的前端專案前端
- 學習開源專案的若干建議
- 【Lolttery】專案開發日誌 (三)維護好一個專案好難
- 大型專案開發: 標頭檔案順序
- 關於Sybase IQ所使用檔案系統維護建議TJ
- 8102年底如何開發和維護一個npm專案NPM
- 如何構建「大型 Node.js 專案」的專案結構?Node.js
- 其實大多開源專案是這樣維護的
- 關於介面可維護性的一些建議
- 測試專案管理的建議專案管理
- 用mobx構建大型專案的最佳實踐
- react-native大型專案開發實踐React
- 大型專案開發:謹慎使用智慧指標指標
- web前端基於vue的大型專案分模組開發Web前端Vue
- Android 開源專案維護者宣佈退出Android
- 如何開發Java專案Java
- 用mobx構建大型專案的最佳實踐(2)
- python大型專案開發規範_學習Python模組匯入機制與大型專案的規範Python
- mpvue開發大型體育專案及總結記Vue
- 如何在大型專案中使用Git子模組開發Git
- 大型開發專案中 git 工作流的最佳實踐Git
- 給予Java初學者的建議(JavaWeb/後臺開發)JavaWeb
- Java開發經典面試題分享,建議收藏Java面試題
- golang開發:go併發的建議Golang
- 如何開發不可維護的軟體?
- Gradle在大型Java專案上的應用GradleJava
- 高效專案管理的十條建議(轉)專案管理
- Webpack 4 構建大型專案實踐 / 微前端Web前端
- Webpack 4 構建大型專案實踐 / 優化Web優化
- 做開源專案的維護者,是怎樣一種體驗?
- 開發者死後,他的開源專案會有人繼續維護嗎?
- 【譯文】構建大型 Redux 應用的五個建議Redux
- 軟體保護建議