附:前兩篇文章鏈接
!(http://www.itdecent.cn/p/251d1b796259?v=1673184489236)[重構(gòu)改善既有代碼的設(shè)計-代碼的壞味道(上)]
!(http://www.itdecent.cn/p/efa726759259)[重構(gòu)改善既有代碼的設(shè)計-代碼的壞味道(中)]
下面繼續(xù)把重構(gòu)一書代碼中的壞味道進行總結(jié)與列舉:
1.18 異曲同工的類(Alternative Classes with Different Interfaces)
如果兩個函數(shù)做同一件事,卻有著不同的名字。
使用 Rename Method(重命名函數(shù)) 重新命名這些相同功能的函數(shù),反復(fù)運用 Move Method(搬移函數(shù)) 將這些函數(shù)移入類,如果需要移入類的函數(shù)過多,可以考慮Extract Superclass(提煉父類)來減少過多贅余的屬性。
1.19 Incomplete Library Class (不完美的類庫)
含義:封裝好的類庫中功能不能滿足實際需求。
缺憾: 庫中沒有某些需求能夠使用的方法函數(shù)等,封裝好的庫不能更改。
目標(biāo): 解決代碼不能更改造成的不便。
實現(xiàn)方法:
使用 Introduce Foreign Method(162引入外加函數(shù))
在一個無法修改的類中增加新的函數(shù),剝離出來作為靜態(tài)函數(shù)放在需要的類中使用。
或使用 Introduce Local Extension(164引入本地擴展)
你需要為服務(wù)類提供一些額外函數(shù),但你無法修改這個類。
則你可以建立一個新類,使它包含這些額外函數(shù),讓這個拓展品成為源類的子類或包裝類。
該兩種重構(gòu)手法看后續(xù)文章更新會進一步附上鏈接以及詳細(xì)的總結(jié):
1.20 Data Class(純稚的數(shù)據(jù)類)
它們擁有一些字段,以及用于訪問(讀寫)這些字段的函數(shù), 除此之外一無長物.
這樣的類只是不會說話的數(shù)據(jù)容器, 它們幾乎一定被其他類過分細(xì)碎地操控著.
修改點:
1.這些類早期可能擁有public字段, 果真如此你應(yīng)該在別人注意到它們之前, 立刻運用Encapsulate Field(封裝字段) 將它們封裝起來.
2.如果這些類內(nèi)含有容器類字段, 你應(yīng)該檢查它們是不是得到了恰當(dāng)?shù)姆庋b;
3.如果沒有, 就運用 Encapsulate Collection(封裝集合) 把它們封裝起來. 對于那些不該被其他類修改的字段, 運用Remove Setting Method(移除設(shè)值函數(shù))。找出這些取值/設(shè)值函數(shù)被其他類運用的地點. 嘗試以Move Method 把那些調(diào)用行為搬移到Data Class來. 如果無法搬移整個函數(shù), 那就運用Extract Method 產(chǎn)生一個可被搬移的函數(shù). 不久之后你就可以Hide Method(隱藏函數(shù)) 把這些取值/設(shè)值函數(shù)隱藏起來了.
1.21 Refused Bequest(被拒絕的饋贈)
定義:
被拒絕的遺贈是指:對于某個子類,它只想繼承基類的部分函數(shù)和數(shù)據(jù),不需要基類提供的全部內(nèi)容,這些不需要的內(nèi)容就成為了子類的負(fù)擔(dān)。
影響: 這種壞味道通常影響并不大,但如果子類拒絕實現(xiàn)部分接口或者基類的方法只適用于某個子類特定的方法,就會對可維護、可擴展性等造成較大影響。
改進目標(biāo): 改進不合理的繼承體系,使代碼結(jié)構(gòu)清晰、可控。
方法:
?函數(shù)/字段下移,讓超類只持有子類共享的東西[1]。
?以委托取代超類/子類。
注[1]:并不建議對所有存在“被拒絕的遺贈”的代碼都進行修改,我們經(jīng)常使用繼承復(fù)用一些行為,可以很好的應(yīng)對日常工作,所以修改的成本和收益還是需要開發(fā)者自己權(quán)衡。但是當(dāng)“被拒絕的遺贈”使開發(fā)人員困惑時,就建議及時處理掉。
1.22 Comments (過多的注釋)
首先聲明,注釋不是一種壞味道,但是我們經(jīng)常遇到一段代碼有非常長的注釋,然后也可以推導(dǎo)出注釋之所以這么長,是因為代碼很糟糕。這種情況發(fā)生的次數(shù)多了。
注釋可以幫助我們找到本章先前提到的各種壞味道。找到壞味道我們運用各種重構(gòu)去重構(gòu)之后,會發(fā)現(xiàn)注釋一斤變得多余了。因為代碼已經(jīng)說明了一切。
做法:
如果你需要注釋來解釋一塊代碼做了什么, 試試Extract Method;
如果函數(shù)已經(jīng)提煉出來,但還是需要注釋來解釋其行為,試試Rename Method
如果你需要注釋說明某些系統(tǒng)的需求規(guī)格,試試Introduce Assertion(引入斷言)。
首先,當(dāng)你感覺需要填寫撰寫注釋時,請先嘗試重構(gòu), 試著讓所有注釋都變得多余。
如果你不知道該做什么, 這才是注釋的良好運用時機 . 除了用來記錄將來的打算之外, 注釋還可以用來標(biāo)記你并無十足把握的區(qū)域. 你可以在注釋里寫下自己"為什么做某某事". 這類信息可以幫助將來的修改者, 尤其是那些健忘的家伙.
以上就是重改改善既有代碼的設(shè)計中列舉的代碼中的壞味道,希望我們開發(fā)人員在開發(fā)、迭代功能、需求、解決bug或者優(yōu)化代碼時,能夠多多思考,對壞味道多多體會的同時,能夠盡量減少這些壞味道。
注這幾篇文章中,比較復(fù)雜,有意思的重構(gòu)手法會在文章中附鏈接,相對簡單易理解的,讀者可以自行百度。