亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

重構(gòu)改善既有的代碼設(shè)計(jì)(代碼的壞味道)

Code4App / 2823人閱讀

摘要:壞的味道指的是應(yīng)該被修改,被重構(gòu)的代碼,不具有可讀性,復(fù)用性,判斷邏輯復(fù)雜,冗余代碼。它們通常能指出代碼用途和實(shí)現(xiàn)手法之間的語(yǔ)義距離。把所有和這個(gè)變量相關(guān)的代碼新建一個(gè)類放入。但這往往不夠,請(qǐng)反復(fù)運(yùn)用將某些行為移入類,直到者的協(xié)議一致為止。

壞的味道:指的是應(yīng)該被修改,被重構(gòu)的代碼,不具有可讀性,復(fù)用性,判斷邏輯復(fù)雜,冗余代碼。應(yīng)該使用各種重構(gòu)的手法去改變它!
Duplicated Code(重復(fù)代碼)
如果你在一個(gè)以上的地點(diǎn)看到相同的程序結(jié)構(gòu),那么可以肯定的:設(shè)法將他們合而為一,程序會(huì)變得更好。

同一個(gè)類的兩個(gè)函數(shù)含有相同的表達(dá)式

兩個(gè)互為兄弟子類內(nèi)含相同表達(dá)式

如果兩個(gè)毫不相關(guān)的類出現(xiàn)Duplicated Code 應(yīng)該考慮對(duì)其中一個(gè)將重復(fù)代碼提煉到一個(gè)獨(dú)立類種,然后在另一個(gè)類內(nèi)使用這個(gè)新類。

Long Method(過(guò)長(zhǎng)函數(shù))
我們應(yīng)當(dāng)遵循這樣一條原則:每當(dāng)感覺(jué)需要以注釋來(lái)說(shuō)明點(diǎn)什么的時(shí)候,我們就需要說(shuō)明的東西寫進(jìn)一個(gè)獨(dú)立的函數(shù)中,并以器用途(而非實(shí)現(xiàn)手法)命名。

我們可以對(duì)一組甚至短短一行代碼做這件事。哪怕替換后的函數(shù)調(diào)用動(dòng)作比函數(shù)自身還長(zhǎng),只要函數(shù)名稱能夠解釋其用途,我們也該毫不猶豫得那么做。關(guān)鍵不在于函數(shù)得長(zhǎng)度,而在于函數(shù):“做什么”和“如何做”之間得語(yǔ)義距離。

如何確定該提煉哪一段代碼呢?一個(gè)很好得技巧是:尋找注釋。它們通常能指出代碼用途和實(shí)現(xiàn)手法之間的語(yǔ)義距離。如果代碼前方有一行注釋,就是再提醒你L可以將這段代碼替換成一個(gè)函數(shù),而且可以在注釋得基礎(chǔ)上給這個(gè)函數(shù)命名。就算只有一行代碼,如果他需要以注釋來(lái)說(shuō)明,那也值得將它提煉導(dǎo)獨(dú)立函數(shù)去。

條件表達(dá)式和循環(huán)常常也是提煉得信號(hào)。可以使用Decompose Conditional處理?xiàng)l件表達(dá)是。至于循環(huán),你應(yīng)該將循環(huán)和期內(nèi)的代碼提煉導(dǎo)一個(gè)獨(dú)立的函數(shù)中

Large Class(過(guò)大的類)

如果類中有太多的實(shí)例變量,可以將幾個(gè)變量提煉至新類內(nèi)。提煉時(shí)應(yīng)該選擇類內(nèi)彼此相關(guān)的變量,將它們放在一起

類內(nèi)如果有太多代碼,把多余的東西消弭于類內(nèi)部。如果有五個(gè)“百行代碼”,它們之中很多代碼都相同,那么或許你可以把它們變成五個(gè)“十行函數(shù)”和十個(gè)提煉出的“雙行函數(shù)”。

Long Parameter List(過(guò)長(zhǎng)的參數(shù)列)

如果已有的對(duì)象發(fā)出一條請(qǐng)求就可以取代一個(gè)參數(shù),那么你應(yīng)該激活重構(gòu)手法Replace Paramter with Method。在這里,“已有的對(duì)象”可能時(shí)函數(shù)所屬類內(nèi)一個(gè)字段,也可能是另一個(gè)參數(shù)。你也可以運(yùn)用Preserve Whole Object將來(lái)自同一個(gè)對(duì)象的一堆數(shù)據(jù)收集起來(lái),并以該對(duì)象替換它們。如果某些數(shù)據(jù)缺乏合理的對(duì)象歸屬,可以使用Introduce Parameter Object 為它們制造出一個(gè)“參數(shù)對(duì)象”。

Divergent Change(發(fā)散式變化)
一旦需要修改,我們希望能夠跳到系統(tǒng)的某一點(diǎn),只在該處做修改。如果不能做到這點(diǎn),你就嗅出兩種相關(guān)的刺鼻味道中的一種了。

針對(duì)某一外界變化的所有相應(yīng)修改,都只應(yīng)發(fā)生在單一類中,而這個(gè)新類內(nèi)的所有內(nèi)容都應(yīng)該反應(yīng)此變化,為此,你應(yīng)該找出某特定原因而造成的所有變化,然后運(yùn)用Extract Class將它們提煉導(dǎo)另一個(gè)類中。

Shotgun Surgery(散彈式修改)
遇到某種變化,你都必須在不同類內(nèi)做出許多小修改,你所面臨的壞味道就是shotgun Surgery,如果需要修改的代碼散布四處,你不但很難找到它們,也很容易忘記某個(gè)重要的修改

這種情況下應(yīng)該使用Move MethodMove Field把所有需要修改的代碼放進(jìn)同一個(gè)類。如果眼下沒(méi)有合適的類可以安置這些代碼,就創(chuàng)造一個(gè)。通常可以運(yùn)用inline class把一系列相關(guān)行為放進(jìn)同一個(gè)類。

Divergent change 是指“一個(gè)類受多種變化影響”,shotgun surgery則是指“一種變化引發(fā)多個(gè)類相應(yīng)修改”。者兩種情況下你都會(huì)希望整理代碼,使“外界變化”與“需要修改的類”趨于一一對(duì)應(yīng)。

Feature Envy(依戀情結(jié))
函數(shù)對(duì)某個(gè)類的興趣高過(guò)對(duì)自己所處類的興趣,通常焦點(diǎn)便是數(shù)據(jù),某個(gè)函數(shù)為了計(jì)算某個(gè)值,從另一個(gè)對(duì)象那調(diào)用幾乎半打的額取值函數(shù)。

療法顯而易見(jiàn):把這個(gè)函數(shù)移至另一個(gè)地點(diǎn)。

一個(gè)函數(shù)往往會(huì)用到幾個(gè)類的功能,那么它究竟該被置于何處呢?我們的原則是判斷哪個(gè)類擁有最多被此函數(shù)使用的數(shù)據(jù),然后把這個(gè)函數(shù)和那些數(shù)據(jù)擺在一起。

Data Clumps(數(shù)據(jù)泥團(tuán))

兩個(gè)類中相同的字段、許多函數(shù)簽名中相同的參數(shù)。這些總是綁在一起出現(xiàn)的數(shù)據(jù)真應(yīng)該擁有屬于它們自己的對(duì)象

一個(gè)好的評(píng)判方法是:刪掉眾多數(shù)據(jù)中的一項(xiàng)。這么做,其他數(shù)據(jù)有沒(méi)有因而失去意義?如果它們不在有意義,這就是個(gè)明確信號(hào):你應(yīng)該為它們產(chǎn)生一個(gè)新對(duì)象。

Primitive Obsession(基本類型偏執(zhí))
對(duì)象的一個(gè)極大的價(jià)值在于:它們模糊(甚至打破)了橫亙于基本類型數(shù)據(jù)和體積較大類之間的界限

可以運(yùn)用Replace Data Vlaue with Object將原本多帶帶存在的數(shù)據(jù)值替換為對(duì)象

如果想要替換的數(shù)據(jù)值是類型碼,而它并不影響行為,則可以運(yùn)用Replace type Code with class 將它替換

如果有與類型碼有關(guān)的條件表達(dá)式,可運(yùn)用 Replace Type Code with Subclass 或 Replace Type Code with State/Strategy

Switch Statements(switch 驚悚現(xiàn)身)

大多數(shù)時(shí)候,一看到switch語(yǔ)句,你就應(yīng)該考慮以多態(tài)來(lái)替換它。問(wèn)題是多態(tài)應(yīng)該出現(xiàn)在哪兒?switch語(yǔ)句常常根據(jù)類型碼進(jìn)行選擇,你要的是“與該類型碼相關(guān)的函數(shù)或類

Parallel Inheritance Hierarchies(平行繼承體系)
Shotgun Surgery的特殊情況,在這種情況下,每當(dāng)你為某個(gè)類增加一個(gè)子類,也必須為另一個(gè)類相應(yīng)的增加一個(gè)子類。如果你發(fā)現(xiàn)某個(gè)繼承體系的名稱前綴和另一個(gè)繼承體系名稱前綴完全相同,便是聞到了這種壞味道

消除這種重復(fù)性的一般策略是:讓一個(gè)繼承體系的實(shí)例引用另一個(gè)繼承體系的實(shí)例。再運(yùn)用Move Method 和Move Field,就可以就將引用端的繼承體系消弭于無(wú)形

Lazy Class(冗贅類)
如果一個(gè)類的所得不值其身價(jià),它就該消失

如果某些子類沒(méi)有做足夠的工作,試試Collapse Hierarchy。對(duì)于幾乎沒(méi)用的組件,你應(yīng)該以Inline Class對(duì)付它們

Speculative Generality(夸夸其談的未來(lái)性)
不要過(guò)分對(duì)的為未來(lái)考慮
如果你的某個(gè)抽象類其實(shí)沒(méi)有太大作用,請(qǐng)運(yùn)用Collapse Hierarchy。不必要的委托可運(yùn)用Inline Class除掉。如果函數(shù)的某些參數(shù)違背用上,可對(duì)它實(shí)施Remove Parameter。如果函數(shù)名稱帶有多余的抽象意味,應(yīng)該對(duì)它實(shí)施rename Method,讓它現(xiàn)實(shí)一點(diǎn)
Temporary Field (令人迷惑的暫時(shí)字段)

某個(gè)實(shí)例變量?jī)H為某種特定的情況而設(shè)。這樣的代碼讓人不易理解,因?yàn)槟阃ǔUJ(rèn)為對(duì)象在所有時(shí)候都需要它的所有變量,在未被使用的情況下猜測(cè)當(dāng)初其設(shè)置目的,會(huì)讓你發(fā)瘋的。把所有和這個(gè)變量相關(guān)的代碼新建一個(gè)類放入。

Message Chains(過(guò)度耦合的消息鏈)
如果你看到用戶一個(gè)對(duì)象請(qǐng)求另一個(gè)對(duì)象,然后后者請(qǐng)求另一個(gè)對(duì)象,然后再請(qǐng)求另一個(gè)對(duì)象這就是消息鏈

先觀察消息鏈最終得到的對(duì)象用來(lái)干什么的,看看能否以Extract Method 把使用該對(duì)象的代碼提煉到一個(gè)獨(dú)立的函數(shù)中再運(yùn)用Move Method 把這個(gè)函數(shù)推入消息鏈

Middle Man(中間人)
人們可能過(guò)度運(yùn)用委托,會(huì)有某個(gè)接口有一半的函數(shù)都委托給其他類,這樣就是過(guò)度運(yùn)用, 使用Remove Middle Man ,直接和真正負(fù)責(zé)的對(duì)象打交道
Inappropriate Intimacy(狎昵關(guān)系)

過(guò)分狎昵的類必須拆散. 你可以采用Move MethodMove Field 幫它們劃分界限, 從而減少狎昵行徑. 你可以可以看看是否可以運(yùn)用Change Bidirectional Association to Unidirectional (將雙向關(guān)聯(lián)改為單向關(guān)聯(lián))讓其中一個(gè)類對(duì)另一個(gè)斬?cái)嗲榻z.

如果兩個(gè)類實(shí)在是情投意合, 可以運(yùn)用Extract Class 把兩者的共同點(diǎn)提煉到一個(gè)安全的地點(diǎn),讓它們坦蕩地使用這個(gè)新類. 或者也可以嘗試運(yùn)用Hide Delegate讓另一個(gè)類來(lái)為它們傳遞相思情.

繼承往往造成過(guò)度親密, 因?yàn)樽宇悓?duì)超類的了解總是超過(guò)超類的主管愿望. 如果你覺(jué)的該讓這個(gè)孩子獨(dú)立生活了, 請(qǐng)運(yùn)用Replace Inheritance with Delegation 讓它離開(kāi)繼承體系.

Alternative Class with Different Interfaces(異曲同工的類)

如果兩個(gè)函數(shù)做同一件事,卻有著不同的簽名,請(qǐng)運(yùn)用Rename Method根據(jù)它們的用途重新命名。但這往往不夠,請(qǐng)反復(fù)運(yùn)用?Move Method將某些行為移入類,直到2者的協(xié)議一致為止。如果你必須反復(fù)而贅余的移入代碼才能完成這些,或許可運(yùn)用Extract SuperClass

Incomplete Library Class(不完美的類庫(kù))

如果只想修改類庫(kù)的一兩個(gè)函數(shù),可以運(yùn)用Introduce Foreign Method 如果想要添加一大堆額外行為,就得運(yùn)用Introduce Local Extension

Data Class(純稚的數(shù)據(jù)類)
所謂Data Class是指:它們擁有一些值域(fields),以及用于訪問(wèn)(讀寫〕這些值域的函數(shù),除此之外一無(wú)長(zhǎng)物。

這樣的classes只是一種「不會(huì)說(shuō)話的數(shù)據(jù)容器」,它們幾乎一定被其他classes過(guò)份細(xì)瑣地操控著。這些classes早期可能擁有public值域,果真如此你應(yīng)該在別人注意到它們之前,立刻運(yùn)用Encapsulate Field?(封裝值域)將它們封裝起來(lái)。如果這些classes內(nèi)含容器類的值域(collection fields),你應(yīng)該 檢査它們是不是得到了恰當(dāng)?shù)姆庋b;如果沒(méi)有,就運(yùn)用 Encapsulate Collection(封裝群集)?把它們封裝起來(lái)。對(duì)于那些不該被其他classes修改的值域,請(qǐng)運(yùn)用 Remove Setting Method(移除設(shè)置函數(shù))。

然后,找出這些「取值/設(shè)值」函數(shù)(getting and setting methods)被其他classes運(yùn)用的地點(diǎn)。嘗試以Move Method(搬移函數(shù))?把那些調(diào)用行為搬移到Data Class來(lái)。如果無(wú)法搬移整個(gè)函數(shù),就運(yùn)用 Extract Method(提煉函數(shù))?產(chǎn)生一個(gè)可被搬移的函數(shù)。不久之后你就可以運(yùn)用Hide Method?(隱藏某個(gè)函數(shù))把這些「取值/設(shè)值」函數(shù)隱藏起來(lái)了。

Refused Bequest(被拒絕的遺贈(zèng))
指的是一個(gè)子類,不需要父類中的過(guò)多方法

這樣我們可以為這個(gè)子類創(chuàng)建一個(gè)兄弟類,把父類中不需要的方法下移到兄弟類中去。 如果子類復(fù)用了超類的行為(實(shí)現(xiàn)),卻又不愿意支持超類的接口。不過(guò)即使不愿意繼承接口,也不要胡亂修改繼承體系,應(yīng)該運(yùn)用Replace Inheritance with Delegation 來(lái)達(dá)到目的

Comments(過(guò)多的注釋)
引用作者的一句話"當(dāng)你感覺(jué)需要撰寫注釋,請(qǐng)先嘗試重構(gòu),試著讓所有注釋都變得多余。"

并不是說(shuō)寫注釋不好,而是當(dāng)你寫一段很長(zhǎng)的注釋來(lái)說(shuō)明代碼邏輯的時(shí)候,說(shuō)明這段代碼真的很糟糕,你就要考慮重構(gòu)了。?

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/72464.html

相關(guān)文章

  • 重構(gòu)-改善代碼設(shè)計(jì)(三)--代碼的壞味道

    摘要:壞味道的代碼重復(fù)代碼會(huì)自動(dòng)標(biāo)注重復(fù)的代碼。一般都是遇到真實(shí)情況后才考慮得到霰彈式修改添加或修改一個(gè)功能引發(fā)多個(gè)類相應(yīng)修改遇到這種情況可以移動(dòng)代碼,將需要修改的代碼都放在同一個(gè)類下。被拒絕的遺贈(zèng)子類應(yīng)該繼承超類的函數(shù)和數(shù)據(jù)。 壞味道的代碼 重復(fù)代碼 idea會(huì)自動(dòng)標(biāo)注重復(fù)的代碼。一般重復(fù)代碼就是可以重構(gòu)的點(diǎn)。 同一個(gè)類的兩個(gè)函數(shù)還有相同的表達(dá)式,這時(shí)需要提煉出重復(fù)代碼。 兩個(gè)互為兄弟的...

    Mr_houzi 評(píng)論0 收藏0
  • 重構(gòu)---改善代碼設(shè)計(jì)

    摘要:為何重構(gòu)重構(gòu)有四大好處重構(gòu)改進(jìn)軟件設(shè)計(jì)如果沒(méi)有重構(gòu),程序的設(shè)計(jì)會(huì)逐漸腐敗變質(zhì)。經(jīng)常性的重構(gòu)可以幫助維持自己該有的形態(tài)。你有一個(gè)大型函數(shù),其中對(duì)局部變量的使用使你無(wú)法采用。將這個(gè)函數(shù)放進(jìn)一個(gè)單獨(dú)對(duì)象中,如此一來(lái)局部變量就成了對(duì)象內(nèi)的字段。 哪有什么天生如此,只是我們天天堅(jiān)持。 -Zhiyuan 國(guó)慶抽出時(shí)間來(lái)閱讀這本從師傅那里借來(lái)的書,聽(tīng)說(shuō)還是程序員的必讀書籍。 關(guān)于書的高清下載連...

    baihe 評(píng)論0 收藏0
  • 編寫可維護(hù)的代碼

    摘要:編寫可維護(hù)的代碼前言我們?cè)谛薷乃舜a的時(shí)候,閱讀他人代碼所花的時(shí)間經(jīng)常比實(shí)現(xiàn)功能的時(shí)間還要更多如果程序結(jié)構(gòu)不清晰,代碼混亂。這樣可以去除重復(fù)的代碼,提高靈活性關(guān)鍵點(diǎn)找出不同的地方和重復(fù)的地方。 編寫可維護(hù)的代碼 前言 我們?cè)谛薷乃舜a的時(shí)候,閱讀他人代碼所花的時(shí)間經(jīng)常比實(shí)現(xiàn)功能的時(shí)間還要更多 如果程序結(jié)構(gòu)不清晰,代碼混亂 。牽一發(fā)而動(dòng)全身。那維護(hù)起來(lái)就更難維護(hù)了 可讀性 可理解性...

    imingyu 評(píng)論0 收藏0
  • 重構(gòu):一項(xiàng)常常被忽略的基本功

    摘要:無(wú)論如何,單元測(cè)試一直是一中非常重要卻常常被忽視的技能。在實(shí)踐中,重構(gòu)的要求是很高的它需要有足夠詳盡的單元測(cè)試,需要有持續(xù)集成的環(huán)境,需要隨時(shí)隨地在小步伐地永遠(yuǎn)讓代碼處于可工作狀態(tài)下去進(jìn)行改善。 showImg(https://segmentfault.com/img/bVbttWF?w=1000&h=528); 五月初的時(shí)候朋友和我說(shuō)《重構(gòu)》出第 2 版了,我才興沖沖地下單,花了一個(gè)...

    idealcn 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<