技術團隊中,財富即代碼,但并不是所有的代碼都是財富,有些代碼可能是毒藥。前段時間看到一篇文章,“你寫的代碼,是別人的噩夢嗎?”,雖然標題針對我們技術人員來說,可能有點刺耳,但有時候確實是不爭的事實。
在碼奴圈,有一句話很流行:“能運行工作的代碼就是好代碼”。這句話沒有對與錯,在小的創業團隊或人員能力不足的情況,能運行工作的代碼確實是好代碼,因為它解決了我們當時的問題。在對于有追求的技術人員來說,特別是在一個多人開發的團隊中,產品功能在不停的迭代、優化,好代碼就會我們的開發效率與維護效率帶來成倍的提升。
何謂“好代碼”,每個人的答案其實是不一樣的。但說到“壞代碼”,大家應該都能說出一籮筐來。
我先說一下我認為的“壞代碼”:可讀性差、業務邏輯相互纏繞、代碼復用性低,這樣帶來的后果將是隱藏bug、團隊其他人員調用或維護難以入手,更嚴重的可能就是重構。有時候可能陷入不停的重構循環當中去。原因有二:1.自己寫的代碼,沒有重構到關鍵點上;2.下一個重構者與上一個開發者不分伯仲。
那好代碼就是壞代碼的反面:可讀性強、業務邏輯低耦合高內聚、代碼復用性高、有良好的可拓展性。
說了這么多,解決問題才是王道,如何才能按照上面說的好代碼的目標開發,下面分享給大家一個容易入手的方法。
一、面向用例編程(橫向):
1.先把系統按照功能進行劃分,細化成多個功能模塊。做到每個模塊的功能是相對獨立的,但也有可能一個模塊與另一個模塊有交互。
2.將功能需求進行抽象,達到高內聚、低耦合的標準,明確該功能模塊的參與者是什么。
3.對每一個功能模塊進行業務分析,看看是否能再按照子功能進行細分,細分后形成具體的用例。
4.對具體用例進行分析,理清用例與參與者的關系、參與者與參與者的關系、以及用例與用例的關系。
將功能需求劃分成一個個獨立的用例后,我們就能很清晰的表達功能需求的分離與組合。即先造一個個通用的輪子,然后對這些輪子按照業務需求進行組裝。這樣就能達到有良好的組件顆粒度,很好的滿足了代碼結構清晰、復用性強、組件可任意插拔、各個功能可以獨立測試(單元測試)的目標。
面向用例編程的核心是把業務分解成一個個小的獨立的case(解耦),在根據業務需求將相關case聚集、組裝在一起(內聚)。最終又回歸到我們經常說的低耦合、高內聚的目標之上。大到模塊劃分、小到函數定義,都是同樣的方法。業務case集成一個模塊,功能函數聚集成一個類。
面向用例編程也是封裝的一種體現。將內部邏輯封裝在一個盒子(case)里,對外只需要暴露接口。調用者也只需要關注接口,不關心底層邏輯。
所以在我們開發之前,進行業務建模,還是很重要的。
二、分層架構(縱向)
上面說的面向用例編程是從橫向對業務功能進行解耦,那分層架構就是從縱向上對功能職責的劃分。不論是后端開發、前端開發還是客戶端開發,分層架構很普遍。通常我們會在縱向上對項目進行三層劃分:展示層、業務邏輯層、數據訪問層。MVC、MVP、MVVM都是為了更好的分層。
在團隊成員中,經常會有人質疑分層,認為有時候明明是一個很簡單的邏輯,非要搞幾層數據轉換,把結構搞的比較復雜。這個觀點也沒有錯,在生活中能用簡單的方法完成一件事情卻故意把事情搞的很復雜,確實是多此一舉。但我們通常是做一個復雜、龐大且不停迭代更新的項目,功能業務可能會像網狀一樣交織在一起。如果沒有清晰的結構、各個組件各司其職,如何能保證多人開發的團隊敏捷高效的共同開發,發現問題及時定位問題所在。
三、建立約束(規則)
約束即規范,團隊成員按照一套統一的規范開發,盡可能的降低溝通成本(了解現有代碼邏輯成本、業務調用成本、維護成本等)。約束包括一下幾個方面:
1.命名規范:按照規范進行合理的命名,BEAN、ENTITY、DTO、API等都分別代表不同的標簽或職責。看到名稱就知道它能做什么事情。
2.分模塊、分包:每一個組件或包都有自己明確定義的職責,不可以亂放。presenter包只放Presenter,config包只放配置文件等。
3.統一的結構:項目主體要統一結構,堅決不能出現相似業務不同代碼結構,這樣只會讓參與項目的其他成員不知所錯。
4.代碼檢查:如果有可能或有條件的話,通過工具或插件進行項目代碼的檢查,可以是靜態的編譯檢查,也可以是動態的運行時檢查。
總之,建立約束,就是讓項目的參與者開發出來的代碼盡可能的保持風格一致。
上面說了這么多,我們在開發過程中,只要代碼具有低耦合、高內聚、可拓展、有良好的可讀性,就是給團隊創造財富。
一種MVP的實現方式,目標:代碼高度復用、良好的組件顆粒度、方便進行單元測試,結構盡量清晰簡單的高內聚低耦合的分層結構。