一個(gè)軟件項目從探索階段到發(fā)展方向明確階段,會(huì )經(jīng)歷從簡(jiǎn)單到復雜的一個(gè)過(guò)程,需求的不斷疊加,會(huì )讓系統越來(lái)越龐大,功能繁多,公司業(yè)務(wù)的擴展也讓軟件系統的生命周期變的更長(cháng)。在業(yè)務(wù)變復雜軟的過(guò)程中,各種原因的驅使,代碼質(zhì)量會(huì )退化,維護和開(kāi)發(fā)新功能的成本也會(huì )相應的變高,推倒重新開(kāi)發(fā)的成本也是高的嚇人。
大多情況下編碼設計質(zhì)量最高的時(shí)候是根據第一版需求進(jìn)行編碼實(shí)現的時(shí)候,但只要需求一變更,就會(huì )打亂原來(lái)的編碼設計,軟件質(zhì)量也就會(huì )越來(lái)越差?;蛘呔蜎](méi)有了設計。
到了項目中期,有新的功能或者bug的修復,老板就給我了一天時(shí)間,讓我寫(xiě)好處理代碼?逾期是要被罵的;這個(gè)沒(méi)用的功能,做了也沒(méi)人用,隨便寫(xiě)吧,早點(diǎn)結束,早去干別的;我手上現在這么多活,你又插進(jìn)來(lái)個(gè)新功能,我只能亂搞了,團隊內人員水平的不同寫(xiě)的代碼更是天差地別,等等,這都是我們實(shí)際工作中會(huì )遇到的問(wèn)題。責任心讓我們也會(huì )想先這樣寫(xiě),以后再重構,一般以后重構表示永遠不會(huì )重構。
上面說(shuō)的這些都會(huì )讓我們增加糟糕的代碼,混亂的業(yè)務(wù)邏輯分布在我們系統的各個(gè)地方,部門(mén)人員變動(dòng),新的員工更不可能理解那些雜亂無(wú)章的東西,再接著(zhù)推糟糕的代碼,想要理清楚一個(gè)業(yè)務(wù)邏輯,非常容易在混亂的代碼中迷路。最直接的后果就是這些混亂的代碼會(huì )增加新功能的開(kāi)發(fā)周期,領(lǐng)導層問(wèn)為啥現在開(kāi)發(fā)個(gè)功能這么慢?是不是人手不夠,再招幾個(gè)人吧。這雜亂的項目,不是新員工能理的清的,你會(huì )發(fā)現,雖然員工變多了。但開(kāi)發(fā)效率還是上不去。
那我們重新來(lái)做一個(gè)新的系統完全替代這個(gè)老項目吧,我們可以用最新的框架,更好的實(shí)現方式去完成這個(gè)系統,這種天真的想法會(huì )在團隊成員的腦海里無(wú)數次出現,舊的系統業(yè)務(wù)很復雜,新的系統在兼容舊系統邏輯的同時(shí),舊的系統也在更新需求,增加功能,在新系統完全可以抗衡舊系統之前,舊的系統會(huì )一直運行。如果你的新系統開(kāi)發(fā)的時(shí)間過(guò)長(cháng),等完成的時(shí)候,可能員工都已經(jīng)不知道換了幾批了,代碼又亂成了一鍋粥,周而復始。
軟件的退化變的越來(lái)越嚴重的過(guò)程中,我們也在思考和改變現有的系統,如何才能讓系統的在擁有更長(cháng)的生命周期的同時(shí),提高代碼的質(zhì)量,不讓其退化,并擁有更好的可維護性和擴展性?那就是根據需求的變化去調整架構、代碼,不斷的打破原來(lái)的設計,保持清晰,而不是讓他爛在那里。
大多數人能想到的最直接的方案是從架構入手,引入多維度的架構,微服務(wù)化,領(lǐng)域驅動(dòng)模型(DDD)等等
從頂層設計出發(fā)引入新的架構模型,或者說(shuō)根據需求的變動(dòng)不斷的調整代碼的分層和模塊,加上理論知識的應用,會(huì )讓業(yè)務(wù)代碼在結構歸屬上更清晰。分層的嚴密能讓整體的業(yè)務(wù)邊界更明確,前提是我們要從多維度去審視系統的構架,思考如何去現有的架構做出合理的改動(dòng)。
比如在項目初期業(yè)務(wù)比較簡(jiǎn)單,最簡(jiǎn)單的分層架構就實(shí)現了項目需求,觀(guān)察我們的架構可能是這樣子的,從上而下的松散分層架構
后來(lái)又加入了緩存,又加入了消息隊列,業(yè)務(wù)的不斷擴張又加入了不同的數據庫nosql,業(yè)務(wù)的升級有了v2.0,v3.0,新業(yè)務(wù)要兼容舊功能等等,如果還是原來(lái)的分層結構,很快就會(huì )出現邏輯代碼堆積的問(wèn)題,業(yè)務(wù)層之間引用雜亂,一個(gè)代碼文件幾千行代碼,需求變動(dòng)時(shí)牽一發(fā)動(dòng)全身,及時(shí)調整架構的必要性就體現出來(lái)了。
一定要復用好依賴(lài)倒置原則,層與層之間不應該依賴(lài)實(shí)現,要依賴(lài)于抽象,比如我們的基礎設施層要為其他三層提供支持,基礎設施層可以實(shí)現其他層定義的接口來(lái)進(jìn)行抽象,從這個(gè)角度來(lái)開(kāi)的話(huà)我們的基礎設施層應該在最上面,也可以是左邊或者右邊
應用依賴(lài)倒置后,我們調用的是抽象接口,你會(huì )發(fā)現層的概念沒(méi)有了,層的概念被打破了,我們可以更激進(jìn)一點(diǎn)把基礎設施層剝離出去用各種適配器去接入各種組件,把層的關(guān)系拉平,把架構調整為六邊形構架
不要固化自己的思維,根據業(yè)務(wù)和系統的發(fā)展去調整你的系統架構,能讓系統能更高的可擴展和可維護性。
對于非常老的項目調整架構是痛苦的,一定要得到管理層充分的支持下再去做改造,這樣的工作只能是從上往下推進(jìn),痛苦的過(guò)程終會(huì )換來(lái)后期維護的喜悅。
在團隊內除了要有代碼規范,所有人都要遵守,這樣代碼的風(fēng)格才能更統一,和使用Lint工具去檢查代碼,各種語(yǔ)言lint工具,能在早期查檢出你代碼中不合理的地方。還有下面一些辦法
程序員最喜歡的就是編碼實(shí)現具體的功能,在這里才是我們真正秀內功的地方,可以應用各種模式把代碼和邏輯寫(xiě)的很漂亮,但是放到整個(gè)項目結構里,被調用和使用的過(guò)程又感覺(jué)那么的不協(xié)調,根源是我們模塊劃分不正確,模塊之間的依賴(lài)耦合性太強。
這就是典型的寫(xiě)的很優(yōu)雅,使用的很粗糙。依賴(lài)倒置原則,依然適用于模塊間的劃分,模塊與模塊之間的依賴(lài)是倒置的,用依賴(lài)注入的方式去解耦,模塊對外暴露出盡可能少的接口,之間的調用依賴(lài)于接口。抽象的好處能讓你把模塊的邊界定義的更明確。
業(yè)務(wù)越復雜,需要操作的對象也就越多,對象的邊界不明確就會(huì )出現糾纏不清的情況,要不就是一個(gè)對象負責的東西過(guò)多;要不就是幾個(gè)對象同時(shí)做一件事,邏輯雜亂。
當你發(fā)現你的對象之前不再是協(xié)作關(guān)系時(shí)就要停下來(lái),從高處去看你組織的代碼,把大對象分解,職責界線(xiàn)理清楚也就是功能單一原則,很多同學(xué)不知道如何確定一個(gè)對象的職責,不清楚一個(gè)屬性是不是屬于某個(gè)對象,最簡(jiǎn)單的方法就是,判斷這個(gè)屬性的變動(dòng)會(huì )不影響某個(gè)對象,如果沒(méi)有就不屬于這個(gè)對象。
還有就是,面對新的業(yè)務(wù)需求敢于打破原有的代碼設計,不破不立。
定期要檢查和刪除沒(méi)用的代碼。少寫(xiě)或者不寫(xiě)感覺(jué)未來(lái)可能會(huì )用到的方法,這些多出來(lái)的代碼會(huì )成為將來(lái)重構的絆腳石,會(huì )浪費精力在這些沒(méi)有用到的代碼上,查找有沒(méi)有地方在使用他。
不能不提的,就是Bob大叔(Robert C. Martin)的SOLID編碼原則,他是設計模式的基石,要不斷的去應用和實(shí)踐。
隨著(zhù)編碼時(shí)間的增長(cháng),越來(lái)越感覺(jué)SOLID真的是一盞明燈,當你在黑暗中找不到方向的時(shí)候,指引你回歸正確的道路。
如果你對SOLID原則應用的比較熟練,我上面說(shuō)的幾項完全都可以忽略。
具體的代碼示例這篇帖子就不寫(xiě)了。
被bob大叔指到的你,一定能寫(xiě)出更完美的代碼
新功能的開(kāi)發(fā)的同時(shí)要重構之前邏輯,堅持開(kāi)閉原則,能達到事半功倍的效果。
工作閑暇時(shí)間去瀏覽現有的代碼邏輯,我們每天都在成長(cháng),對系統的認知也在改變,思維方式也在不斷的變化,用現在的眼光去審視舊的代碼邏輯,大多數是能找可以?xún)?yōu)化的地方,或者隱藏的bug,重構他,不要以為這些只是一些擠牙膏式的調優(yōu),所有的事情都有一個(gè)從質(zhì)變到量變的過(guò)程。
代碼評審在團隊里還是很有必要的,代碼評審不是口水戰,也不是批斗大會(huì ),如果只是走形式code review的意義也就不存在了。
你寫(xiě)的代碼是需要讓團隊的成員能看明白的,將來(lái)也是會(huì )有新的員工來(lái)維護你寫(xiě)的功能的,code review是一個(gè)能讓團隊內的其他成員快速了解新代碼意圖的辦法。
大多數團隊里程序員的水平參差不齊的,對業(yè)務(wù)和系統的理解深度也是不一樣的,讓團隊內不同的人去code review能及時(shí)發(fā)現代碼中的不足之處,哪些地方邏輯上有問(wèn)題,哪里的業(yè)務(wù)沒(méi)有考慮全面。
當一次提交的代碼太多時(shí),一下子是看不完,也可能理解不了,就要很評審整體思路,再review實(shí)現主干邏輯,最后才是實(shí)現細節。
需說(shuō)明一下的是,code review 并不能完全發(fā)現代碼中隱藏的bug,不要把找bug的任務(wù)和他混在一起。
學(xué)習多少構架或者框架知識,都不能阻止我們寫(xiě)爛代碼。但當你沉下心來(lái)去打磨產(chǎn)品或者認真去實(shí)現一個(gè)功能時(shí),你會(huì )在意你寫(xiě)的代碼,會(huì )主動(dòng)去寫(xiě)更清晰的邏輯,并改變和想辦法去并處理糟糕的代碼,希望這篇帖子有能幫助到你的地方。
原文轉自:https://www.cnblogs.com/li-peng/p/15775038.html