<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          內(nèi)卷時(shí)代,更應(yīng)提升代碼質(zhì)量!

          共 4637字,需瀏覽 10分鐘

           ·

          2020-12-28 07:50

          △點(diǎn)擊上方Python貓”關(guān)注 ,回復(fù)“1”領(lǐng)取電子書

          作者:Zachary
          來源:跨界架構(gòu)師
          提到代碼質(zhì)量,不知道你的腦海中浮現(xiàn)出的第一個(gè)詞是什么?規(guī)范?可讀性?優(yōu)雅?

          在我的心中,好的代碼質(zhì)量 = 舒服。看著舒服,接手這樣的項(xiàng)目感覺舒服,在其中找問題和改代碼舒服。


          軟件開發(fā)這個(gè)行業(yè)是一個(gè)年輕的行業(yè),如果在十幾年前談代碼質(zhì)量,可能還算是個(gè)比較高級的問題。但是在大家都認(rèn)為越來越內(nèi)卷的當(dāng)下,注重和提升代碼質(zhì)量我認(rèn)為是每個(gè)程序員的必修課。說的嚴(yán)重一些,它影響了你在團(tuán)隊(duì)中的價(jià)值,說的表面一些,它是你在團(tuán)隊(duì)中的“面子”。

          假象一下,你接手了兩個(gè)項(xiàng)目,一個(gè)項(xiàng)目代碼干干凈凈、非常整潔,另一個(gè)隨處可見的相似代碼以及雜亂無章的分類擺放。你對這兩個(gè)項(xiàng)目的前負(fù)責(zé)人是什么想法?未來你更愿意和誰合作?我想答案是顯而易見的。


          在我看來要寫出舒服的代碼并不需要對那些代碼規(guī)范背的滾瓜爛熟,其實(shí)只要掌握一個(gè)六字核心原則:高內(nèi)聚低耦合。如此寫出的代碼至少能在60分以上。

          可以回想一下,當(dāng)你在做一個(gè)簡單項(xiàng)目的時(shí)候,使用那些成熟的框架和工具可以輕松地完成大部分工作。甚至?xí)杏X有點(diǎn)無聊,因?yàn)楦杏X都是在CRUD。這就是應(yīng)用了經(jīng)過精心設(shè)計(jì)的高內(nèi)聚低耦合的框架和工具所具有的效果,讓事情變簡單。

          講句題外話,「高內(nèi)聚低耦合」在軟件開發(fā)領(lǐng)域真是一個(gè)黃金原則,在哪都適用,大到一個(gè)分布式系統(tǒng)的設(shè)計(jì),小到一個(gè)class的設(shè)計(jì)。如果我的腦子只能記住一條原則的話,毫不猶豫會(huì)選擇它。


          那么如何讓自己也能寫出高內(nèi)聚低耦合的代碼呢?我們要對「高內(nèi)聚低耦合」有更深入地理解,而不是僅僅停留在這6個(gè)字上。

          葡萄牙馬德拉大學(xué)精確科學(xué)與工程中心的教授,被認(rèn)為是計(jì)算機(jī)領(lǐng)域先驅(qū)者之一的賴瑞·康斯坦丁帶隊(duì)對內(nèi)聚性和耦合性做了深入的研究和分析,對內(nèi)聚性和耦合性的強(qiáng)弱關(guān)系進(jìn)行了梳理,得到了以下結(jié)論。(摘自于維基百科)

          內(nèi)聚性的分類如下,強(qiáng)度由低到高排列:

          偶然內(nèi)聚性:是指模塊中的機(jī)能只是剛好放在一起,模塊中各機(jī)能之間唯一的關(guān)系是其位在同一個(gè)模塊中(例如:“工具”模塊)。

          邏輯內(nèi)聚性:是只要機(jī)能只要在邏輯上分為同一類,不論各機(jī)能的本質(zhì)是否有很大差異,就將這些機(jī)能放在同一模塊中(例如將所有的鼠標(biāo)和鍵盤都放在輸入處理副程序中)。模塊內(nèi)執(zhí)行幾個(gè)邏輯上相似的功能,通過參數(shù)確定該模塊完成哪一個(gè)功能。

          時(shí)間性內(nèi)聚性:是指將相近時(shí)間點(diǎn)運(yùn)行的程序,放在同一個(gè)模塊中(例如在捕捉到一個(gè)異常后調(diào)用一函數(shù),在函數(shù)中關(guān)閉已開啟的文件、產(chǎn)生錯(cuò)誤日志、并告知用戶)。

          程序內(nèi)聚性:是指依一組會(huì)依照固定順序運(yùn)行的程序放在同一個(gè)模塊中(例如一個(gè)函數(shù)檢查文件的權(quán)限,之后開啟文件)。

          聯(lián)系內(nèi)聚性/信息內(nèi)聚/通信內(nèi)聚:是指模塊中的機(jī)能因?yàn)樘幚硐嗤馁Y料或者指各處理使用相同的輸入數(shù)據(jù)或者產(chǎn)生相同的輸出數(shù)據(jù),因此放在同一個(gè)模塊中(例如一個(gè)模塊中的許多機(jī)能都訪問同一個(gè)記錄)。

          依序內(nèi)聚性/順序內(nèi)聚:是指模塊中的各機(jī)能彼此的輸入及輸出資料相關(guān),一模塊的輸出資料是另一個(gè)模塊的輸入,類似工廠的生產(chǎn)線(例如一個(gè)模塊先讀取文件中的資料,之后再處理資料)。

          功能內(nèi)聚性:是指模塊中的各機(jī)能是因?yàn)樗鼈兌紝δK中單一明確定義的任務(wù)有貢獻(xiàn)(例如XML字符串的詞法分析)。


          耦合性的分類如下,強(qiáng)度由高到低排列:

          內(nèi)容耦合:也稱為病態(tài)耦合當(dāng)一個(gè)模塊直接使用另一個(gè)模塊的內(nèi)部數(shù)據(jù),或通過非正常入口而轉(zhuǎn)入另一個(gè)模塊內(nèi)部。

          共享耦合/公共耦合:也稱為全局耦合指通過一個(gè)公共數(shù)據(jù)環(huán)境相互作用的那些模塊間的耦合。公共耦合的復(fù)雜程度隨耦合模塊的個(gè)數(shù)增加而增加。

          外部耦合:發(fā)生在二個(gè)模塊共享一個(gè)外加的資料格式、通信協(xié)議或是設(shè)備界面,基本上和模塊和外部工具及設(shè)備的溝通有關(guān)。

          控制耦合:指一個(gè)模塊調(diào)用另一個(gè)模塊時(shí),傳遞的是控制變量(如開關(guān)、標(biāo)志等),被調(diào)模塊通過該控制變量的值有選擇地執(zhí)行塊內(nèi)某一功能;

          特征耦合/標(biāo)記耦合:也稱為數(shù)據(jù)結(jié)構(gòu)耦合,是指幾個(gè)模塊共享一個(gè)復(fù)雜的數(shù)據(jù)結(jié)構(gòu),如高級語言中的數(shù)組名、記錄名、文件名等這些名字即標(biāo)記,其實(shí)傳遞的是這個(gè)數(shù)據(jù)結(jié)構(gòu)的地址;

          資料耦合/數(shù)據(jù)耦合:是指模塊借由傳入值共享資料,每一個(gè)資料都是最基本的資料,而且只分享這些資料(例如傳遞一個(gè)整數(shù)給計(jì)算平方根的函數(shù))。

          消息耦合:可以借由以下二個(gè)方式達(dá)成:狀態(tài)的去中心化(例如在對象中),組件間利用傳入值或消息傳遞 (計(jì)算機(jī)科學(xué))來通信。

          無耦合:模塊完全不和其他模塊交換信息。


          如果你代碼寫的還不夠多,上面有些差異還無法很好的感知。但是你不需要把這些概念一字一句背下來,只要平時(shí)在寫代碼的時(shí)候多思考一下:“當(dāng)前的代碼設(shè)計(jì)是屬于哪種類型?”。如果不能確定的話回頭來看這篇文章:D。慢慢地,通過寫更多的代碼,你會(huì)對耦合和內(nèi)聚的強(qiáng)弱,有更敏感的感知力。

          根據(jù)上面的這些概念,寫出高質(zhì)量代碼的思路就很清晰了。method的歸類、class的歸類能根據(jù)功能內(nèi)聚性歸類的絕不用順序內(nèi)聚,能根據(jù)順序內(nèi)聚性歸類的絕不用更弱的。耦合也是同樣的,能不耦合的就不耦合,能用消息耦合的絕不用數(shù)據(jù)耦合。

          但是想要保證代碼按照這個(gè)設(shè)想去發(fā)展,還是需要通過做一些具體的事情作為抓手。這些事不需要全部做,但每一項(xiàng)都有助于提高代碼質(zhì)量。


          /01? 執(zhí)行代碼規(guī)范+Code Review/

          在Z哥看來,執(zhí)行代碼規(guī)范,最重要的價(jià)值并不是非得讓100%的代碼符合這個(gè)規(guī)范,而是讓所有人一起養(yǎng)成一種意識,意識到我的代碼會(huì)被別人看到,被評價(jià)。這樣才能在寫代碼的時(shí)候,不僅僅是為了實(shí)現(xiàn)功能。

          所以具體代碼規(guī)范是什么樣,并沒那么重要,可以是自己定義的,也可以是參考大廠的。當(dāng)然我更推薦前者,大廠的規(guī)范雖好,但是你要全部照搬,這個(gè)執(zhí)行成本可不小。

          如果你想提高代碼質(zhì)量,但又不想做很多事。那么執(zhí)行代碼規(guī)范+Code Review可以是你的唯一選擇。如果你是一位個(gè)人開發(fā)者,那么可以讓身邊你認(rèn)為代碼寫的最好的人幫你做CodeReview,以他的規(guī)范作為代碼規(guī)范即可。


          很多人覺得代碼規(guī)范是一種約束,會(huì)降低開發(fā)效率。其實(shí)不會(huì),最多在初期因?yàn)樽约翰⒉涣?xí)慣一些規(guī)范,所以花了很多時(shí)間在修正代碼。一旦走上正軌后,代碼規(guī)范反而會(huì)提高開發(fā)效率,因?yàn)楣?jié)省了很多閱讀代碼的時(shí)間以及同事之間溝通的時(shí)間。

          就算它真的降低了開發(fā)效率,但你要提升效率也不應(yīng)該降低代碼質(zhì)量,而是通過其它方式去提效。


          /02? 寫單元測試/

          寫單元測試之所以能提高代碼質(zhì)量,是因?yàn)槿绻皇歉邇?nèi)聚低耦合的代碼,你會(huì)發(fā)現(xiàn)單元測試非常難寫。

          比如,你只想測一下方法A,但是發(fā)現(xiàn)里面的依賴錯(cuò)綜復(fù)雜,好吧,都stub掉。最后發(fā)現(xiàn)測一個(gè)方法寫了幾十個(gè)stub,這種操作我親眼看到過……。這就是前面提到的「內(nèi)容耦合」過多了。

          所以,能輕松地寫出單元測試,并且將其養(yǎng)成一種習(xí)慣,你的代碼質(zhì)量必然不會(huì)差。


          /03? 設(shè)計(jì)先行/

          雖然設(shè)計(jì)不出完美的代碼,但是優(yōu)先考慮設(shè)計(jì)可以讓你多思考“我應(yīng)該怎么寫這段代碼”,而不是直接抄起家伙就寫,寫到哪算到哪。

          畢竟大多數(shù)功能都不可能一步到位,需要多次迭代。這種情況下最初的設(shè)計(jì)就顯得尤為重要,畢竟大部分人遇到不舒服的代碼不會(huì)推翻重寫,最多就是修修補(bǔ)補(bǔ),甚至是直接在這之上疊加新的代碼。


          /04? 項(xiàng)目與團(tuán)隊(duì)”微服務(wù)化”/

          保證一個(gè)幾萬行代碼的項(xiàng)目質(zhì)量和幾百萬行代碼的項(xiàng)目必然難度不同。所以,如果合適的話可以將項(xiàng)目拆小,并且由專門的團(tuán)隊(duì)負(fù)責(zé)。這樣可以提高團(tuán)隊(duì)把控代碼質(zhì)量意愿,并降低其難度。


          /05? 利用相關(guān)的工具/

          主流的編程語言或多或少都有一些靜態(tài)代碼分析工具、單元測試覆蓋率統(tǒng)計(jì)工具,這些要充分利用起來。它們可以快速的幫助避免一些低級的代碼壞味道,節(jié)約大量時(shí)間。


          /06? 幾個(gè)代碼層面的小建議/??

          01? 勿過度使用鏈?zhǔn)骄幊?/span>

          很多人會(huì)追求極致少的代碼行數(shù),恰好鏈?zhǔn)骄幊棠芡镀渌谩5拇_在很多時(shí)候鏈?zhǔn)骄幊炭梢蕴岣叽a的可讀性,但是它帶來的弊端也是顯而易見的,

          1. 調(diào)試的時(shí)候觀察變量變得很不方便。

          2. 容易在當(dāng)前方法里處理不應(yīng)該在這里處理的業(yè)務(wù)邏輯。畢竟很多class的方法和屬性是public的,相比單獨(dú)做一層封裝再調(diào)用,“點(diǎn)”出來直接用多香啊~所以在使用鏈?zhǔn)骄幊痰臅r(shí)候也得遵守「得墨忒耳定律」。


          得墨忒耳定律:
          每個(gè)單元對于其他的單元只能擁有有限的知識:只是與當(dāng)前單元緊密聯(lián)系的單元;
          每個(gè)單元只能和它的朋友交談:不能和陌生單元交談;
          只和自己直接的朋友交談。
          維基百科


          02? 避免隨處可見的try-catch

          Try-catch雖好,切勿貪杯。很多人喜歡寫try-catch然后通過一個(gè)單獨(dú)封裝的通用返回模型告知調(diào)用方出現(xiàn)了什么異常。

          這種方法的目的最初是為了避免上層調(diào)用者沒有做異常捕獲導(dǎo)致程序崩潰,但是弊端也是顯而易見的,如果調(diào)用方?jīng)]有正確的判斷返回模型里的異常相關(guān)屬性,會(huì)導(dǎo)致程序在錯(cuò)誤的狀態(tài)下繼續(xù)執(zhí)行,這個(gè)后果就不可預(yù)知了。

          所以我認(rèn)為通過try-catch封裝異常應(yīng)該出現(xiàn)在更上層的代碼里,越底層的代碼越不應(yīng)該封裝異常。


          03? 認(rèn)真編寫訪問修飾符

          很多編程語言都有多個(gè)訪問修飾符,我們在編寫的代碼的時(shí)候應(yīng)該盡可能的選擇最嚴(yán)格的修飾符,而不是什么都是public。

          因?yàn)閜ublic會(huì)導(dǎo)致很多變量在不知道什么情況下就被外部修改了,導(dǎo)致bug層出不窮、排查困難,項(xiàng)目質(zhì)量堪憂。

          訪問修飾符的過于寬松也是前面提到的鏈?zhǔn)骄幊瘫贿^度使用的推手之一。

          訪問修飾符的目的是為了防止程序員在無意間誤用不應(yīng)該使用的方法和屬性,畢竟代碼往往不只有一個(gè)人寫。


          04? 慎用繼承

          繼承的確挺香的,可以少寫很多代碼。但是使用不當(dāng)會(huì)破壞封裝的效果,造成訪問修飾符的失效。

          繼承的正確使用姿勢應(yīng)該傳達(dá)的是“子父”的關(guān)系,而不是“相似”的關(guān)系。比如“汽車”可以繼承于“交通工具”,但是不應(yīng)該繼承于“自行車”,雖然它們都有輪子。

          像汽車和自行車的這種情況要復(fù)用的話,可以抽象提煉出相同的部分,然后通過「組合」的方式進(jìn)行。


          最后,如果你對代碼質(zhì)量有更高的追求,想修煉和強(qiáng)化“內(nèi)功”,那必須不能錯(cuò)過這本經(jīng)典書籍。(之前的黃皮版本更新成這本灰皮了)


          好了,總結(jié)一下。

          這篇呢,Z哥和你分享了我對代碼質(zhì)量這件事的看法。在行業(yè)越來越內(nèi)卷的趨勢下,注重“質(zhì)”總是沒錯(cuò)的。

          Z哥認(rèn)為想要提高代碼質(zhì)量最核心的原則就是:高內(nèi)聚低耦合。文中給你羅列了賴瑞·康斯坦丁教授提煉了不同的內(nèi)聚性和耦合性原則來表達(dá)關(guān)系的強(qiáng)弱。

          基于對內(nèi)聚性和耦合性原則的理解,再通過以下抓手進(jìn)行代碼質(zhì)量的提升工作:

          1. 執(zhí)行代碼規(guī)范+Code Review

          2. 寫單元測試

          3. 設(shè)計(jì)先行

          4. 項(xiàng)目與團(tuán)隊(duì)”微服務(wù)化”

          5. 利用相關(guān)的工具


          最后還分享了幾個(gè)代碼層面的建議:

          1. 勿過度使用鏈?zhǔn)骄幊?/span>

          2. 避免隨處可見的try-catch

          3. 認(rèn)真編寫訪問修飾符

          4. 慎用繼承


          希望對你有所啟發(fā)。
          Python貓技術(shù)交流群開放啦!群里既有國內(nèi)一二線大廠在職員工,也有國內(nèi)外高校在讀學(xué)生,既有十多年碼齡的編程老鳥,也有中小學(xué)剛剛?cè)腴T的新人,學(xué)習(xí)氛圍良好!想入群的同學(xué),請?jiān)诠杻?nèi)回復(fù)『交流群』,獲取貓哥的微信(謝絕廣告黨,非誠勿擾!)~

          近期熱門文章推薦:

          揭開Python對象的神秘面紗!
          動(dòng)態(tài)規(guī)劃:特朗普怎樣才能贏?
          趣漫畫:Java 對 Python 的滲透能成功嗎?
          當(dāng)我發(fā)現(xiàn)國際友人翻譯了我的文章之后……

          感謝創(chuàng)作者的好文
          瀏覽 17
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  就爱添逼视频免费网站 | 日韩乱轮视频 | 黄色视频免费看网站 | 国产伦精品一区二区三区视频女 | 美女操逼黄片 |