1、重復(fù)代碼
解決方案:
2、函數(shù)過長(zhǎng)和參數(shù)列過長(zhǎng)
修改點(diǎn):
解決方案:
3、過大的類
解決方案:提煉新的獨(dú)立類或者子類
4、參數(shù)列過長(zhǎng)
解決方案:
5、發(fā)散式變化(一個(gè)類受多種變化影響,貌似就是單一職責(zé)原則)目標(biāo):外界變化和需要修改的類一一對(duì)應(yīng)
修改點(diǎn):軟件一旦發(fā)生多種變化,但是都修改同一個(gè)類,說明此類職責(zé)重復(fù)
解決方案:找出某種特殊原因造成的所有變化,然后將它們提取到另一個(gè)類里面
6、霰彈式修改(一個(gè)變化修改多個(gè)類)目標(biāo):外界變化和需要修改的類一一對(duì)應(yīng)
修改點(diǎn):軟件一旦發(fā)生變化,造成要修改很多類
解決方案:找出某種變化引起的不同類中的眾多修改點(diǎn),將各個(gè)類中修改點(diǎn)放到一個(gè)類中
7、依戀情節(jié)
修改點(diǎn):
當(dāng)一個(gè)類的函數(shù)為了計(jì)算經(jīng)常調(diào)用另一個(gè)類的一大堆的函數(shù)時(shí)就表示出現(xiàn)了依戀情節(jié)。
1和0的世界里面出現(xiàn)了如此具有文藝氣質(zhì)的詞,那么我們就用文藝的手法去理解:你們家的女朋友經(jīng)常去找別人家的漢子時(shí),你多多少少需要知道壞了。
解決方案:
如果這段代碼完全依戀另一個(gè)類,那么將此部分出現(xiàn)依戀情節(jié)的代碼提煉成函數(shù)放到另一個(gè)類里面(這告訴我們當(dāng)一個(gè)女人完全不愛你的時(shí)候要學(xué)會(huì)放手?)
然而很多時(shí)候并非這么簡(jiǎn)單,它兩個(gè)類都有依戀呢?(然而很多時(shí)候并非這么簡(jiǎn)單,她兩個(gè)都愛呢?)
那就判斷哪個(gè)類擁有最多被此函數(shù)使用的數(shù)據(jù),然后就把此函數(shù)和那些數(shù)據(jù)擺在一起。(判斷她愛哪個(gè)的優(yōu)點(diǎn)多一點(diǎn),就讓她去找誰吧?)
難怪大家都說程序員都是好男人@_@
然而Martin大神多說了一句:
如果先提取方法將這段代碼分割成不同的數(shù)個(gè)較小的獨(dú)立函數(shù)上述步驟會(huì)簡(jiǎn)單很多。(請(qǐng)恕我直言,左腿和左手我要了,刀交給你了,你隨意?)
8、數(shù)據(jù)泥團(tuán)
修改點(diǎn):
所謂數(shù)據(jù)泥團(tuán)就是指那些經(jīng)常一起出現(xiàn)的數(shù)據(jù),比如一些經(jīng)常一起出現(xiàn)的參數(shù),舉個(gè)例子:分頁參數(shù)
解決方案:
數(shù)據(jù)泥團(tuán)應(yīng)該擁有他們自己的類,就像幾個(gè)好基友需要讓他們住在一起
9、基本類型偏執(zhí)
解決方案:
使用一些小對(duì)象比如郵編類,電話號(hào)碼類將此類數(shù)據(jù)應(yīng)用起來
使用枚舉類型將或者小對(duì)象去替代那些類型碼
10、少用Switch
解決方案:
11、平行繼承體系
修改點(diǎn):每當(dāng)你為某個(gè)類增加一個(gè)子類時(shí),必須為另外一個(gè)類增加子類,那么就有問題
解決方案:讓一個(gè)繼承體系的實(shí)例去引用另一個(gè)繼承體系
12、冗贅類
解決方案:如果某個(gè)類失去了價(jià)值,應(yīng)該將其去掉,比如父子類之間區(qū)別不大,那么可以合并,或者將其搬移到另一個(gè)類里
13、夸夸其談未來性
不要去考慮未來性,如果用不到就不值得,未來的事情就交給未來,做好現(xiàn)在的事情即可
14、令人迷惑的暫時(shí)字段
修改點(diǎn):某個(gè)實(shí)例變量?jī)H為某種特定情況而設(shè),這樣的代碼就會(huì)不易理解,因?yàn)槟銜?huì)認(rèn)為所有時(shí)候都會(huì)需要它的所有變量。
解決方案:
15、過度耦合的消息鏈
修改點(diǎn):一個(gè)對(duì)象請(qǐng)求另一個(gè)對(duì)象,然后后者再請(qǐng)求一個(gè)變量,然后后者再請(qǐng)求一個(gè)變量這就是消息鏈
解決方案:
隱藏委托,在前一個(gè)類中寫一個(gè)函數(shù)直接調(diào)用第三個(gè)類的函數(shù),即嘗試把函數(shù)鏈寫在第一個(gè)類的一個(gè)新函數(shù)中
16、中間人
修改點(diǎn):
過度運(yùn)用委托關(guān)系
解決方案:
17、狎昵關(guān)系
當(dāng)看到這兩個(gè)字的時(shí)候我查了一下字典,狎妓的狎(xia),一個(gè)比較猥瑣的字眼,當(dāng)然你不介意的話也可以稱為搞基關(guān)系.
修改點(diǎn):
搞基關(guān)系的意思是,兩個(gè)類之間花太多時(shí)間探究彼此的PRivate部分,就像兩個(gè)男人喜歡探究對(duì)方的私處一樣。
解決方案:
18、異曲同工的類
解決方案:
其實(shí)差不多就是重復(fù)代碼的問題,就是兩個(gè)做相同事情的函數(shù)或者類,唯一的區(qū)別在于,當(dāng)這兩個(gè)類差不多的情況下可以提取一個(gè)父類
來解決問題
19、不完美的庫類
修改點(diǎn):
簡(jiǎn)而言之就是別人寫的類不好用時(shí),就比如一個(gè)引用的動(dòng)態(tài)鏈接庫,你又改不了這個(gè)東西時(shí)
解決方案:
以下并不是重構(gòu)作者的解決方案:
因?yàn)檫@本書真的是太老了
對(duì)于應(yīng)用.net的我們可以考慮用一下partial類或者擴(kuò)展函數(shù)
partial類示例:
namespace 重構(gòu)測(cè)試程序{ class Program { static void Main(string[] args) { var test = new Encoding(); Console.WriteLine(test.我就是個(gè)中文函數(shù)你拿我怎樣吧()); Console.ReadKey(); } }}namespace System.Text { public partial class Encoding { public string 我就是個(gè)中文函數(shù)你拿我怎樣吧() { return "有種你打我啊"; } }}
擴(kuò)展函數(shù)示例(老實(shí)說我在實(shí)際項(xiàng)目中沒用過這玩意,這玩意雖好,但是吃螃蟹的恐懼讓我并不敢用):
namespace 重構(gòu)測(cè)試程序{ class Program { static void Main(string[] args) { var test = new StringBuilder(); Console.WriteLine(test.我叫擴(kuò)展函數(shù)("Troy123")); Console.ReadKey(); } } public static class 中文編碼類 { public static string 我叫擴(kuò)展函數(shù)(this object obj, string name)//擴(kuò)展函數(shù) { return name + "最喜歡寫測(cè)試代碼的時(shí)候用中文了"; } }}
20、純稚的數(shù)據(jù)類
修改點(diǎn):
就是說這個(gè)類擁有一些字段,并且有一些讀寫這個(gè)字段的函數(shù)
更簡(jiǎn)單的說就是不用公共字段,不要把需要隱藏的東西暴露出來(不要把你的私處暴露出來(#‵′)凸)
解決方案:
字段封裝成方法來調(diào)用(.NET的我們用屬性就好了)
特別是對(duì)于容器類的字段要控制好它的封裝,
21、被拒絕的遺贈(zèng)
修改點(diǎn):
當(dāng)子類不需要繼承父類多余的屬性和方法時(shí)
這個(gè)修改點(diǎn)在Martin看來一般并不是很嚴(yán)重,很多時(shí)候可以不去理睬,這個(gè)視具體情況而定
我的理解是,如果子類繼承多余的東西并沒有引起誤解和較差的可讀性,那么其實(shí)可以不理睬
解決方案:
22、過多的注釋
修改點(diǎn):
這里并不是說注釋不重要,而是說你這段過多的注釋可能是因?yàn)槟阌幸欢纬瑺€的代碼而導(dǎo)致你不得不寫這么多注釋
注釋除了用于標(biāo)注將來之外,更應(yīng)該用在你那些并無把握的地方,而不是為了一段超爛的但是你理解了的代碼寫一段超長(zhǎng)的注釋。
解決方案:
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注