二維碼
企資網(wǎng)

掃一掃關(guān)注

當(dāng)前位置: 首頁 » 企資快訊 » 問答式 » 正文

提升代碼質(zhì)量的方法_領(lǐng)域模型、設(shè)計原則、設(shè)計模

放大字體  縮小字體 發(fā)布日期:2021-09-02 06:53:21    作者:宮志強    瀏覽次數(shù):10
導(dǎo)讀

一 影響代碼差的根因1 差代碼的體現(xiàn)我們可以列舉出非常多質(zhì)量差的代碼的表現(xiàn)現(xiàn)象,如名字不知所意、超大類、超大方法、重復(fù)代碼、代碼難懂、代碼修改困難……其中最為影響代碼質(zhì)量的兩個表現(xiàn)是命名名不副實、邏輯可

一 影響代碼差的根因

1 差代碼的體現(xiàn)

我們可以列舉出非常多質(zhì)量差的代碼的表現(xiàn)現(xiàn)象,如名字不知所意、超大類、超大方法、重復(fù)代碼、代碼難懂、代碼修改困難……其中最為影響代碼質(zhì)量的兩個表現(xiàn)是命名名不副實、邏輯可擴展性差,當(dāng)一個新人閱讀代碼時,有時發(fā)現(xiàn)方法命名與實際邏輯對不上,這就讓人感到非常疑惑,這種現(xiàn)象在平時工作并不少見;另一個就是邏輯擴展性差,一個新業(yè)務(wù)需求提出來后,發(fā)現(xiàn)要在多處改動,需要回歸的業(yè)務(wù)邏輯比較多,造成研發(fā)效率不高。

2 問題歸納

對第1節(jié)中提到的現(xiàn)象進行問題歸納整理,大致整理出6類問題,分別展開加以說明。

  • 命名問題:命名問題是一件非常頭疼的事,想要取一個名副其實又好理解的名字并不那么容易。涉及到變量的命名、方法的命名、類命名,常見的命名問題有兩種:一種是不知所云;另一種是名不副實。命名不知所云是一個人初一看,不知道它是什么意思,根本原因就是沒有想到一個合適的詞匯去抽象問題;命名名不副實是命名和實際邏輯想表達的意思不一樣,這樣的命名會誤導(dǎo)人。
  • 代碼結(jié)構(gòu)問題:當(dāng)一個人初看工程代碼時,當(dāng)還沒有深入看代碼邏輯時,從模塊劃分、類劃分、方法劃分整體上可以感受得出代碼質(zhì)量,如果一個類有幾千行代碼,一個方法有幾百行,這樣的邏輯相信沒有多少人愿意去看,復(fù)雜度比較高。好的代碼層次結(jié)構(gòu)非常清晰,就像看一本優(yōu)美的書一樣有一種賞心悅目的感覺。
  • 編程范式問題:有三種編程范式:表模式、事務(wù)腳本模式和領(lǐng)域設(shè)計模式,大家用得最多的是事務(wù)腳本模式,這種模式最符合人做事的方法,step by step,這種模式最大的問題就是承擔(dān)了不該自己承擔(dān)的職責(zé),看起來比較符合邏輯,實際上問題比較多,平時大家喜歡稱之為"面條型代碼"。
  • 可讀性問題:代碼除了實現(xiàn)業(yè)務(wù)功能外,還要具備良好的可讀性,有的代碼沒有任何注釋;有的代碼格式不統(tǒng)一;有的是為了炫耀技術(shù),大段大段的Lambda表達式(并不是說Lambda表達式不好,關(guān)鍵要控制層次深度),這樣的代碼看起來簡潔,可讀性并不太好。
  • 擴展性問題:可擴展性問題是一個老生常談的問題,要實現(xiàn)良好的可擴展性并不那么容易,一般是沒有抽象問題,如店鋪在店招頭展示Tab,面條型的代碼就是直接定義一個List,然后往里面加Tab對象,如果需要再加一個Tab怎么辦?典型的就是不滿足開閉原則。
  • 無設(shè)計問題:整個代碼看起來比較平淡,別人看了之后也從中學(xué)習(xí)不到內(nèi)容。一般這種問題是沒有深入分析問題,僅僅解決了問題,而沒有考慮如何更好地解決問題,比如重復(fù)處理流程的工作是否可以抽象成一個通用的模板類、不同處理類是否可以通過工廠類去獲取具體的策略、異步處理是否可以使用事件模式去處理、對于新增加的能力能否通過自動注冊去發(fā)現(xiàn)……

    3 根因分析

    接下來分析下為什么會產(chǎn)生代碼差的原因,這個問題有外部原因,也有內(nèi)部原因。外部原因主要有:項目排期急,沒有多少時間去設(shè)計;資源短缺,人手不夠,只能怎么快怎么來;緊急問題修復(fù),臨時方案快速處理……。內(nèi)部原因主要有:自身技能低,怎么技能沒有掌握到,如Lamda表達式、常用的工具類、框架高級用法等;無極致追求的精神,僅僅完成需求就行,穩(wěn)定性、可擴展性、性能、數(shù)據(jù)一致性等沒有考慮……

    筆者認為最為關(guān)鍵的是內(nèi)部自身的問題,根因就兩個:自我要求不高;無反饋通道。如果對自已要求不高,僅僅滿足完成需求開發(fā)就止步了,很難寫出高質(zhì)量的代碼,另外如果沒有外部反饋,也難以提高自己的技能。筆者之前的主管非常嚴厲,對大家寫的代碼review比較仔細,一個變量名、一段邏輯的寫法,反復(fù)讓修改,這其實是提升技能最快的方法。

    二 提升代碼質(zhì)量的方法

    提升代碼質(zhì)量的方法,筆者喜歡用三個方法:領(lǐng)域建模、設(shè)計原則、設(shè)計模式,主要談下如何使用。

  • 分析階段:當(dāng)拿到一個需求時,先不要著急想著怎么把這個功能實現(xiàn),這種很容易陷入事務(wù)腳本的模式。分析什么呢?需要分析需求的目的是什么、完成該功能需要哪些實體承擔(dān),這一步核心是找實體。舉個上面進店Tab展示的例子,它有兩個關(guān)鍵的實體:導(dǎo)航欄、Tab,其中導(dǎo)航欄里面包含了若干個Tab。
  • 設(shè)計階段:分析完了有哪些實體后,再分析職責(zé)如何分配到具體的實體上,這就要運用一些設(shè)計原則去指導(dǎo),GRASP中提到一些職責(zé)分配的原則,感興趣的同學(xué)可以去詳細看看。回到上面的例子上,Tab的職責(zé)主要有兩個:一個是Tab能否展示,這是它自己的職責(zé),如上新Tab展示的邏輯是店鋪30天內(nèi)有上架新商品;另一個職責(zé)就是Tab規(guī)格信息的構(gòu)建,也是它自己要負責(zé)的。導(dǎo)航欄的職責(zé)有兩個:一個是接受Tab注冊;另一個是展示。職責(zé)分配不適理,也就不滿足高內(nèi)聚、低耦合的特征。
  • 打磨階段:這個階段選擇合適的模式去實現(xiàn),大家一看到模式都會理解它是做什么的,比如看到模板類,就會知道處理通用的業(yè)務(wù)流程,具體變化的部分放在子類中處理。上面的這個例子,用到了2個設(shè)計模式:一個是訂閱者模式,Tab自動注冊的過程;另一個是模板模式,先判斷Tab能否展示,然后再構(gòu)建Tab規(guī)格信息,流程雖然簡單,也可以抽象出來通用的流程出來,子類只用簡單地重寫2個方法。

    三 領(lǐng)域模型的作用

    領(lǐng)域建模的入門門檻比較高,包含了一些難理解的概念。本篇文章中并不會講述如何進行建模(可以私下交流),筆者發(fā)現(xiàn)讓大家接受領(lǐng)域建模遠比知道如何建模更重要,當(dāng)你知道了領(lǐng)域建模的作用后,自己會想各種辦法去學(xué)習(xí)。下面通過筆者經(jīng)歷的一些實際案例進行闡述,讓大家聽起來并不感覺到那么空洞。

    1 簡化認識

    筆者工作一年后加入到了一家金融公司,當(dāng)時對金融一無所知,開始接觸到標的、債權(quán)、債權(quán)轉(zhuǎn)讓、融資擔(dān)保、非融資擔(dān)保等名詞后,一時感到無所適從,每天要學(xué)習(xí)非常多的新內(nèi)容。

    兩個月后,我的主管給我們做了一次分享,就拿了一張ppt來講,它里面包含了領(lǐng)域的實體,以及實體之間的關(guān)聯(lián)關(guān)系,一下子我就知道了整個業(yè)務(wù)是怎么玩轉(zhuǎn)的。模型的作用就是簡化人對事物的認識,如果一開始我們就陷入到代碼細節(jié)中,很難看到業(yè)務(wù)的全貌,而且代碼是為了實現(xiàn)業(yè)務(wù)能力,當(dāng)你知道了業(yè)務(wù)之后,再去看代碼就會快得多。

    2 統(tǒng)一認識

    在公司里,有研發(fā)、產(chǎn)品、運營、測試……,當(dāng)我們在一起交流的時候,大家默認的語言是不統(tǒng)一的,開發(fā)經(jīng)常講怎么操作這張數(shù)據(jù)庫表,產(chǎn)品經(jīng)常講業(yè)務(wù)模式……這就導(dǎo)致大家的認識并不統(tǒng)一。

    那是一個晚上,剛和交互同學(xué)確認完交互流程后,突然她問了一個問題:把相似的頁面讓賣家移到同一個文夾中,這個好實現(xiàn)吧?聽完后告知不能,交互同學(xué)一聽說這很合理呀,怎么實現(xiàn)不了?開始給她講了下現(xiàn)有的系統(tǒng)流程,發(fā)現(xiàn)她聽得一臉懵逼,馬上發(fā)現(xiàn)問題了,我是用開發(fā)的語言在描述問題,立馬換了一種方式,找了一支筆和一張紙,給交互同學(xué)畫了我們的領(lǐng)域模型是什么,業(yè)務(wù)實體之間的交互是怎樣的,一講完后,交互同學(xué)馬上明白了為什么不能實現(xiàn)的原因所在了。

    3 指導(dǎo)設(shè)計

    有的同學(xué)覺得領(lǐng)域建模偏空洞,比較虛,其實除了能夠簡化認識和統(tǒng)一認識外,領(lǐng)域建模還可能指導(dǎo)代碼設(shè)計,比如上面舉的店鋪導(dǎo)航Tab的例子,筆者就是通過領(lǐng)域建模來設(shè)計的,雖然它是一個小的需求,并不妨礙領(lǐng)域建模的運用。在下圖中,可以清晰的看到,導(dǎo)航欄包含了若干個Tab,一個Tab包含規(guī)格信息和點擊操作信息。把這個業(yè)務(wù)模式畫出來之后,對應(yīng)的代碼中也會有上面的概念,現(xiàn)實與代碼之間存在映射關(guān)系,模型即代碼,代碼即模型。如果你的模型不能反映現(xiàn)實,模塊只能算是一個花架子,范鋼老師對此總結(jié)了三句話:現(xiàn)實有什么事物,對應(yīng)有什么對象;現(xiàn)實事物有什么行為,對應(yīng)對象有什么方法;現(xiàn)實事物有什么聯(lián)系,對應(yīng)對象有什么關(guān)聯(lián)。

    四 設(shè)計原則的底層邏輯

    1 SOLID

    對于設(shè)計原則,一般我們會談到SOLID,它包含了五個設(shè)計原則:

  • 單一職責(zé)原則:A class should have one, and only one, reason to change,一個類只能因為一個理由被修改。
  • 開閉原則:Entities should be open for extension, but closed for modification,對擴展開放,對修改關(guān)閉。
  • 里氏替換原則:Functions that use pointers of references to base classes must be able to use objects of derived classes without knowing it,子類可以替換父類。
  • 接口隔離原則:A client should not be forced to implement an interface that it doesn’t use,不能強制客戶端實現(xiàn)它不使用的接口,應(yīng)該把接口拆的盡可能小。
  • 依賴倒置原則:Abstractions should not depend on details. Details should depend on abstractions,抽象不依賴于細節(jié),而細節(jié)依賴于抽象。

    2 為什么要有設(shè)計原則

    我們對SOLID原則基本上聽說過或者了解過,但為什么要有這些設(shè)計原則呢?為了回答這個問題,我們從目標往下推導(dǎo)下。軟件開發(fā)的目標是高內(nèi)聚、低耦合,這句掛在嘴邊的話,發(fā)現(xiàn)很難衡量,比如要回答:什么樣的叫高內(nèi)聚?什么樣的叫低耦合?高內(nèi)聚要高到什么程度?低耦合要低到什么程度?這四個問題并不太好回答。

    反過來想想,如果我們的代碼不是高內(nèi)聚和低耦合的會怎樣?也即是低內(nèi)聚和高耦合的場景。如果代碼是低內(nèi)聚和高耦合,則會出現(xiàn)修改一個邏輯,會導(dǎo)致多處代碼要修改,這個并不是我們希望看到的,尤其在修改原有的邏輯,很容易出現(xiàn)bug,比如筆者之前修改一個問題,改了另外一處的規(guī)則,看起來是沒有問題,結(jié)果影響到了一個業(yè)務(wù)方,這也是為什么開閉原則提出對修改關(guān)閉的原因,修改原有的邏輯是有風(fēng)險的。

    理想的情況是修改只限定在某個局部范圍內(nèi),這樣影響的范圍有限,因此我們要求邏輯要單一,不要包含多個職責(zé)。再往下思考下:為什么我們要修改呢?除了原有邏輯有bug要修復(fù)、代碼重構(gòu)外,一個重要的原因是需求發(fā)生了變化,是變化導(dǎo)致我們要對原有的邏輯進行修改。如果沒有修改的場景,也就沒有所謂的高內(nèi)聚、低耦合之說了。因此設(shè)計原則的底層邏輯就是讓軟件能夠較好地應(yīng)對變化,降本增效。

    3 如何落地實踐

    設(shè)計原則只是一個指導(dǎo)的方針,離落地實踐還有很大的一段距離,就像有些同學(xué)說設(shè)計原則我懂了,但我依然運用不到。實際上這個問題的本質(zhì)還是對設(shè)計原則的底層邏輯沒有理解,沒有洞察出變化關(guān)注點,怎么解決這個問題呢?設(shè)計模式給出的答案:找到變化、封裝變化。

    五 設(shè)計模式的本質(zhì)

    設(shè)計模式請參考筆者之前寫的文章。

    六 案例實踐

    當(dāng)調(diào)用的接口有不同的實現(xiàn)時(入?yún)ⅰ⒊鰠ⅰ⒔涌诙疾幌嗤枰橄蟪鲆粚臃栏瘜樱趺慈崿F(xiàn)呢?接下來分別看2個案例,這2個案例的側(cè)重點不一樣,一個是偏行為的抽象,一個是偏結(jié)構(gòu)的抽象。

    1 店鋪品牌查詢

    店鋪需要查詢店鋪品牌信息,然而Lazada和AE的接口是不一樣的,怎么抽象防腐層呢?

    首先最簡單的方案很容易想到,就是定義一個接口,然后有兩個實現(xiàn)。它的優(yōu)點是層次簡單,大家基本看了就懂。它的缺點也是明顯的,在兩個實現(xiàn)類中,職責(zé)不一單一,承擔(dān)了兩個職責(zé):一個是實現(xiàn)店鋪品牌的查詢,另一個是數(shù)據(jù)轉(zhuǎn)換。

    根據(jù)方案一提到的缺點,很容易想到使用適配器模式,將之前的類拆成兩個類:一個類是調(diào)用對應(yīng)的品牌服務(wù);另一個類做數(shù)據(jù)適配轉(zhuǎn)換。不過此時的方式還有一個缺點就是在國際化場景下,要考慮多租戶之間的隔離,比如Lazada有多個站點,如何實現(xiàn)更細粒度的差異呢?方案三基于這些的思考就產(chǎn)生了。

    方案三是引入了多租戶框架,能夠支撐多租戶場景。

    2 店鋪優(yōu)惠券查詢

    有一種"萬金油"式開發(fā)模式:組裝參數(shù)、調(diào)用接口、解析響應(yīng)結(jié)果,你會發(fā)現(xiàn)這種模式太萬能了,適合所有的場景,這樣的開發(fā)模式也即是"事務(wù)腳本模式"或者"面條型代碼"。

    優(yōu)惠券查詢的案例,用領(lǐng)域建模的模式,首先思考有哪些實體。優(yōu)惠券查詢的本質(zhì):通過xx條件查詢返回滿足條件的優(yōu)惠券集合。對于優(yōu)惠券來講,有兩類信息至關(guān)重要。一個是優(yōu)惠券的規(guī)格信息,如優(yōu)惠券名稱、優(yōu)惠金額、有效期等;另一個是優(yōu)惠券的限制條件。在查詢的時候,是查店鋪優(yōu)惠券,還是查粉絲優(yōu)惠券,或者是查詢商品優(yōu)惠券……。因此分開兩部分抽象優(yōu)惠券:一個是優(yōu)惠券查詢請求;另一個是優(yōu)惠券規(guī)格實體。

    如果按照這樣的設(shè)計,有一個缺點是業(yè)務(wù)方理解復(fù)雜度會上升,它是偏底層實現(xiàn),沒有做到使用簡單。優(yōu)惠券偏產(chǎn)品交付而非僅僅功能交付。因此在底層實現(xiàn)之上,再抽象出產(chǎn)品組件,這樣業(yè)務(wù)方使用起來就比較簡單。

    作者 | 不拔

    原文鏈接:http://click.aliyun.com/m/1000290565/

    本文為阿里云原創(chuàng)內(nèi)容,未經(jīng)允許不得轉(zhuǎn)載。

  •  
    (文/宮志強)
    免責(zé)聲明
    本文僅代表作發(fā)布者:宮志強個人觀點,本站未對其內(nèi)容進行核實,請讀者僅做參考,如若文中涉及有違公德、觸犯法律的內(nèi)容,一經(jīng)發(fā)現(xiàn),立即刪除,需自行承擔(dān)相應(yīng)責(zé)任。涉及到版權(quán)或其他問題,請及時聯(lián)系我們刪除處理郵件:weilaitui@qq.com。
     

    Copyright ? 2016 - 2025 - 企資網(wǎng) 48903.COM All Rights Reserved 粵公網(wǎng)安備 44030702000589號

    粵ICP備16078936號

    微信

    關(guān)注
    微信

    微信二維碼

    WAP二維碼

    客服

    聯(lián)系
    客服

    聯(lián)系客服:

    在線QQ: 303377504

    客服電話: 020-82301567

    E_mail郵箱: weilaitui@qq.com

    微信公眾號: weishitui

    客服001 客服002 客服003

    工作時間:

    周一至周五: 09:00 - 18:00

    反饋

    用戶
    反饋

    主站蜘蛛池模板: 日韩一级在线观看| 花季视传媒app下载| 欧美乱大交XXXXX疯狂俱乐部| 国内外成人在线视频| 亚洲高清偷拍一区二区三区| jazzjazz国产精品一区二区 | 久久久久久中文字幕| 青娱乐精品视频| 日产精品卡二卡三卡四卡乱码视频| 国产人妖系列在线精品| 久久久久久久久久国产精品免费| 被夫上司强迫的女人在线| 日本videos18高清hd下| 国产一区在线观看视频| 中文字幕一区二区三区乱码| 成人免费视频网站www| 日韩中文字幕网| 国产一在线精品一区在线观看 | 国产乱码一区二区三区| 亚洲欧洲日产v特级毛片| 2021国产精品自产拍在线观看| 精品免费国产一区二区三区| 女女女女BBBBBB毛片在线| 亚洲色大成网站WWW尤物| 92国产精品午夜福利免费| 欧美乱xxxxx| 国产午夜福利在线观看视频| 亚洲AV无码成人黄网站在线观看| 91国内揄拍国内精品对白| 深夜a级毛片免费视频| 国产精品日韩一区二区三区| 亚洲一区在线免费观看| 182在线播放| 日韩在线电影网| 嘟嘟嘟www在线观看免费高清| juliecasha大肥臀hd| 欧美成人高清WW| 国产成人久久av免费| 中文字幕巨大乳在线看| 爱搞网在线观看| 国产日韩在线亚洲字幕中文|