當一個對象方法什么都沒干時

jopen 10年前發布 | 5K 次閱讀 對象

當一個對象方法什么都沒干時

本文作者介紹

<div class="author_name"> 
 <p>Michael Feathers</p>

</div>

<div class="author_desc"> 
 <p>Michael Feathers是Object Mentor International公司的技術顧問。他的工作不僅是技術開發,他還參與對世界各地技術團隊進行培訓、指導等工作。他曾開發了將JUnit遷移到 C++的CppUnit的初始部分,還有FitCpp——一個C++版的FIT基礎測試框架。他是《<a href="/misc/goto?guid=4958546137902434749">Working Effectively with Legacy Code</a>》一書的作者。</p>

</div>

</div>

重構的方式千差萬別。當在分析一個很大的方法時,我會首先看一下它的整體結構,心里對如何分解它有了一個初步的感覺。里面的條件判斷代碼塊通常都會是我認為有問題、可以入手的地方。

    if (...) {       ...     }

當看到有一個像這樣的if語句后,我知道我面臨著選擇。我可以 提取這個if語句以及和它相關的代碼塊到一個新方法里,或者我只提取相關代碼塊。我并不知道這樣或那樣做哪一種更好——這要根據上下文來判斷。有時候這個 條件語句非常重要,有必要重點突出它,而另一些時候,這些if語句和它的代碼塊可以干凈的提取出去,使得調用它的程序的顯得更整潔干凈。但是,我們如何調 用這個提取出去的方法呢?

讓我來看看一個實際例子:

    if (alarmEnabled) {       
        Alarm alarm = new Alarm();       
            ... 
              ...       
        alarm.sound();    
    }

我們可以把整個if語句和它的代碼塊提取到一個叫做soundAlarm的方法里。

    soundAlarm();
<p>這樣好嗎?</p>

<p>大多數人最初的反應會說:現在的這塊代碼有時會說謊。它告訴我們它將要響起警報,但有時候它并不響。通常,如果有這樣說謊的代碼不是一件好事,所以,選擇另外一種重構策略可能更好:</p>

<div class="highlight lazy "> 
 <pre>  <span class="k lazy ">if</span> <span class="p lazy ">(</span><span class="n lazy ">alarmEnabled</span><span class="p lazy ">)</span> <span class="p lazy ">{</span>     

        soundAlarm();
    }</pre> </div>

<p>但是,這樣看起來并不像之前那樣干凈。</p>

<p>這 種兩難抉擇讓我想起了Null對象模式。Null對象模式就是一種經常會讓人感覺代碼在說謊的另一個例子。在主調代碼里,我們看到有消息發送到一個對象, 但讓人震驚的是,我們發現相應的動作并沒有發生。但并不是所有的人都會有這種感覺。我所在的這個團隊里大量的使用了Null對象模式,我們對代碼的理解有 這樣的共識:當你告訴一個對象做X時,有時候它并不去做——發送執行X的消息意味著有時X事件并不一定會發生。這要由這個對象決定。</p>

<p>我的直覺告訴我,這沒什么,但你需要理解為什么會這樣,這是十分重要的——這是一個內部的理解問題。</p>

<p>如果說多態有任何意義,它至少在說對象是自己管理自己的。我們給它發送一個消息,這是由它來決定應該去做什么。這是面向對象的核心,也是 Alan Kay 最初的對對象的認識之一——消息只是它們的信息傳遞。這種觀點在如今并不占主導地位。</p>

<p>當我非常想讓這種提取變的更易懂時,我通常有兩種策略——使用一種意指一個事件的名字,或泛化這個操作。在這種情況下,我會選擇使用一個事件風格的過去式的名字。</p>

<div class="highlight lazy "> 
 <pre>   <span class="n lazy ">intruderDetected</span><span class="p lazy ">();//入侵檢測</span></pre> 
</div>

<p>這種事件風格的命名方式的好處是,它強調了事件條件,而不是動作。現在,我們可以將任何想要的東西都放到<code>intruderDetected</code>方法里。</p>

<p>我們還可以選擇去泛化這個操作。相對于說我們要想起警報,我們可以換成說我們要向世界通知一個關于我們的狀態的信息。</p>

<div class="highlight lazy "> 
 <pre>  <span class="n lazy ">performNotifications</span><span class="p lazy ">();//執行通知</span></pre> 
</div>

<p>如果使用一個像<code>performNotifications</code>這樣的名字,我就能使事情變得抽象。這里的通知是一個還是多個并不重要。關鍵是,主調程序觸發這個動作,但不意味著動作沒有發生就可以解釋成在撒謊。</p>

<p>盡管這樣,我仍然疑惑,我們是否應該永遠不要相信一個顯示它肯定將會做某事的方法名?</p>

<p>如果它沒有做,我們可以認為它在撒謊嗎?</p>

<p><br />

[英文原文:When A Method Can Do Nothing ]
來自: 外刊IT評論 http://www.aqee.net/ </p>

</div>

</div>

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!