欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

PHP 雜談《重構(gòu)-改善既有代碼的設(shè)計》之一 重新組織你的函數(shù)

 更新時間:2012年04月09日 22:16:39   作者:  
我把我比較喜歡的和比較關(guān)注的地方寫下來和大家分享。上次我寫了篇《php 跟老大的對話》。還是有很多疑問,這書幫了我不少的忙

思維導(dǎo)圖 點擊下圖,可以看大圖。
介紹

我把我比較喜歡的和比較關(guān)注的地方寫下來和大家分享。上次我寫了篇《php 跟老大的對話》。還是有很多疑問,這書幫了我不少的忙。

如果你比較繁忙,或者懶得看文字,建議你直接看截圖,也會有很大的收獲的。你可以通過比較截圖中的代碼就能知道孰優(yōu)孰劣了。

代碼部分我為什么用圖呢?因為我經(jīng)常用手機看代碼,博客園的代碼在手機里亂七八糟的,還是看圖比較舒服。

專業(yè)術(shù)語

我們畢竟是用英文字母編碼,所以用一些英語單詞,更能顯示出我們的專業(yè)性。以下的英文單詞,你如果掌握了,與其他coder交流的時候會更直接,更專業(yè)?!麸@擺一下吧,呵呵。
“*”表示文中經(jīng)常提到的

inline:內(nèi)聯(lián)
function:函數(shù)
*method:方法
finely grained:細粒度的
rename:重命名
query:查詢
temp:臨時(temporary)——一般指臨時變量
*extract:提取——我個人更喜歡翻譯成“提煉”
*duplicate:復(fù)制
split:剖解
variable:變量
factor:因素,因子

重構(gòu)原則

一、何謂重構(gòu)?
  名詞形式:對軟件內(nèi)部結(jié)構(gòu)的一種調(diào)整,目的是在不改變軟件之可察行為前提下,提高其可理解型性,降低其修改成本。
  動詞形式:使用一系列重構(gòu)準(zhǔn)則,在不改變軟件之可察行為前提下,調(diào)整其結(jié)構(gòu)。

二、為何重構(gòu) ?
  1、經(jīng)常重構(gòu)可以讓代碼維持該有的形態(tài)。
  2、讓代碼找到合適的位置。
  3、讓軟件更易理解。
  4、可以找到bug。
  5、提高我們的編碼速度。
三、重構(gòu)的難題
  1、修改接口命名
    如果你的類中的方法是public,那么你在rename的時候,冒著很大的風(fēng)險,你不知道到底有哪些模塊在調(diào)用你的這個方法(我們經(jīng)常的做法是在整個項目下做grep操作,然后逐一看各個模塊的調(diào)用和邏輯)?!晕覀冊诰帉戭惖臅r候不管是屬性還是方法盡量做到private,避免接口開放。

  2、何時不該重構(gòu)
   ?。?)重寫所有代碼,而且現(xiàn)有代碼實在太混亂,重構(gòu)還不如重寫。
   ?。?)項目臨近結(jié)束的時候,應(yīng)該避免重構(gòu)。我們可以把重構(gòu)放到二期去解決。

代碼的壞味道

一、Duplicate Code
  1、同一個類,兩個方法含有相同表達式。
    解決方法:你可以Extract Method提煉重復(fù)代碼,然后讓這兩個方法都調(diào)用這個Extract Method。
2、兩個類,有相似的方法。
    解決方法:(1)把兩個類的方法提出來,共同構(gòu)造一個父類。
         (2)把其中一個類的方法刪除,調(diào)用另一個類的方法。
二、Long Method
  1、短函數(shù):代碼閱讀費點力氣,因為我們必須經(jīng)常轉(zhuǎn)換上下文去看看子程序做了什么。但是讓small method容易理解的真正關(guān)鍵在于一個好的名字。讀者可以通過名字了解函數(shù)的作用,根本不必去看其中寫了些什么?!缙诘木幊陶Z言中,調(diào)用方法需要額外開銷,這使得coder不愿意使用small method。但是現(xiàn)代的OO語言幾乎已經(jīng)完全免除了process內(nèi)的額外開銷(函數(shù)調(diào)用)。

  2、注釋地方提煉信號:每當(dāng)感覺需要以注釋來說明點什么的時候,我們就把需要說明的東西寫進一個獨立函數(shù)中,并以其用途命名??梢詫σ唤M或甚至短短一行代碼做這件事。——只要函數(shù)名稱能夠解釋其用戶,我們也該毫不猶豫地那么做。

"函數(shù)"理解為”做什么“或”如何做“

  3、條件式和循環(huán)常常也是提煉信號。

  4、《代碼整潔之道》的一個例子。我們可以想想!

三、Large Class

  1、Class內(nèi)數(shù)個屬性變量有相同前綴或者字尾,可使用Extract Class。

  2、Class內(nèi)并非大多數(shù)變量使用屬性變量,可使用Extract Class。
  
  3、有太多代碼,可Extract Class。

四、Long Parameter
  做成Introduce Parameter Object?!@個我不太贊同,因為我在使用別人方法的時候,我很少去看代碼實踐,更不要說去看里面都用到了對象的那些屬性或者方法,取我想要的數(shù)據(jù)了。

五、Switch Statements
  1、少用switch語句?!獑栴}在于duplication。添加新case的時候,你必須找到所有case并修改它們。
  
  2、用多態(tài)來替換它。做法:1.將switch進行Extract Method;2.MoveMethod把case里的實踐代碼放到多態(tài)性的class里。

六、 Comments
  試試用Extract Method,如果還不行,那你試試Rename Method。

當(dāng)你感覺需要撰寫注釋,請先嘗試重構(gòu),試著讓所有注釋變得多余。

  注釋一般用于將來的打算,還可以用于你并無十足把握的區(qū)域(為什么做某事)。


重新組織你的函數(shù)

  Long Method往往包含太多信息,這些信息又被錯綜復(fù)雜的邏輯掩蓋,不易鑒別。

一、Extract Method

狀況:我看見一個過長的函數(shù)或者需要一段注釋才能讓人理解用途的代碼,那么將這段代碼放進一個獨立函數(shù)中,并讓函數(shù)名稱解釋改函數(shù)的用途。

 

動機:

簡短而有良好命名的函數(shù):——finely grained

  1、復(fù)用機會大。

  2、函數(shù)讀起來像讀一系列comments。

  3、函數(shù)覆寫容易。

重點:函數(shù)長度關(guān)鍵在于函數(shù)名稱和函數(shù)本體之間的語義距離。如果提煉動作可以強化代碼的清晰度,那么就去做。

作法:

  1、創(chuàng)建新函數(shù),根據(jù)函數(shù)的意圖命名——以它“做什么”命名,而不是以它“怎樣做”命名。

    =》 即使Extract Function 非常簡單,例如只是消息或函數(shù)調(diào)用,只要新Function能夠以更好方式昭示代碼意圖,你也應(yīng)該提煉它。但如果你想不出更有意義的名稱,就別動它。

  2、將Extract的代碼從Source Function 中Move到New Function中。

二、Inline Method

  Method Body與Method Name一樣清晰易懂的時候,請Inline Method。

 

三、Inline Temp

一個臨時變量,只被一個簡單表達式賦值一次,而且賦值完也只使用了一次。——請Inline Temp

 

四、Replace Temp with Query

如果一個Temp變量,保存一個表達式,將這個表達式Extract Method?!@就是所謂的查詢式,query

 

動機:

  1、局部變量會使代碼難以提煉。

  2、臨時變量會驅(qū)使你寫出更長的代碼。如果改成query method,那么class下的method,都可以獲得這份信息?!獙⒕帉懗龈逦拇a。

  3、Replace Temp with Query往往是你運用Extract Method之前必不可少的步驟。

作法:

  1、找出只被賦值一次的臨時變量。

    =>  如果臨時變量賦值超過一次,考慮使用Split Temporary Variable將它分割成多個變量。

  2、對Temp Variable賦值的右側(cè)部分,Extract到一個獨立函數(shù)中。

           =>  將Method聲明為private,日后如果有其他class用的時候再放開它(public或protected)。

  

如果代碼組織良好,那么你往往能發(fā)現(xiàn)更有效的優(yōu)化方案?!绻阅苷娴暮茉愀猓敲捶呕厝ヒ埠苋菀?。
 
五、Introduce Explaining Variable
 
將復(fù)雜表達式中(或其中一部分)的結(jié)果放進一個臨時變量,以此變量名稱來解釋表達式用途。
 

 
動機:
  表達式復(fù)雜而且難以閱讀。在這種情況下,臨時變量可以幫助你將表達式分解為比較容易管理的形式。
  
 六、Split Temporator Variable
 
 某個臨時變量被賦值超過一次,它既不是循環(huán)變量,也不是集合變量。那么針對每次賦值,創(chuàng)造一個獨立的,對應(yīng)的臨時變量。

 

 

動機:

  1、如果臨時變量承擔(dān)多個責(zé)任,它就應(yīng)該被替換為多個臨時變量。每個變量只承擔(dān)一個責(zé)任。

  2、同一個臨時變量承擔(dān)兩件不同的事情,會令review變得糊涂。

六、Remove Assignments To Parameters
如果你的代碼對參數(shù)進行賦值,那么以一個臨時變量取代該參數(shù)的位置
 

 

七、Replace Method with Method Object

大型函數(shù)對局部變量的使用無法采用Extract Method。那么將這個Method放進一個單獨對象中,如此一來,讓局部變量成為對象的filed,然后在同一個對象中將大型函數(shù)分解為數(shù)個小型Method。

 

 

動機:

  1、將相對獨立的代碼從大型Method中Extract出來,就可以大大提高代碼的可讀性。

  2、一個Method中,局部變量泛濫成災(zāi),分解這個函數(shù)將會非常困難。

  3、Replace Method with Method Object 會將所有局部變量變成對象的值域。然后對這個新對象進行Extract Method了。

八、Substitute Algorithm
 
如果你想把某個算法替換為另一個更清晰的算法,那么將Method Body替換為另一個算法。——就是直接修改原來的Method Body。
 
動機:隨著對問題有了更多的了解,你發(fā)現(xiàn)一件事可以有更清晰的方式,就應(yīng)該以較清晰的方式取代復(fù)雜方式。

總結(jié)

這只是本書的一部分內(nèi)容,我知道會有很多的coder應(yīng)該有不同的觀點,我自己也是,有的很贊同,有的我也是不太贊同的。所以要“則其善之而從之,其不善之而改之”。

歡迎大家發(fā)表下自己的看法。

相關(guān)文章

  • PHP適配器模式Adapter?Pattern的使用介紹

    PHP適配器模式Adapter?Pattern的使用介紹

    這篇文章主要介紹了PHP適配器模式Adapter?Pattern的使用,適配器模式是一種結(jié)構(gòu)型模式,它可以將一個類的接口轉(zhuǎn)換成客戶端所期望的接口,從而使原本不兼容的類能夠一起工作
    2023-03-03
  • php動態(tài)添加url查詢參數(shù)的方法

    php動態(tài)添加url查詢參數(shù)的方法

    這篇文章主要介紹了php動態(tài)添加url查詢參數(shù)的方法,涉及php通過正則替換操作URL的技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-04-04
  • php實現(xiàn)動態(tài)口令認證的示例代碼

    php實現(xiàn)動態(tài)口令認證的示例代碼

    這篇文章主要為大家詳細介紹了php實現(xiàn)動態(tài)口令認證的相關(guān)知識,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-02-02
  • 淺析PHP中Collection 類的設(shè)計

    淺析PHP中Collection 類的設(shè)計

    本篇文章是對PHP中Collection 類進行了詳細的分析介紹,需要的朋友參考下
    2013-06-06
  • PHP依賴注入(DI)和控制反轉(zhuǎn)(IoC)詳解

    PHP依賴注入(DI)和控制反轉(zhuǎn)(IoC)詳解

    這篇文章主要介紹了PHP依賴注入(DI)和控制反轉(zhuǎn)(IoC)的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • 淺談php處理后端&接口訪問超時的解決方法

    淺談php處理后端&接口訪問超時的解決方法

    下面小編就為大家?guī)硪黄獪\談php處理后端&接口訪問超時的解決方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-10-10
  • PHP+redis實現(xiàn)的悲觀鎖機制示例

    PHP+redis實現(xiàn)的悲觀鎖機制示例

    這篇文章主要介紹了PHP+redis實現(xiàn)的悲觀鎖機制,簡單介紹了redis鎖機制與樂觀鎖、悲觀鎖等概念,并結(jié)合實例形式分析了php+redis實現(xiàn)悲觀鎖相關(guān)操作技巧,需要的朋友可以參考下
    2018-06-06
  • php中iconv函數(shù)使用方法

    php中iconv函數(shù)使用方法

    最近在做一個程序,需要用到iconv函數(shù)把抓取來過的utf-8編碼的頁面轉(zhuǎn)成gb2312, 發(fā)現(xiàn)只有用iconv函數(shù)把抓取過來的數(shù)據(jù)一轉(zhuǎn)碼數(shù)據(jù)就會無緣無故的少一些。
    2008-05-05
  • MySQL GBK→UTF-8編碼轉(zhuǎn)換

    MySQL GBK→UTF-8編碼轉(zhuǎn)換

    MySQL GBK→UTF-8編碼轉(zhuǎn)換...
    2007-05-05
  • PHP使用swoole編寫簡單的echo服務(wù)器示例

    PHP使用swoole編寫簡單的echo服務(wù)器示例

    這篇文章主要介紹了PHP使用swoole編寫簡單的echo服務(wù)器,結(jié)合實例形式分析了基于swoole的echo服務(wù)器客戶端與服務(wù)器端相關(guān)實現(xiàn)技巧及操作注意事項,需要的朋友可以參考下
    2020-03-03

最新評論