• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆 - 181  文章 - 15  trackbacks - 0
            <2009年5月>
            262728293012
            3456789
            10111213141516
            17181920212223
            24252627282930
            31123456

            常用鏈接

            留言簿(1)

            隨筆分類

            隨筆檔案

            My Tech blog

            搜索

            •  

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            現(xiàn)在回到重構(gòu)--改善既有代碼的設(shè)計(jì)這本書。
            3.4Long Parameter List(過長(zhǎng)參數(shù)列)
            如果“向既有對(duì)象發(fā)出一條請(qǐng)求”就可以取得原本位于參數(shù)列上的一份數(shù)據(jù),那么你應(yīng)該激活重構(gòu)準(zhǔn)則Replace Parameter with Method。上述的既有對(duì)象可能是函數(shù)所屬class內(nèi)的一個(gè)值域,也可能是另一個(gè)參數(shù)。你還可以用 Preserve Whole Object將來自同一對(duì)象的一堆數(shù)據(jù)收藏起來,并以該對(duì)象替換它們。如果某些數(shù)據(jù)缺乏合理的對(duì)象歸屬,可使用Introduce Parameter Object為它們制造出一個(gè)“參數(shù)對(duì)象”。

            Replace Parameter with Methods(以函數(shù)取代參數(shù))
            對(duì)象調(diào)用某個(gè)函數(shù),并將結(jié)果作為參數(shù),傳遞給另外一個(gè)函數(shù)。而接受該參數(shù)的函數(shù)也可以(也有能力)調(diào)用前一個(gè)函數(shù)。
            動(dòng)機(jī)
            如果函數(shù)可以通過其它途徑(而非參數(shù)列)獲得參數(shù)值,那么它就不應(yīng)該通過參數(shù)取得該值。
            縮減參數(shù)列的辦法之一就是,看看“參數(shù)接受端”是否可以通過“與調(diào)用端相同的計(jì)算”來取得參數(shù)攜帶值。如果調(diào)用端通過“其所屬對(duì)象內(nèi)部的另一個(gè)函數(shù)”來計(jì)算參數(shù),并在計(jì)算過程中“未曾飲用調(diào)用端的其它參數(shù)”,那么你就應(yīng)該將這個(gè)計(jì)算過程轉(zhuǎn)移到被調(diào)用端內(nèi),從而除去該項(xiàng)參數(shù)。如果你所調(diào)用的函數(shù)隸屬另一對(duì)象,而該對(duì)象擁有一個(gè)reference指向調(diào)用端所屬對(duì)象,前面所說的這些也同樣適用。
            作法
            1、如果有必要,將參數(shù)的計(jì)算過程提煉到一個(gè)獨(dú)立函數(shù)中。
            2、將函數(shù)本體內(nèi)“對(duì)該參數(shù)的引用”替換為對(duì)“新函數(shù)的引用”。
            3、每次替換后,修改并測(cè)試。
            4、全部替換完成后,適用Remove Parameter將該參數(shù)去掉。


            思考:
            確實(shí)從實(shí)踐角度講,上面這種方法是一種很實(shí)用的重構(gòu)方法。確實(shí)是縮減了函數(shù)的參數(shù)個(gè)數(shù),并隱藏了一些中間結(jié)果。但是我認(rèn)為,在應(yīng)用這個(gè)方法的時(shí)候,還應(yīng)當(dāng)考慮這樣兩個(gè)問題:
            1、當(dāng)中間函數(shù)(方法)被隱藏的時(shí)候,以這個(gè)中間函數(shù)的返回值為參數(shù)的那個(gè)函數(shù)名還能夠表述自己的用途嗎?
            2、被修改的那個(gè)函數(shù)所處的具體語境是什么。因?yàn)樵诿嫦驅(qū)ο缶幊痰臅r(shí)代,單獨(dú)去考慮一個(gè)函數(shù)的情況是很少的。確保這個(gè)函數(shù)是否處在正確的位置上(如是否處在正確的類中)是必要的。



            此間存在一個(gè)重要的例外。有時(shí)候你明顯不希望造成“被調(diào)用之對(duì)象”與“較大對(duì)象”間的某種依存關(guān)系。這時(shí)候?qū)?shù)據(jù)從對(duì)象拆解出來單獨(dú)作為參數(shù),也很合情合理。但是請(qǐng)注意其所引發(fā)的代價(jià)。如果參數(shù)列太長(zhǎng)或變化太頻繁,你就需要重新考慮自己的依存結(jié)構(gòu)了。

             Introduce Parameter Object(引入?yún)?shù)對(duì)象)
            某些參數(shù)總是很自然的同時(shí)出現(xiàn),以一個(gè)對(duì)象取代這些參數(shù)。
            你常會(huì)看到特定的一組參數(shù)總是一起被傳遞。可能有好幾個(gè)函數(shù)都使用這一組參數(shù),這些函數(shù)可能隸屬同一個(gè)class,也可能隸屬不同的classes。這樣一組參數(shù)就是所謂的Data Clump(數(shù)據(jù)泥團(tuán))。我們可以運(yùn)用一個(gè)對(duì)象包裝所有這些數(shù)據(jù),再以該對(duì)象取代它們。
            作法:
            1、新建一個(gè)class,用以表現(xiàn)你想替換的一組參數(shù)。將這個(gè)class設(shè)為不可變的(不可被修改的,immutable)。
            2、編譯。
            3、針對(duì)使用該組參數(shù)的所有函數(shù),實(shí)施Add Parameter,以上述新建class之實(shí)體對(duì)象作為新添參數(shù),并將此一參數(shù)值設(shè)為null。
            4、對(duì)于Data Clump(數(shù)據(jù)泥團(tuán))中的每一項(xiàng)(在此均為參數(shù)),從函數(shù)簽名式中移除之,并修改調(diào)用端和函數(shù)本體,令他們都改而通過“新建的參數(shù)對(duì)象” 取得該值。
            5、每除去一個(gè)參數(shù),編譯并測(cè)試。
            6、將原先的參數(shù)全部除去之后,觀察有無適當(dāng)函數(shù)可以運(yùn)用Move Method搬移到參數(shù)對(duì)象中。


            思考:
            現(xiàn)在我有一個(gè)函數(shù)f,函數(shù)定義如下:
            public string f(int i,int j,string s)
            {
               int newValue=i+j;
               string result=s+":"+newValue.ToString();
               return result;
            }
            現(xiàn)在我把這三個(gè)參數(shù)轉(zhuǎn)化為類對(duì)象,類名定義為MyParameter
            public class MyParameter
                {
                    
            int _i;

                    
            public int I
                    {
                        
            get { return _i; }
                        
            set { _i = value; }
                    }
                    
            int _j;

                    
            public int J
                    {
                        
            get { return _j; }
                        
            set { _j = value; }
                    }
                    
            string _s;

                    
            public string S
                    {
                        
            get { return _s; }
                        
            set { _s = value; }
                    }
                    
            public MyParameter(int i, int j, stirng s)
                    {
                        _i 
            = i;
                        _j 
            = j;
                        _s 
            = s;
                    }

                }

            然后再我的代碼中這樣寫:
            f(new MyParameter(3,2,"Result"));

            發(fā)現(xiàn)什么問題了嗎?
            1、好像參數(shù)并沒有減少,只不過是移動(dòng)到了構(gòu)造函數(shù)中;
            2、你從f參數(shù)中將會(huì)看不出f中到底需要什么東西(如果參數(shù)名稱體現(xiàn)了參數(shù)的用途的話)。
            這說明:
            1、雖然這是經(jīng)典的重構(gòu)方法,但是不能濫用,在使用的時(shí)候要謹(jǐn)慎考慮場(chǎng)景是否合適。
            2、注意TDA原理,不要刻意產(chǎn)生太多的中間對(duì)象。
            3、參數(shù)不能隨便合并或隱去,要特別注意領(lǐng)域模型,要切合領(lǐng)域模型所表述的意圖。
            我個(gè)人認(rèn)為可以應(yīng)用的場(chǎng)景:
            就是文中所說的DataRange,即適合于被轉(zhuǎn)換為參數(shù)對(duì)象的參數(shù)列具有通用的含義,并且概念層次比較低。


             

            posted on 2007-07-10 22:16 littlegai 閱讀(275) 評(píng)論(0)  編輯 收藏 引用 所屬分類: 我的讀書筆記
            欧美日韩久久中文字幕| 9久久9久久精品| 99久久精品九九亚洲精品| 人妻无码αv中文字幕久久琪琪布 人妻无码久久一区二区三区免费 人妻无码中文久久久久专区 | 精品精品国产自在久久高清| 久久久久免费精品国产| 亚洲人AV永久一区二区三区久久 | 亚洲精品无码久久久久sm| 日韩美女18网站久久精品| 久久久久亚洲av毛片大| 久久一区二区免费播放| 手机看片久久高清国产日韩| 国产精品久久久久免费a∨| 国产精品久久久香蕉| 久久亚洲AV成人出白浆无码国产| 久久精品国产2020| 久久夜色精品国产噜噜亚洲AV| 久久婷婷五月综合色奶水99啪 | 国产精品久久久久乳精品爆| 国内精品欧美久久精品| 久久综合久久综合亚洲| 一本色道久久88—综合亚洲精品 | 久久久久久久久久久| 久久久久久久亚洲Av无码| 91精品国产91久久久久福利| 国产精品va久久久久久久| 久久久久久国产精品无码下载| 人妻无码久久精品| 久久国产精品一国产精品金尊| 99久久无码一区人妻| 久久久久无码专区亚洲av| 狠狠色噜噜色狠狠狠综合久久| 国产精品久久久久久影院| 区亚洲欧美一级久久精品亚洲精品成人网久久久久 | 国产美女久久精品香蕉69| 国内精品久久久久久久影视麻豆| 18禁黄久久久AAA片| 中文字幕亚洲综合久久| 久久免费看黄a级毛片| 久久青青草原精品影院| 久久久久久精品免费看SSS |