代碼審查與重構(gòu)的5個(gè)層次

? ?最近一直在從事一款iOS的app的開發(fā)工作。為了提高團(tuán)隊(duì)整體的代碼質(zhì)量,從項(xiàng)目開始我就一直擔(dān)負(fù)著代碼審查重構(gòu)的工作盘榨。在這期間發(fā)現(xiàn)了很多問題郊愧,也吸取了很多教訓(xùn)朴译。今天將自己的思路總結(jié)一下井佑,整理出了代碼審查重構(gòu)由高到低的5個(gè)層次。

第一個(gè)層次:業(yè)務(wù)架構(gòu)的審查重構(gòu)

? ?這是最高層次的代碼審查重構(gòu)眠寿。其實(shí)躬翁,這個(gè)階段的審查并未真正涉及到具體的代碼實(shí)現(xiàn),而是針對(duì)客戶需求盯拱,對(duì)相應(yīng)的業(yè)務(wù)邏輯的設(shè)計(jì)進(jìn)行審查盒发,目的在于使業(yè)務(wù)邏輯架構(gòu)的設(shè)計(jì)與用戶需求保持精確一致。這里審查所謂的業(yè)務(wù)架構(gòu)可以從兩個(gè)層次討論:首先是審查復(fù)雜且完整的業(yè)務(wù)邏輯的架構(gòu)狡逢,比如支付相關(guān)的業(yè)務(wù)邏輯架構(gòu)宁舰,導(dǎo)航,map奢浑,語音相關(guān)的業(yè)務(wù)等等蛮艰。這個(gè)層次的審查需要我們充分了解相關(guān)的業(yè)務(wù)知識(shí),進(jìn)而審查業(yè)務(wù)架構(gòu)的合理性與準(zhǔn)確性雀彼。以支付為例壤蚜,我們需要熟悉支付方式以及支付的整個(gè)流程,另外還有其中涉及的一些關(guān)鍵問題徊哑。最終確保我們的業(yè)務(wù)邏輯的架構(gòu)設(shè)計(jì)符合這一系列的需求袜刷。

? ?其次,審查簡單的單個(gè)功能點(diǎn)的業(yè)務(wù)邏輯設(shè)計(jì)實(shí)現(xiàn)实柠,例如用戶的注冊(cè)與登錄功能水泉。我們需要確保這些業(yè)務(wù)邏輯的設(shè)計(jì)完全符合UX的設(shè)計(jì),并最終符合用戶需求窒盐。

第二個(gè)層次:代碼架構(gòu)的審查重構(gòu)

? ?這個(gè)層次的審查針對(duì)的是項(xiàng)目中采用的具體的架構(gòu)模式草则,目的在于審查代碼是否符合架構(gòu)模式。在我們目前的項(xiàng)目中采用的是mvvm架構(gòu)模式蟹漓,因此在這個(gè)層次的代碼審查的時(shí)候應(yīng)注重審查代碼是否遵循了mvvm的基本原則炕横。

? ?View部分:其中包含了view組件以及ViewController主要的功能應(yīng)在于處理界面的顯示,而不應(yīng)有任何的業(yè)務(wù)邏輯的處理葡粒;

? ?ViewModel部分:應(yīng)主要負(fù)責(zé)業(yè)務(wù)邏輯的處理份殿,并不涉及任何頁面的展示邏輯。

? ?Model部分:應(yīng)主要負(fù)責(zé)業(yè)務(wù)數(shù)據(jù)模型的建立嗽交,使用它可以根據(jù)業(yè)務(wù)邏輯建立相應(yīng)的業(yè)務(wù)數(shù)據(jù)卿嘲。

? ?另外涉及到各部分之間的交互通信,項(xiàng)目中我們采用了RxSwift夫壁,因此應(yīng)遵循其相應(yīng)的語法規(guī)則與使用習(xí)慣拾枣。

? ?最后涉及到項(xiàng)目中引入的依賴注入的框架SwInject,也要符合其使用規(guī)范,最大限度的消除依賴梅肤。

? ?總之司蔬,在這個(gè)層次的代碼審查重構(gòu)的時(shí)候,我們應(yīng)始終把焦點(diǎn)關(guān)注在代碼是否符合我們項(xiàng)目中所采用的架構(gòu)模式姨蝴。無論app開發(fā)還是web開發(fā)俊啼,其實(shí)都是一個(gè)道理。

第三個(gè)層次:設(shè)計(jì)模式的審查重構(gòu)

? ?這個(gè)階段主要針對(duì)的是面向?qū)ο箝_發(fā)中的類之間的組織結(jié)構(gòu)以及類自身行為屬性的設(shè)計(jì)左医,這可能就會(huì)涉及到一些設(shè)計(jì)模式的使用授帕。通過使用設(shè)計(jì)模式,可以使我們的代碼更加的可復(fù)用炒辉,可擴(kuò)展以及可測(cè)試豪墅。這是我們這個(gè)階段進(jìn)行設(shè)計(jì)模式的審查重構(gòu)的目的。然而設(shè)計(jì)模式的過度使用也會(huì)使代碼陷入“萬惡的深淵”黔寇,提前設(shè)計(jì)與設(shè)計(jì)過度同樣不可取。

? ?因此設(shè)計(jì)模式的審查重構(gòu)時(shí)應(yīng)注重審查:

? ?(1)代碼應(yīng)盡量保持簡單斩萌,只有在必要的時(shí)候才使用設(shè)計(jì)模式缝裤,避免過度設(shè)計(jì)與提前設(shè)計(jì)。

? ?(2)設(shè)計(jì)應(yīng)遵循面向?qū)ο缶幊痰腟OLID原則颊郎。

? ?(3)使用規(guī)范化的設(shè)計(jì)模式的“術(shù)語”編寫憋飞,如設(shè)計(jì)模式中類的命名等相關(guān)“術(shù)語”應(yīng)標(biāo)準(zhǔn)化,規(guī)范化姆吭。

? ?(4)使用結(jié)構(gòu)型設(shè)計(jì)模式進(jìn)行類的組織結(jié)構(gòu)設(shè)計(jì)榛做。這其中包括:Composite, Decorator, Adapter, Bridge, Facade, Proxy, Flyweight。

? ?(5)使用行為型設(shè)計(jì)模式進(jìn)行類方法的設(shè)計(jì), 進(jìn)行封裝變化内狸,對(duì)象做為參數(shù)的封裝检眯,對(duì)象間通信,類間解耦合昆淡。包括:Strategy, State, Template method, Visitor, Command, Memento, Observer, Mediator, Iterator, Interpreter, Chain of responsibility锰瘸。

? ?(6)使用創(chuàng)建型設(shè)計(jì)模式進(jìn)行類型的創(chuàng)建初始化。它包括:Factory method, Abstract factory, Builder, Prototype, singleton昂灵。

第四個(gè)層次:最優(yōu)算法的審查重構(gòu)

? ?這個(gè)層次的代碼審查重構(gòu)針對(duì)的是代碼算法的使用避凝,主要審查面向?qū)ο箢愔蟹椒ǖ乃惴ㄔO(shè)計(jì)實(shí)現(xiàn)。這里說的算法的使用并非一定要使用那些經(jīng)典的算法眨补,例如排序算法管削,查找算法等,而指的是使用合理的數(shù)據(jù)結(jié)構(gòu)進(jìn)行時(shí)間與空間最優(yōu)化的代碼編寫撑螺,不分配不必要的空間含思,盡量設(shè)計(jì)時(shí)間復(fù)雜度更低的的代碼段∈蹬睿總之茸俭,設(shè)計(jì)更為高效的代碼段吊履。

第五個(gè)層次:語言與代碼規(guī)范的審查重構(gòu)

? ?這是最后一個(gè)層次,也是最為細(xì)節(jié)性的層級(jí):代碼的編寫调鬓。在這個(gè)層次上艇炎,代碼審查以及重構(gòu)時(shí)應(yīng)注重語言的最佳實(shí)踐與代碼風(fēng)格的規(guī)范。

? ?首先腾窝,語言最佳實(shí)踐的審查與重構(gòu)缀踪。

? ?代碼編寫首先應(yīng)符合使用的編程語言的語法規(guī)范,除此之外虹脯,我們還應(yīng)該努力踐行編程語言的最佳實(shí)踐驴娃,比如盡量使用語言已提供的庫中的API,避免重復(fù)建造輪子循集。我們項(xiàng)目中采用的是swift語言唇敞,在涉及到集合類的遍歷處理的時(shí)候,我們不應(yīng)該自己編寫for in loop來實(shí)現(xiàn)遍歷的功能咒彤,而應(yīng)使用集合類的從sequenceType中繼承而來的foreach方法疆柔,通過閉包的方式講要處理的行為變量傳人,從而實(shí)現(xiàn)遍歷處理的功能镶柱。

? ?其次旷档,代碼風(fēng)格的規(guī)范的審查與重構(gòu)。

? ?統(tǒng)一的代碼風(fēng)格規(guī)范是團(tuán)隊(duì)開發(fā)的重要要素之一歇拆。代碼規(guī)范的統(tǒng)一有利于代碼的閱讀維護(hù)鞋屈,有利于代碼的“集體所有制”。試想故觅,如果團(tuán)隊(duì)中每個(gè)人都使用自己的一套代碼規(guī)范厂庇,那整體的代碼風(fēng)格就可謂“百花爭(zhēng)放”,最后的結(jié)果就是代碼越來越混亂逻卖,且難以閱讀維護(hù)宋列。我們項(xiàng)目中統(tǒng)一的代碼風(fēng)格概括來講有如下幾個(gè)方面:

? ?(1)命名:使用帕斯卡命名法命名類名,即名稱中每個(gè)單詞首字母大寫评也,采用形容詞+名詞的形式炼杖;駝峰法命名函數(shù)與屬性,即名稱中除第一個(gè)單詞首字母小寫外盗迟,其他單詞首字母均大寫坤邪。函數(shù)命名采用動(dòng)詞+名詞的組合形式。屬性命名采用形容詞+名詞的形式罚缕。通過使用有意義的命名艇纺,使屬性與函數(shù)通過名稱可以自我表達(dá),從而取代注釋。

? ?(2)函數(shù):保證每個(gè)函數(shù)的單一功能性黔衡,讓每個(gè)函數(shù)只做一件事情蚓聘。采用“To”方法編寫函數(shù),就是將函數(shù)分步編寫盟劫,使每個(gè)步驟單獨(dú)成為一個(gè)新的函數(shù)夜牡。函數(shù)參數(shù)個(gè)數(shù)應(yīng)盡量減少,可以封裝在一起的盡量封裝起來侣签。

? ?(3)避免重復(fù):應(yīng)避免代碼的隨處拷貝塘装,拷貝是重復(fù)的根源之一。應(yīng)將可復(fù)用的部分提取出來影所,供不同的使用者調(diào)用蹦肴。

? ?(4)代碼一致性:一致性可以使代碼更整潔美觀。項(xiàng)目中為了保持一致性猴娩,我們需要一些約定俗成的事情阴幌,例如命名規(guī)則,要不要使用宏定義等等卷中。

? ?(5)去除魔幻數(shù):不應(yīng)在代碼中硬編碼一些數(shù)據(jù)裂七,比如:expectedValue = actualValue*5 + 20,類似這種代碼仓坞,沒人能看明白代碼中的5和20是神馬意思。我們可以使用宏定義或者創(chuàng)建靜態(tài)屬性的方式實(shí)現(xiàn)腰吟,定義成為可被理解閱讀的代碼无埃。

? ?(6)封裝條件表達(dá)式中的條件判斷:代碼中的條件表達(dá)式中如果有很多的條件判斷時(shí),對(duì)于閱讀代碼的人來說毛雇,很難讀懂到底為了判定什么東西設(shè)立的這些條件嫉称。將條件表達(dá)式中的條件判斷封裝成為一個(gè)單獨(dú)的方法,并命名一個(gè)有意義的名稱灵疮,可以極大的提高代碼的可讀性织阅。

? ?(7)函數(shù)異常處理:保持代碼的安全性,需要時(shí)刻注意異常的處理震捣。異常處理分為兩個(gè)部分荔棉,首先是空值的判定,避免程序因空值造成的crash蒿赢∪笥#空值判定主要包括函數(shù)參數(shù)的空值判定以及內(nèi)部局部變量的空值判定;其次是異常的處理羡棵,比如io異常等等壹若。

? ?(8)單元測(cè)試:單元測(cè)試的重要性相信大家都應(yīng)該清楚,只是鑒于開發(fā)進(jìn)度壓力,往往被忽視店展。對(duì)于小型并不復(fù)雜的項(xiàng)目而言养篓,可能單元測(cè)試的作用沒有完全體現(xiàn)出來,但是對(duì)于復(fù)雜度很高赂蕴,團(tuán)隊(duì)規(guī)模較大的項(xiàng)目而言柳弄,單元測(cè)試就無比重要了。我目前所做的項(xiàng)目睡腿,復(fù)雜度非常高语御,團(tuán)隊(duì)規(guī)模也很大,并且需要與歐美團(tuán)隊(duì)協(xié)同開發(fā)席怪,因此保證單元測(cè)試的代碼覆蓋度非常重要应闯。因此,應(yīng)保證每段代碼都應(yīng)被單元測(cè)試覆蓋挂捻。

? ?(9)多線程并發(fā)處理碉纺。開發(fā)中會(huì)經(jīng)常涉及到多線程的問題,因此多線程的并發(fā)處理需要高度重視刻撒,很多問題就是由于多線程并發(fā)造成骨田。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市声怔,隨后出現(xiàn)的幾起案子态贤,更是在濱河造成了極大的恐慌,老刑警劉巖醋火,帶你破解...
    沈念sama閱讀 222,378評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件悠汽,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡芥驳,警方通過查閱死者的電腦和手機(jī)柿冲,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,970評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來兆旬,“玉大人假抄,你說我怎么就攤上這事±鲡” “怎么了宿饱?”我有些...
    開封第一講書人閱讀 168,983評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長宝鼓。 經(jīng)常有香客問我刑棵,道長,這世上最難降的妖魔是什么愚铡? 我笑而不...
    開封第一講書人閱讀 59,938評(píng)論 1 299
  • 正文 為了忘掉前任蛉签,我火速辦了婚禮胡陪,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘碍舍。我一直安慰自己柠座,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,955評(píng)論 6 398
  • 文/花漫 我一把揭開白布片橡。 她就那樣靜靜地躺著妈经,像睡著了一般。 火紅的嫁衣襯著肌膚如雪捧书。 梳的紋絲不亂的頭發(fā)上吹泡,一...
    開封第一講書人閱讀 52,549評(píng)論 1 312
  • 那天,我揣著相機(jī)與錄音经瓷,去河邊找鬼爆哑。 笑死,一個(gè)胖子當(dāng)著我的面吹牛舆吮,可吹牛的內(nèi)容都是我干的揭朝。 我是一名探鬼主播,決...
    沈念sama閱讀 41,063評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼色冀,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼潭袱!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起锋恬,我...
    開封第一講書人閱讀 39,991評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤屯换,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后与学,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體趟径,經(jīng)...
    沈念sama閱讀 46,522評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,604評(píng)論 3 342
  • 正文 我和宋清朗相戀三年癣防,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片掌眠。...
    茶點(diǎn)故事閱讀 40,742評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蕾盯,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蓝丙,到底是詐尸還是另有隱情级遭,我是刑警寧澤,帶...
    沈念sama閱讀 36,413評(píng)論 5 351
  • 正文 年R本政府宣布渺尘,位于F島的核電站挫鸽,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏鸥跟。R本人自食惡果不足惜丢郊,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,094評(píng)論 3 335
  • 文/蒙蒙 一盔沫、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧枫匾,春花似錦架诞、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,572評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至角虫,卻和暖如春沾谓,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背戳鹅。 一陣腳步聲響...
    開封第一講書人閱讀 33,671評(píng)論 1 274
  • 我被黑心中介騙來泰國打工均驶, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人粉楚。 一個(gè)月前我還...
    沈念sama閱讀 49,159評(píng)論 3 378
  • 正文 我出身青樓辣恋,卻偏偏與公主長得像,于是被迫代替她去往敵國和親模软。 傳聞我的和親對(duì)象是個(gè)殘疾皇子伟骨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,747評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容