天天躁日日躁狠狠躁AV麻豆-天天躁人人躁人人躁狂躁-天天澡夜夜澡人人澡-天天影视香色欲综合网-国产成人女人在线视频观看-国产成人女人视频在线观看

防止代碼變質(zhì)的思考與方法

  1、軟件長(zhǎng)期運(yùn)營(yíng)存在什么問(wèn)題

  一個(gè)大規(guī)模的客戶(hù)端軟件的生命周期中,我們可以把它分為兩個(gè)比較粗的時(shí)期。一個(gè)是前期的搭建軟件的時(shí)期,即從無(wú)到有的時(shí)期;第二個(gè)是搭建完成之后,進(jìn)入的一個(gè)穩(wěn)定的運(yùn)營(yíng)時(shí)期。第二個(gè)時(shí)期才是最關(guān)鍵的,在這個(gè)時(shí)期我們會(huì)持續(xù)的迭加需求,持續(xù)的優(yōu)化功能,而且第二個(gè)時(shí)期也是代碼在慢慢變質(zhì)的時(shí)期。

  在這個(gè)時(shí)期,你可能會(huì)發(fā)現(xiàn):我們的軟件慢慢出現(xiàn)模塊耦合嚴(yán)重,牽一發(fā)而動(dòng)全身;每個(gè)版本都會(huì)涌現(xiàn)出老功能的BUG,你沒(méi)動(dòng)過(guò)的模塊也會(huì)出BUG;或者改了一個(gè)小問(wèn)題了,帶出來(lái)很多其他問(wèn)題;缺乏擴(kuò)展性,往老模塊加新功能非常痛苦;程序的崩潰率越來(lái)越高;新員工接手老模塊經(jīng)常不能理解原來(lái)的設(shè)計(jì)思想而改壞;移植一個(gè)DLL到另一個(gè)軟件時(shí),發(fā)現(xiàn)必須連帶也移植十幾個(gè)DLL。本文將分享對(duì)于這些問(wèn)題的思考與方法。

  2、軟件的積木模型

  一個(gè)運(yùn)營(yíng)型的客戶(hù)端軟件,做出來(lái)就是為了長(zhǎng)期運(yùn)營(yíng),需要不斷的迭加功能。而不是做出來(lái),兩三年就重寫(xiě)一次。那么這樣一個(gè)軟件就像堆積木一樣。一個(gè)軟件剛開(kāi)始寫(xiě)了兩千行代碼,感覺(jué)設(shè)計(jì)得非常好,模塊化擴(kuò)展性都非常好,性能也非常快,都能很好的面向運(yùn)營(yíng)。寫(xiě)了兩三年之后,就會(huì)出現(xiàn)像這種積木一樣的結(jié)構(gòu),很容易崩塌。所謂重構(gòu),形象的說(shuō),可以看做是某個(gè)積木不穩(wěn)定,要往里塞一塞。那么整個(gè)開(kāi)發(fā)過(guò)程,就是一個(gè)不斷迭代、不斷優(yōu)化、不斷重構(gòu)的過(guò)程。對(duì)于我們這個(gè)積木模形,有什么辦法不讓一些木條跑出來(lái),這也是我們需要想的思路。我們是不是可以先圍四面墻,然后在墻里面再去塔積木?

  3、導(dǎo)致代碼變質(zhì)的兩大因素

  團(tuán)隊(duì)中總是會(huì)存在這樣那樣的問(wèn)題,這些問(wèn)題最終總是影響到我們的代碼朝著不良的方向發(fā)展。對(duì)于這些因素,我可以將它們抽象為兩大類(lèi)。一類(lèi)是人的因素:比如架構(gòu)設(shè)計(jì)不合理,需求沒(méi)考慮清楚,項(xiàng)目進(jìn)度壓力,溝通問(wèn)題,缺少文檔、培訓(xùn),等等。另一類(lèi)是時(shí)間的因素:比如人員的變動(dòng),需求的長(zhǎng)期迭加和變更,等等。人的因素是由于人本身的素質(zhì)或疏忽導(dǎo)致,時(shí)間因素是由于時(shí)間的長(zhǎng)期推進(jìn)導(dǎo)致,即使人的素質(zhì)很高也必然會(huì)出現(xiàn)時(shí)間因素的問(wèn)題。

  4、代碼變亂的微觀原因

  在上述兩大類(lèi)因素的長(zhǎng)期作用下,最終會(huì)導(dǎo)致代碼越來(lái)越亂。如果從微觀的角度來(lái)剖析,這跟依賴(lài)有著很大的關(guān)系。代碼的變亂,根本原因就是由于太多不良依賴(lài)或者模塊失去單一性所致。我們來(lái)看一下依賴(lài)是如何產(chǎn)生的。

  • 依賴(lài)的方式

  如下圖所示,如果組件A依賴(lài)于B,B依賴(lài)于C,A也是隱含的依賴(lài)于C的。組件A不能單獨(dú)使用,必須同B和C一起使用。在現(xiàn)實(shí)的代碼中,可能存在著非常長(zhǎng)的依賴(lài)鏈。

  依賴(lài)的方式也可能是多種多樣的,單向依賴(lài)、雙向依賴(lài)、環(huán)狀依賴(lài)或者一個(gè)依賴(lài)于多個(gè)。下圖也是一些示例,現(xiàn)實(shí)的代碼中可能是由各種依賴(lài)方式組成的非常復(fù)雜的網(wǎng)狀結(jié)構(gòu)。

  • 依賴(lài)的變化

  在兩大類(lèi)因素的作用下,依賴(lài)會(huì)發(fā)生變化。最常見(jiàn)的變化應(yīng)該是依賴(lài)的箭頭越來(lái)越多,網(wǎng)狀結(jié)構(gòu)變得越來(lái)越復(fù)雜。如果沒(méi)有增加新的組件,下圖中左邊的圖往往會(huì)變成右邊的圖。起初設(shè)計(jì)好的很好的代碼,可能是左邊的樣子,模塊具有很好的獨(dú)立性和可移植性。隨著時(shí)間、需求、人的變化,很可能由開(kāi)發(fā)人員很隨意的一行代碼,就變成了右邊的圖,一條紅線就出來(lái)了。兩個(gè)模塊變成相互依賴(lài),上面那個(gè)模塊就不再有獨(dú)立性和可移值性。

  我們的代碼從設(shè)計(jì)之初到現(xiàn)在,中間經(jīng)過(guò)了幾年的時(shí)間,代碼變得越來(lái)越亂很大的原因是因?yàn)檫@種紅線的持續(xù)出現(xiàn)。本來(lái)有很多獨(dú)立性很好的模塊,變成了錯(cuò)綜復(fù)雜的網(wǎng)狀結(jié)構(gòu)。

  前面是沒(méi)有引入新組件的情況,如果引入了新組件,必然會(huì)引入新的引賴(lài),那么就要好好的去界定,引入的新組件是屬于哪個(gè)層面的。像下面第一個(gè)圖,新引入的組件依賴(lài)于原來(lái)兩個(gè)組件是在最上層,第二個(gè)圖新引入的組件是在中間層,第三個(gè)圖新引入的組件被另外兩個(gè)組件依賴(lài)在最底層。

  引入新組件,其實(shí)應(yīng)該做好充分的考慮,而不是讓開(kāi)發(fā)人員隨意的引入。需要充分思考引入的新組件應(yīng)該放在哪一層面才是最合理的,才有利于以后的擴(kuò)展和移植。

  可能讀者會(huì)遇到這種情況,一個(gè)功能編譯沒(méi)有問(wèn)題,測(cè)試也沒(méi)有問(wèn)題,發(fā)布后一兩年也沒(méi)有問(wèn)題。當(dāng)我們要把這個(gè)功能移植出來(lái)的時(shí)候,才發(fā)現(xiàn)問(wèn)題大了。你想移植一個(gè)組件到另一個(gè)軟件時(shí),必須連帶也移植十幾個(gè)組件。

  5、如何解決依賴(lài)

  • 組件網(wǎng)圖

  要解決依賴(lài),首先要發(fā)現(xiàn)哪些是不正確的依賴(lài)。下圖就是一個(gè)具有良好層次的依賴(lài)關(guān)系圖,我們稱(chēng)之為“組件網(wǎng)圖”。對(duì)于我們現(xiàn)實(shí)的軟件中,我們非常需要這樣一張圖將整個(gè)軟件所有組件的依賴(lài)關(guān)系繪制出來(lái),以便于我們發(fā)現(xiàn)其中的錯(cuò)誤依賴(lài)進(jìn)行解決。

  如果組件網(wǎng)圖中存在錯(cuò)誤的依賴(lài)關(guān)系,或者如果有需求要求圖中的組件h依賴(lài)于g,應(yīng)該怎么辦?可以通過(guò)下面的“分解適配”和“升級(jí)降級(jí)”的方法進(jìn)行解決。

  • 分解適配(單一職責(zé))

  分解適配是指將一個(gè)功能復(fù)雜的模塊分解為多個(gè)具有單一職責(zé)的模塊,那么模塊間的依賴(lài)關(guān)系也會(huì)變得單純。讀者可以結(jié)合下面的案例理解這個(gè)方法。

  • 升級(jí)降級(jí)

  我們經(jīng)常會(huì)做重構(gòu),對(duì)于上面那張組件網(wǎng)圖來(lái)說(shuō),重構(gòu)就是將不合理的依賴(lài)斷開(kāi),把更通用的邏輯抽出來(lái)放在底層,將不能用的邏輯放在上層。重構(gòu)其實(shí)就是不斷升級(jí)和降級(jí)的過(guò)程。

  比如說(shuō)我們前面的圖,如果H依賴(lài)于G了,那么可能考慮將G進(jìn)行分解適配,將G分為G1和G2,將G2和H合并為一個(gè)新組件。這樣就完成了一個(gè)分解適配和升級(jí)降級(jí)的過(guò)程。

  6、處理依賴(lài)的方法論

  • 通用的模塊不要依賴(lài)于不通用的模塊

  我們進(jìn)行層次劃分,通常是通用的模塊放到底層,不通用的模塊放在上層,不通用的模塊依賴(lài)通用的模塊是合情合理的。反過(guò)來(lái),如果通用的模塊依賴(lài)于不通用的模塊,那么這個(gè)通用的模塊也會(huì)變得不通用。

  • 之前的創(chuàng)建模塊盡量不要依賴(lài)于后創(chuàng)建的模塊

  根據(jù)時(shí)間軸以及產(chǎn)品的發(fā)展,較早開(kāi)發(fā)的需求一般都是通用的或者是基礎(chǔ)性質(zhì)的需求,而后開(kāi)發(fā)的需求是業(yè)務(wù)型的需求為主。根據(jù)這個(gè)性質(zhì),后開(kāi)發(fā)的需求應(yīng)該大部分依賴(lài)于之前的特性,比較少的情況是讓之前的需求依賴(lài)于一個(gè)后來(lái)的需求,當(dāng)然一些需求變更可能會(huì)引發(fā)這個(gè)現(xiàn)象。后創(chuàng)建的模塊雖然可以依賴(lài)之前創(chuàng)建的模塊,但是盡量不要去修改原來(lái)創(chuàng)建的模塊,如果出現(xiàn)這種情況,也要考慮一下這個(gè)修改是不是合理的。

  • 需要進(jìn)行微觀分層(組件網(wǎng)圖)

  日常開(kāi)發(fā)中,需要有一張組件網(wǎng)圖展現(xiàn)在開(kāi)發(fā)人員的面前,使得開(kāi)發(fā)人員在能意識(shí)到哪些依賴(lài)是不應(yīng)該出現(xiàn)的。當(dāng)然,在開(kāi)發(fā)一個(gè)功能之前,也應(yīng)該進(jìn)行微觀層次的設(shè)計(jì),之后再進(jìn)行代碼的編寫(xiě)。

  7、增加功能三步法

  我們拿到一份需求,需要增加一個(gè)功能,應(yīng)該怎么做?如果新功能與原先的模塊有依賴(lài)的時(shí)候,如果是經(jīng)驗(yàn)欠缺的同事,他們會(huì)怎么去做呢?會(huì)不會(huì)考慮說(shuō)架構(gòu)會(huì)不會(huì)合理?經(jīng)驗(yàn)欠缺的同事可能通常都不會(huì)這么考慮,他們只是集中于能不能把需求實(shí)現(xiàn),而不是考慮這樣用架構(gòu)上合不合理。團(tuán)隊(duì)就應(yīng)該有規(guī)范去約束經(jīng)驗(yàn)欠缺的同事不去犯錯(cuò)誤。這里有一個(gè)增加功能的三步法供讀者參考,這些方法可能不完善,讀者可能有更好的方法,應(yīng)該尋找適合自己團(tuán)隊(duì)的解決辦法。

  • 不修改依賴(lài),不修改或增加接口

  假設(shè)原來(lái)就有兩個(gè)模塊,一個(gè)在上層一個(gè)在底層,如果需要新寫(xiě)一個(gè)功能,第一步需要先考慮的是,我能不能在上層寫(xiě)代碼,不修改兩個(gè)模塊的依賴(lài),不修改也不增加接口,我的需求能不能滿(mǎn)足。假如說(shuō)已經(jīng)有現(xiàn)成的接口和現(xiàn)成的依賴(lài),首先就要考慮能不能利用現(xiàn)成的接口來(lái)完成需求。在沒(méi)有規(guī)范約束的情況下,可能很多時(shí)候這個(gè)模塊改一下,那個(gè)模塊也改一下,就把需求做完了。

  • 不修改依賴(lài),但增加接口

  如果第一步不滿(mǎn)足需求的情況下,我們才考慮第二步,不要修改依賴(lài),但是修改接口,這個(gè)接口可能就是一個(gè)比較通用的,而不是針對(duì)特定需求的,新增接口需要考慮擴(kuò)展性和通用性。很多場(chǎng)景其實(shí)到這一步都可能滿(mǎn)足的。

  • 修改內(nèi)部依賴(lài)

  如果第二步還不能滿(mǎn)足需求,必然會(huì)導(dǎo)致模塊的耦合,底層如果依賴(lài)于上層,就要重新考慮將組件依賴(lài)圖進(jìn)行一些調(diào)整,就必須做一些重構(gòu),進(jìn)行升級(jí)降級(jí),完全耦合的兩個(gè)模塊甚至可以合二為一。

  8、組件網(wǎng)圖的自動(dòng)化監(jiān)控

  隨時(shí)時(shí)間的推移,代碼中的依賴(lài)越來(lái)越多,如何將代碼依賴(lài)的變化有效的監(jiān)控起來(lái)。建議團(tuán)隊(duì)開(kāi)發(fā)一個(gè)監(jiān)控組件網(wǎng)圖變化的工具,一旦有開(kāi)發(fā)人員把依賴(lài)搞亂,工具就會(huì)發(fā)出郵件進(jìn)行報(bào)警。一個(gè)依賴(lài)層次正常的組件網(wǎng)圖,是不會(huì)出現(xiàn)環(huán)狀依賴(lài)的。我們可以將環(huán)狀依賴(lài)作為代碼變亂的一個(gè)客觀依據(jù)。所以組件網(wǎng)圖工具可以做成只要發(fā)現(xiàn)環(huán)狀依賴(lài),就發(fā)出郵件報(bào)告給開(kāi)發(fā)人員進(jìn)行重構(gòu)。組件網(wǎng)圖工具應(yīng)該每天夜里定期運(yùn)行,找到當(dāng)天新修改的代碼中是否引出新的依賴(lài)和環(huán)狀依賴(lài),及時(shí)修改。

  9、讓架構(gòu)去保證開(kāi)發(fā)人員不犯錯(cuò)

  防止代碼變亂,我們可以進(jìn)行各種培訓(xùn)提高開(kāi)發(fā)人員的素質(zhì),開(kāi)發(fā)前的設(shè)計(jì)評(píng)審,開(kāi)發(fā)后的代碼檢視,或者是監(jiān)控工具每天的檢查。更重要的應(yīng)該是從架構(gòu)上去保證開(kāi)發(fā)人員不會(huì)犯錯(cuò)誤,就像前面提到的積木模型,先將四面墻圍起來(lái)再進(jìn)行積木的搭建。

  我們?cè)趺丛诩軜?gòu)上讓開(kāi)發(fā)人員方便的進(jìn)行解耦?比如我們有一個(gè)通用的界面,界面上會(huì)插入各種業(yè)務(wù)圖標(biāo),我們不能讓一個(gè)通用的界面去依賴(lài)于各個(gè)具體的業(yè)務(wù),所以應(yīng)該設(shè)計(jì)一套插入體系:在界面上留了一些位置,讓業(yè)務(wù)插進(jìn)來(lái)。這就從架構(gòu)上訪止這種耦合,后續(xù)開(kāi)發(fā)人員需要繼續(xù)加圖標(biāo),他不會(huì)在通用界面上去調(diào)用業(yè)務(wù)的接口獲取圖標(biāo),因?yàn)楝F(xiàn)有機(jī)制很難這樣做。所以只要架構(gòu)上設(shè)計(jì)考慮充份,是可以讓后來(lái)的開(kāi)發(fā)人員不要犯錯(cuò)誤的。

it知識(shí)庫(kù)防止代碼變質(zhì)的思考與方法,轉(zhuǎn)載需保留來(lái)源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 国产成人精品在视频 | 国产精品成人在线播放 | 中俄两军在日本海等上空战略巡航 | 柏木舞子在线 | 国产国产成人人免费影院 | 久久秋霞理论电影 | 5g天天奭视频 | 人妻兽虐曲 | 考好老师让你做一次H | 亚洲永久精品ww47 | 福利片福利一区二区三区 | 在线免费视频a | 沟沟人体一区二区 | 中文字幕亚洲乱码熟女在线萌芽 | 国产精品99久久久久久AV蜜臀 | 免费国产在线观看 | 国语对白刺激真实精品 | 久久久久嫩草影院精品 | 99久久久久精品国产免费麻豆 | 影音先锋av男人资源 | 亚洲精品久久久午夜福利电影网 | 365电影成人亚洲网在线观看 | 疯狂做受XXXX高潮欧美日本 | 久久人妻AV一区二区软件 | 伊人久久精品AV一区二区 | 久久亚洲成a人片 | 伊人国产视频 | 国产AV在线传媒麻豆 | 中文在线观看免费网站 | 日韩中文亚洲欧美视频二 | 色尼玛亚洲 | 亚洲黄网站wwwwww | 日韩av片无码一区二区不卡电影 | 日韩免费一区二区三区在线 | 依人在线观看 | zooskoo1videos人与狗 | 在线 自拍 综合 亚洲 欧美 | 色色色五的天 | 欧美性猛交xxxxxxxx软件 | 国产成人99久久亚洲综合精品 | 色悠久久综合 |