自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

關(guān)于代碼質(zhì)量退化的思考

開發(fā)
軟件的退化變的越來越嚴(yán)重的過程中,我們也在思考和改變現(xiàn)有的系統(tǒng),如何才能讓系統(tǒng)的在擁有更長的生命周期的同時(shí),提高代碼的質(zhì)量,不讓其退化,并擁有更好的可維護(hù)性和擴(kuò)展性?

一個(gè)軟件項(xiàng)目從探索階段到發(fā)展方向明確階段,會(huì)經(jīng)歷從簡單到復(fù)雜的一個(gè)過程,需求的不斷疊加,會(huì)讓系統(tǒng)越來越龐大,功能繁多,公司業(yè)務(wù)的擴(kuò)展也讓軟件系統(tǒng)的生命周期變的更長。

在業(yè)務(wù)變復(fù)雜的過程中,各種原因的驅(qū)使,代碼質(zhì)量會(huì)退化,維護(hù)和開發(fā)新功能的成本也會(huì)相應(yīng)的變高,推倒重新開發(fā)的成本也是高的嚇人。

代碼質(zhì)量退化的步驟

大多情況下編碼設(shè)計(jì)質(zhì)量最高的時(shí)候是根據(jù)第一版需求進(jìn)行編碼實(shí)現(xiàn)的時(shí)候,但只要需求一變更,就會(huì)打亂原來的編碼設(shè)計(jì),軟件質(zhì)量也就會(huì)越來越差。或者就沒有了設(shè)計(jì)。

圖片

代碼的變化趨勢

到了項(xiàng)目中期,有新的功能或者bug的修復(fù),老板就給我了一天時(shí)間,讓我寫好處理代碼?逾期是要被罵的;這個(gè)沒用的功能,做了也沒人用,隨便寫吧,早點(diǎn)結(jié)束,早去干別的;我手上現(xiàn)在這么多活,你又插進(jìn)來個(gè)新功能,我只能亂搞了,團(tuán)隊(duì)內(nèi)人員水平的不同寫的代碼更是天差地別,等等,這都是我們實(shí)際工作中會(huì)遇到的問題。

責(zé)任心讓我們也會(huì)想先這樣寫,以后再重構(gòu),一般以后重構(gòu)表示永遠(yuǎn)不會(huì)重構(gòu)。上面說的這些都會(huì)讓我們增加糟糕的代碼,混亂的業(yè)務(wù)邏輯分布在我們系統(tǒng)的各個(gè)地方,部門人員變動(dòng),新的員工更不可能理解那些雜亂無章的東西,再接著推糟糕的代碼,想要理清楚一個(gè)業(yè)務(wù)邏輯,非常容易在混亂的代碼中迷路。

最直接的后果就是這些混亂的代碼會(huì)增加新功能的開發(fā)周期,領(lǐng)導(dǎo)層問為啥現(xiàn)在開發(fā)個(gè)功能這么慢?是不是人手不夠,再招幾個(gè)人吧。這雜亂的項(xiàng)目,不是新員工能理的清的,你會(huì)發(fā)現(xiàn),雖然員工變多了。但開發(fā)效率還是上不去。

圖片

圖片項(xiàng)目演進(jìn)

那我們重新來做一個(gè)新的系統(tǒng)完全替代這個(gè)老項(xiàng)目吧,可以用最新的框架,更好的實(shí)現(xiàn)方式去完成這個(gè)系統(tǒng),這種天真的想法會(huì)在團(tuán)隊(duì)成員的腦海里無數(shù)次出現(xiàn)。

舊的系統(tǒng)業(yè)務(wù)很復(fù)雜,新的系統(tǒng)在兼容舊系統(tǒng)邏輯的同時(shí),舊的系統(tǒng)也在更新需求,增加功能,在新系統(tǒng)完全可以抗衡舊系統(tǒng)之前,舊的系統(tǒng)會(huì)一直運(yùn)行。如果你的新系統(tǒng)開發(fā)的時(shí)間過長,等完成的時(shí)候,可能員工都已經(jīng)不知道換了幾批了,代碼又亂成了一鍋粥,周而復(fù)始。

軟件的退化變的越來越嚴(yán)重的過程中,我們也在思考和改變現(xiàn)有的系統(tǒng),如何才能讓系統(tǒng)的在擁有更長的生命周期的同時(shí),提高代碼的質(zhì)量,不讓其退化,并擁有更好的可維護(hù)性和擴(kuò)展性?那就是根據(jù)需求的變化去調(diào)整架構(gòu)、代碼,不斷的打破原來的設(shè)計(jì),保持清晰,而不是讓他爛在那里。

漸進(jìn)式架構(gòu)

大多數(shù)人能想到的最直接的方案是從架構(gòu)入手,引入多維度的架構(gòu),微服務(wù)化,領(lǐng)域驅(qū)動(dòng)模型(DDD)等等,從頂層設(shè)計(jì)出發(fā)引入新的架構(gòu)模型,或者說根據(jù)需求的變動(dòng)不斷的調(diào)整代碼的分層和模塊,加上理論知識(shí)的應(yīng)用,會(huì)讓業(yè)務(wù)代碼在結(jié)構(gòu)歸屬上更清晰。分層的嚴(yán)密能讓整體的業(yè)務(wù)邊界更明確,前提是我們要從多維度去審視系統(tǒng)的構(gòu)架,思考如何去現(xiàn)有的架構(gòu)做出合理的改動(dòng)。

從不同的角度去分析和改進(jìn)現(xiàn)有架構(gòu)

比如在項(xiàng)目初期業(yè)務(wù)比較簡單,最簡單的分層架構(gòu)就實(shí)現(xiàn)了項(xiàng)目需求,觀察我們的架構(gòu)可能是這樣子的,從上而下的松散分層架構(gòu):

圖片

松散分層架構(gòu)

后來又加入了緩存,又加入了消息隊(duì)列,業(yè)務(wù)的不斷擴(kuò)張又加入了不同的數(shù)據(jù)庫nosql。業(yè)務(wù)的升級(jí)有了v2.0、v3.0,新業(yè)務(wù)要兼容舊功能等等,如果還是原來的分層結(jié)構(gòu),很快就會(huì)出現(xiàn)邏輯代碼堆積的問題,業(yè)務(wù)層之間引用雜亂,一個(gè)代碼文件幾千行代碼,需求變動(dòng)時(shí)牽一發(fā)動(dòng)全身,及時(shí)調(diào)整架構(gòu)的必要性就體現(xiàn)出來了。

一定要復(fù)用好依賴倒置原則,層與層之間不應(yīng)該依賴實(shí)現(xiàn),要依賴于抽象。比如,我們的基礎(chǔ)設(shè)施層要為其他三層提供支持,基礎(chǔ)設(shè)施層可以實(shí)現(xiàn)其他層定義的接口來進(jìn)行抽象,從這個(gè)角度來開的話我們的基礎(chǔ)設(shè)施層應(yīng)該在最上面,也可以是左邊或者右邊。

圖片

圖片基礎(chǔ)架構(gòu)

應(yīng)用依賴倒置后,我們調(diào)用的是抽象接口,你會(huì)發(fā)現(xiàn)層的概念沒有了,層的概念被打破了,我們可以更激進(jìn)一點(diǎn)把基礎(chǔ)設(shè)施層剝離出去用各種適配器去接入各種組件,把層的關(guān)系拉平,把架構(gòu)調(diào)整為六邊形構(gòu)架。

圖片

六邊形架構(gòu)

不要固化自己的思維,根據(jù)業(yè)務(wù)和系統(tǒng)的發(fā)展去調(diào)整你的系統(tǒng)架構(gòu),能讓系統(tǒng)能更高的可擴(kuò)展和可維護(hù)性。對于非常老的項(xiàng)目調(diào)整架構(gòu)是痛苦的,一定要得到管理層充分的支持下再去做改造,這樣的工作只能是從上往下推進(jìn),痛苦的過程終會(huì)換來后期維護(hù)的喜悅。

代碼層面

在團(tuán)隊(duì)內(nèi)除了要有代碼規(guī)范,所有人都要遵守,這樣代碼的風(fēng)格才能更統(tǒng)一,和使用Lint工具去檢查代碼,各種語言lint工具,能在早期查檢出你代碼中不合理的地方。還有下面一些辦法。

功能模塊化

程序員最喜歡的就是編碼實(shí)現(xiàn)具體的功能,在這里才是我們真正秀內(nèi)功的地方,可以應(yīng)用各種模式把代碼和邏輯寫的很漂亮,但是放到整個(gè)項(xiàng)目結(jié)構(gòu)里,被調(diào)用和使用的過程又感覺那么的不協(xié)調(diào),根源是我們模塊劃分不正確,模塊之間的依賴耦合性太強(qiáng)。

這就是典型的寫的很優(yōu)雅,使用的很粗糙。依賴倒置原則,依然適用于模塊間的劃分,模塊與模塊之間的依賴是倒置的,用依賴注入的方式去解耦,模塊對外暴露出盡可能少的接口,之間的調(diào)用依賴于接口。抽象的好處能讓你把模塊的邊界定義的更明確。

對象之間是協(xié)作關(guān)系,不是糾纏

業(yè)務(wù)越復(fù)雜,需要操作的對象也就越多,對象的邊界不明確就會(huì)出現(xiàn)糾纏不清的情況。要不就是一個(gè)對象負(fù)責(zé)的東西過多,要不就是幾個(gè)對象同時(shí)做一件事,邏輯雜亂。

當(dāng)你發(fā)現(xiàn)對象之前不再是協(xié)作關(guān)系時(shí)就要停下來,從高處去看你組織的代碼,把大對象分解,職責(zé)界線理清楚也就是功能單一原則。很多同學(xué)不知道如何確定一個(gè)對象的職責(zé),不清楚一個(gè)屬性是不是屬于某個(gè)對象。最簡單的方法就是,判斷這個(gè)屬性的變動(dòng)會(huì)不影響某個(gè)對象,如果沒有就不屬于這個(gè)對象。還有就是,面對新的業(yè)務(wù)需求敢于打破原有的代碼設(shè)計(jì),不破不立。

不要過度開發(fā),刪除沒用的代碼

定期要檢查和刪除沒用的代碼。少寫或者不寫感覺未來可能會(huì)用到的方法,這些多出來的代碼會(huì)成為將來重構(gòu)的絆腳石,會(huì)浪費(fèi)精力在這些沒有用到的代碼上,查找有沒有地方在使用他。

SOLID 原則

不能不提的,就是Bob大叔(Robert C. Martin)的SOLID編碼原則,它是設(shè)計(jì)模式的基石,要不斷的去應(yīng)用和實(shí)踐。隨著編碼時(shí)間的增長,越來越感覺SOLID真的是一盞明燈,當(dāng)你在黑暗中找不到方向的時(shí)候,指引你回歸正確的道路。如果你對SOLID原則應(yīng)用的比較熟練,上面說的幾項(xiàng)完全都可以忽略。

(1) 單一職責(zé)原則(Single Responsibility Principle)

每個(gè)對象只有一個(gè)職責(zé),明確對象的邊界,文章上面說的對象之間是協(xié)作關(guān)系,“不是糾纏”里就說過,如何確定一個(gè)屬性是否屬于某個(gè)對象。

(2) 開閉原則(Open Closed Principle)

即可擴(kuò)展(extension),不可修改(modification)原則,抽取出代碼中不變的邏輯,封裝可變的代碼, 策略模式就很好的表達(dá)這個(gè)原則的模式。

(3) 里氏替換原則(Liskov Substitution Principle)

繼承必須確保超類所擁有的性質(zhì)在子類中仍然成立,里氏替換原則主要闡述了有關(guān)繼承的一些原則,也就是什么時(shí)候應(yīng)該使用繼承,什么時(shí)候不應(yīng)該使用繼承,以及其中蘊(yùn)含的原理。

里氏替換原是繼承復(fù)用的基礎(chǔ),它反映了基類與子類之間的關(guān)系,是對開閉原則的補(bǔ)充,是對實(shí)現(xiàn)抽象化的具體步驟的規(guī)范。關(guān)于里氏替換原則的例子,最有名的是“正方形不是長方形“。

(4) 接口隔離原則(Interface Segregation Principle)

盡量將臃腫龐大的接口拆分成更小的和更具體的接口,讓接口中只包含調(diào)用方感興趣的方法,這也是我們把復(fù)雜功能分模塊的應(yīng)用法則。

接口隔離原則和單一職責(zé)都是為了提高類的內(nèi)聚性、降低它們之間的耦合性,但兩者是不同的:單一職責(zé)原則注重的是職責(zé),而接口隔離原則注重的是對接口依賴的隔離。單一職責(zé)原則主要是約束類,它針對的是程序中的實(shí)現(xiàn)和細(xì)節(jié);接口隔離原則主要約束接口,主要針對抽象和程序整體框架的構(gòu)建。

(5) 依賴倒置原則(Dependence Inversion Principle)

抽象不應(yīng)該依賴于細(xì)節(jié),細(xì)節(jié)應(yīng)當(dāng)依賴于抽象。換言之,要針對抽象(接口)編程,而不是針對實(shí)現(xiàn)細(xì)節(jié)編程。上面在說改進(jìn)架構(gòu)的時(shí)候有說這個(gè)原則。

重構(gòu)代碼

新功能的開發(fā)的同時(shí)要重構(gòu)之前邏輯,堅(jiān)持開閉原則,能達(dá)到事半功倍的效果。工作閑暇時(shí)間去瀏覽現(xiàn)有的代碼邏輯,我們每天都在成長,對系統(tǒng)的認(rèn)知也在改變,思維方式也在不斷的變化,用現(xiàn)在的眼光去審視舊的代碼邏輯,大多數(shù)是能找可以優(yōu)化的地方,或者隱藏的bug,重構(gòu)它。不要以為這些只是一些擠牙膏式的調(diào)優(yōu),所有的事情都有一個(gè)從質(zhì)變到量變的過程。

代碼評審(code review)

代碼評審在團(tuán)隊(duì)里還是很有必要的,代碼評審不是口水戰(zhàn),也不是批斗大會(huì),如果只是走形式code review的意義也就不存在了。你寫的代碼是需要讓團(tuán)隊(duì)的成員能看明白的,將來也是會(huì)有新的員工來維護(hù)你寫的功能的,code review是一個(gè)能讓團(tuán)隊(duì)內(nèi)的其他成員快速了解新代碼意圖的辦法。

大多數(shù)團(tuán)隊(duì)里程序員的水平參差不齊的,對業(yè)務(wù)和系統(tǒng)的理解深度也是不一樣的,讓團(tuán)隊(duì)內(nèi)不同的人去code review能及時(shí)發(fā)現(xiàn)代碼中的不足之處,哪些地方邏輯上有問題,哪里的業(yè)務(wù)沒有考慮全面。

圖片

代碼評審

當(dāng)一次提交的代碼太多時(shí),一下子是看不完,也可能理解不了,就要先評審整體思路,再review實(shí)現(xiàn)主干邏輯,最后才是實(shí)現(xiàn)細(xì)節(jié)。需說明一下的是,code review 并不能完全發(fā)現(xiàn)代碼中隱藏的bug,不要把找bug的任務(wù)和它混在一起。

學(xué)習(xí)多少構(gòu)架或者框架知識(shí),都不能阻止我們寫爛代碼。但當(dāng)你沉下心來去打磨產(chǎn)品或者認(rèn)真去實(shí)現(xiàn)一個(gè)功能時(shí),你會(huì)在意你寫的代碼,會(huì)主動(dòng)去寫更清晰的邏輯,并改變和想辦法去并處理糟糕的代碼,希望這篇帖子有能幫助到你的地方。

責(zé)任編輯:趙寧寧 來源: 技術(shù)控
相關(guān)推薦

2015-04-27 09:41:35

前端質(zhì)量質(zhì)量保障

2023-01-31 07:47:14

Dooring低代碼輔助設(shè)計(jì)

2011-04-13 14:04:14

Java數(shù)組

2021-12-08 10:54:09

汽車智能芯片

2015-10-12 08:59:57

異步代碼測試

2012-11-08 11:19:38

2018-07-11 14:06:04

數(shù)據(jù)質(zhì)量數(shù)據(jù)治理數(shù)據(jù)清洗

2021-03-15 08:25:49

數(shù)據(jù)分析互聯(lián)網(wǎng)運(yùn)營大數(shù)據(jù)

2010-06-18 15:03:12

BGP路由協(xié)議

2013-04-18 09:29:02

編程語言編程

2019-05-14 14:10:34

工業(yè)物聯(lián)網(wǎng)物聯(lián)網(wǎng)IOT

2022-05-27 11:46:48

技術(shù)能力思考

2021-03-04 20:01:11

代碼思考業(yè)務(wù)

2012-03-07 09:02:29

代碼復(fù)用

2012-06-20 10:07:35

應(yīng)用商店Android

2012-04-02 15:52:11

2018-01-02 13:30:04

代碼質(zhì)量代碼預(yù)言

2021-06-25 14:41:42

網(wǎng)絡(luò)安全

2020-05-19 08:52:31

APP滲透測試終端安全

2009-02-24 10:51:30

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)