軟件開發思想之我見
一
雖不敢自詡自己的代碼量有多大,但是這絲毫不能壓制我對於軟件開發的理解。寫的代碼越多,越發覺面向對象相對於面向過程是多么的優越,就比如簡單的jdbc編程,為執行一條解決目標業務的sql語句,往往會搭上更多的諸如加載驅動、獲取連接、捕獲異常、關閉資源等額外操作,對於初學者而言,反正有的是精力,也會覺得理所當然:有多少個方法,就會有多少個這樣額外的東西的身影存在。當這樣重復寫過兩三天后,開始有點反思了,考慮是不是應該把這些重復的、不涉及具體業務的固定步驟提取出來?於是有了JDBC操作數據庫的util工具類,把那些一成不變的動作按一定的功能封裝為不同的靜態方法。這種提取公共代碼轉為工具類的方法的確解決了燃眉之急,而且還似乎提升了自己的編程內功,但是當用過一兩個月后又發現自己的包里充斥着各種各樣的util工具類,導致包負荷量的臃腫,更麻煩的是這些特定的util工具類僅僅適合特定的應用場合,還不能在各個api、底層產品間平滑過渡。而你就會開始反思之前的封裝辦法似乎有點具有**特色主義的封裝——雖然符合特定場合的“國情”,但是我們要的是以不變應萬變!於是,你就開始嘗試着將你對重復工作的封裝進一步優化和擴展,反正算法和策略或是業務流程是不變的,何不弄一個為Template,設定好房屋的骨骼架構,留給以后的具體開發僅僅是一個蘿卜一個坑的往里填就是了。當這樣做過之后,又是一段時間編程中的游刃有余,但是后文似乎還沒有完,當你對這些重復功能或業務的封裝應用於更大更復雜的場合時,加上你的經驗的累積,開始站在更高的軟件思想角度來思考這是不是應該把這些東西復合成一個特定的領域解決方案?這樣想過之后,你開始將之前那些封裝再次進行肢解,應用更健壯、更靈活的設計邏輯和各式的設計模式來進行重新設計——於是,你從混沌未開中開辟了一條領域解決方案,甚至於你打算將之進行開源,這便是一個新的框架的誕生。
而這樣一個過程,或者說是設計思想的轉變,需要時間和代碼量的積累。的確,當你對現有的代碼進行分析、歸納、總結時,你才會發現很多顯而易見或者隱形的問題,這個時候你就會逐漸的反思自己的設計方式的合理性。面向對象的三大特征:封裝、繼承、多態,從字面上或者理論上是多么的容易理解,但是要在自己的代碼中體現,對於剛剛踏入程序開發行列的初學者而言又是何其的難,原因可能有經驗不足,在沒有多個可供選擇的設計方案下,只能依據流程式的思維把功能實現就好;也有可能是因為沒有面向對象設計的主動意識;還有可能是在時間和開發成本的約束下,顯得有些力不從心。
但是無論如何,我認為一種科學的設計思想比編碼本身更重要,這就相當於理論指導實踐,決策高於執行(很好的執行力在錯誤的決策下只會自食惡果)。不管是Gof的32種設計模式,還是面向對象的四大原則,亦或是基於UML的RUP等等,這些都是一種指導並實現高效編碼的理論思想。值得注意的是,這些設計思想和方式,並不能因為一兩本書的字面理解中深刻理解。
但是,過分講求這些條條框框而不具體問題具體分析,便會陷入另一個麻煩:教條主義。話說回來,所謂的最佳實踐也就是一個經驗的累積加上事實求是(具體問題具體分析),面向過程也好,面向對象也罷,都沒有絕對的好壞,這要依具體的情況而言。
二
對於項目的分析、設計,在后期開發的時候,以嚴謹的思維面對計算機沒錯,但是在分析設計階段,作為一個程序員很容易陷入系統的角度分析和考慮問題,這其實是很麻煩的。容易導致的結果是,你的后期的代碼實現依據了你自己的分析,但是你這種分析沒有以一個用戶的角度、一個業務人的角度來進行分析,很容易到最終你所實現的系統並不是用戶想要的甚至是不能被理解的。那么即使再安全、再高效、再優秀的系統也只能落得個返工的下場。“涉眾”決定“系統用戶”,“用例”決定“系統實現”。足見用例的重要性,我們尤其在對用例分析的時候,要多站在用戶的角度去思考用戶是想要實現怎樣一個系統或者功能,而不應是急促地跳進系統里去,用數據庫的CRUD來向用戶拍胸口保證這就是完美解決方案。
三
以上是關於我對設計思想的重要性的理解,還有一個很重要的就是關於項目管理方面的一個要注意的地方——專注核心功能的實現,把輔助性的功能放在次要位置!
對一個項目,為確保該項目正確地體現設計方案的要求,應該提取出項目的核心功能,並進行着重的開發、監督和控制。像一個基於元數據的數據庫管理視圖系統,其核心功能應該是三個模塊:其一,數據查詢;其二,數據編輯;其三,數據庫導入導出。雖然系統定義了用戶管理、角色分配、日志管理、修改密碼等功能,但是它們不是系統的核心,所以在核心功能沒有完成或者無法保證其按時、順利地完成的情況下,應該要減輕對這些次要功能的開發成本的投入。讓“核心”的人做核心的事,讓大的成本投入於核心的工作。除此之外,對於核心的模塊,也應該警惕開發人員一個與生俱來的癖好——遇到哪個問題往往糾結哪個問題,技術人員最喜歡死扣一個心眼兒,糾纏於一個死問題。問題當然是要解決的,而且應該制定專門的問題、bug匯總日志;只是如果站在全局的角度看,我們完全應該暫時“跳過”這個問題,把其他的東西先做着走,之后才回過頭來解決它。只有這樣,我們的才能夠保證項目有序地進行下去。