国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

【重構(gòu)學(xué)習(xí)】02何處重構(gòu)?

2019-11-14 13:38:53
字體:
供稿:網(wǎng)友

1、重復(fù)代碼

  解決方案:

  • 重復(fù)代碼位于同一個(gè)類:提煉成新函數(shù)進(jìn)行調(diào)用
  • 重復(fù)代碼位于不同的子類:提煉成函數(shù)放進(jìn)父類
  • 重復(fù)代碼位于完全不相干的類:提煉出一個(gè)新的類,將重復(fù)代碼放進(jìn)新的類中
  • 重復(fù)代碼并非完全相同,存在些微差異性:用模版方法的設(shè)計(jì)模式解決

2、函數(shù)過長(zhǎng)和參數(shù)列過長(zhǎng)

  修改點(diǎn):

  • 有注釋的地方就可能有修改點(diǎn),因?yàn)橐粋€(gè)地方既然值得你去寫注釋,那么就已經(jīng)存在將其提煉出來的可能性,即使它只有一行代碼
  • 條件表達(dá)式和循環(huán)處:將分支邏輯和實(shí)現(xiàn)細(xì)節(jié)分離,都可以函數(shù)化。而循環(huán)可以放到單獨(dú)的一個(gè)函數(shù)里。 

  解決方案:

  • 不存在太多參數(shù)和臨時(shí)變量的情況:提煉成新函數(shù)進(jìn)行調(diào)用(有太多臨時(shí)變量和參數(shù),會(huì)導(dǎo)致提煉出來的函數(shù)可讀性可能并不會(huì)得到提升)
  • 臨時(shí)變量多:將臨時(shí)變量替換成查詢方法,再進(jìn)行提煉
  • 參數(shù)過多:參考參數(shù)列過長(zhǎng)的處理辦法
  • 依然存在很多臨時(shí)變量和參數(shù):用方法對(duì)象替代方法,簡(jiǎn)單地說搞一個(gè)類,臨時(shí)變量作為這個(gè)的字段,然后代碼提煉為里面的方法

3、過大的類

  解決方案:提煉新的獨(dú)立類或者子類

4、參數(shù)列過長(zhǎng)

  解決方案:

  • 對(duì)象替代法:將多個(gè)參數(shù)放入一個(gè)參數(shù)對(duì)象中,再進(jìn)行傳遞(不僅提高可讀性,因?yàn)閭鬟f的只是引用所以會(huì)少開辟棧空間,提高性能)
  • 函數(shù)替代法:看能否將這些參數(shù)用函數(shù)替代,簡(jiǎn)單的說就是將這些參數(shù)的計(jì)算部分放到一個(gè)函數(shù)里,返回結(jié)果再傳值

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

  解決方案:

  • 用多態(tài)來替代Switch,比如用子類去替換狀態(tài)碼,或者用狀態(tài)模式和策略模式
  • 或者用明確的函數(shù)去取代各分支,然后觀察是否能將分支去除

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ì)需要它的所有變量。

  解決方案:

  • 通過傳遞NUll參數(shù)在變量不合法的情況下傳遞NULL
  • 提煉新的對(duì)象以適應(yīng)此種特殊情況

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)系

  解決方案:

  • 移除中間人,直接和對(duì)象打交道
  • 當(dāng)函數(shù)主體和函數(shù)名的可讀性一樣清晰時(shí),將其放進(jìn)調(diào)用端
  • 用繼承替代委托

17、狎昵關(guān)系

  當(dāng)看到這兩個(gè)字的時(shí)候我查了一下字典,狎妓的狎(xia),一個(gè)比較猥瑣的字眼,當(dāng)然你不介意的話也可以稱為搞基關(guān)系.

  修改點(diǎn):

  搞基關(guān)系的意思是,兩個(gè)類之間花太多時(shí)間探究彼此的PRivate部分,就像兩個(gè)男人喜歡探究對(duì)方的私處一樣。

  解決方案:

  • 通過移動(dòng)字段和移動(dòng)方法讓兩個(gè)好基友分開(好殘忍,割雞解決的方式太可怕了
  • 將雙向關(guān)聯(lián)改為單向關(guān)聯(lián)(也就是說將其中一個(gè)變性為妹子就好了
  • 通過提取新類的方式將兩者之間的復(fù)雜關(guān)系放在一個(gè)新類里(將他們分開,讓他們都通過另一個(gè)人對(duì)話
  • 如果是父子類關(guān)系,那么應(yīng)該用委托替代繼承,讓子類不繼承父類,而把父類對(duì)象作為子類的一個(gè)屬性(......⊙﹏⊙‖∣) 

18、異曲同工的類

  解決方案:

  其實(shí)差不多就是重復(fù)代碼的問題,就是兩個(gè)做相同事情的函數(shù)或者類,唯一的區(qū)別在于,當(dāng)這兩個(gè)類差不多的情況下可以提取一個(gè)父類

  來解決問題

19、不完美的庫類

  修改點(diǎn):

  簡(jiǎn)而言之就是別人寫的類不好用時(shí),就比如一個(gè)引用的動(dòng)態(tài)鏈接庫,你又改不了這個(gè)東西時(shí)

  解決方案:

  • 添加較少函數(shù)或者應(yīng)用不普遍的情況:就是在客戶類中添加一個(gè)函數(shù),然后傳個(gè)服務(wù)類對(duì)象進(jìn)去
  • 添加較多函數(shù)或者應(yīng)用普遍的情況:就是自己再寫一個(gè)類去繼承這個(gè)不能改寫的類

  以下并不是重構(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í)可以不理睬

  解決方案:

  • 去為這個(gè)子類新建一個(gè)兄弟類,將這些不需要的方法和屬性下移到這個(gè)兄弟類
  • 如果子類繼承了饋贈(zèng),但是不愿繼承父類其他的·接口,那么可以用委托來替代繼承,可以參考狎昵關(guān)系

22、過多的注釋

  修改點(diǎn):

  這里并不是說注釋不重要,而是說你這段過多的注釋可能是因?yàn)槟阌幸欢纬瑺€的代碼而導(dǎo)致你不得不寫這么多注釋

  注釋除了用于標(biāo)注將來之外,更應(yīng)該用在你那些并無把握的地方,而不是為了一段超爛的但是你理解了的代碼寫一段超長(zhǎng)的注釋。

  解決方案:

  • 提煉函數(shù),用詳細(xì)的函數(shù)名字去表達(dá)這段代碼的意思。
  • 因?yàn)槭?a href="http://www.survivalescaperooms.com/article.asp?typeid=160">java所以Martin還給出了java的斷言去替代注釋的用法,斷言的意思就是如果條件不成立那么某段代碼就不執(zhí)行(為何我覺得如此像if,好吧這里就不深究了

 


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 遂宁市| 肇东市| 凉城县| 泌阳县| 西林县| 获嘉县| 堆龙德庆县| 普安县| 巴彦淖尔市| 封开县| 阿拉善右旗| 阿荣旗| 登封市| 岐山县| 祁阳县| 平顶山市| 蓬安县| 甘谷县| 安达市| 巴马| 雷山县| 茶陵县| 临颍县| 封丘县| 山阴县| 藁城市| 山东省| 新河县| 红安县| 临安市| 黔西县| 土默特右旗| 永修县| 长葛市| 防城港市| 潞城市| 通州市| 闵行区| 澜沧| 巴塘县| 南安市|