重構_改善既有的代碼設計(二)

一、重構:對軟件內部結構的一種調整,目的是在不改變軟件可觀察行爲的前提下,提升其可理解性,下降其修改爲本。編程

二、使用重構技術開發軟件時,把本身的時間分配給兩種大相徑庭的行爲:添加新功能,以及重構。添加新功能時,不該該修改既有代碼,直觀添加新功能。重構時不能再添加新功能,只管改進程序結構。須要清楚本身正在作哪一塊工做。函數

三、爲什麼重構:性能

(1)重構改進軟件設計。spa

完成一樣一件事,設計不良的程序每每須要更多代碼,這經常是由於代碼在不一樣的地方使用徹底相同的語句作一樣的事情。所以改進設計的一種重要方向就是消除重複代碼。代碼越多,正確的修改就越困難,由於有更多的代碼須要理解。若是消除重複代碼,你就能夠肯定全部事物和行爲在代碼中只表述一次,這正是優秀設計的根本。不要只爲短時間的目的。設計

(2)重構使軟件更容易理解。調試

程序猿須要考慮從此將會有另一個讀者,會來修改代碼。因此代碼須要儘可能表現出準確的功能。一開始所作的重構可能只停留在細枝末節上,隨着代碼漸趨簡潔,能夠發現一些之前看不到的設計層面的東西。若是不對代碼作這些修改,咱們也許永遠看不見它們,由於咱們的才智不足以將一切想象出來。重構能夠將咱們帶到更高的理解層次。對象

(3)重構能夠幫助找到bug。繼承

若是對代碼進行重構,咱們能夠深刻理解代碼的行爲,並恰到好處地把新的理解反饋回去。搞清楚程序結構的同時,也能幫助找到bug。重構可以幫助咱們寫出更健壯的代碼。接口

(4)重構能夠提升編程速度。進程

改善設計、提高可讀性、減小錯誤,這些都是提升質量,同時也會提升開發進度。

良好的設計是快速開發的根本。若是沒有良好的設計,或許某一段時間內,你的進展迅速,但惡劣的設計很快讓你的速度慢下來。你會把時間花在調試上面,沒法添加新功能。(深有體會啊。。。)

四、什麼時候重構:

幾乎任何狀況下我都反對專門撥出時間進行重構。在我看來,重構原本就不是意見應該特別撥出時間作的事情,重構應該隨時隨地進行。第一次作某件事時只管去作;第二次作相似的事會產生反感,但不管如何仍是能夠去作;第三次再作相似的事,你就應該重構。

(1)添加功能時重構:

重構的直接緣由每每是爲了幫助我理解須要修改的代碼——這些代碼多是別人寫的,也多是我本身寫的。不管什麼時候,只要我想理解代碼所作的事就會嘗試着衝可以。在嘗試的過程當中把代碼的結構理清,我就能夠從中理解更多的東西。另外,多是由於代碼的設計沒法幫助我輕鬆添加我所須要的特性。重構以後也能使將來添加新特性的時候,更加快速、流暢。

(2)修補錯誤時重構:

調試過程當中運用重構,多半是爲了讓代碼更具可讀性。當我看着代碼並努力理解它的時候,我用重構幫助加深本身的理解。我發現以這種程序來處理代碼,經常可以幫助我找出bug。

(3)複審代碼的重構:

不少公司都會作常規的代碼複審(表示木有。。。),由於這種活動能夠改善開發情況。這種活動有助於在開發團隊中傳播知識,也有助於讓較有經驗的開發者把知識傳遞給比較欠缺經驗的人,並幫助更多人理解大型軟件系統中的更多部分。代碼複審對於編寫清晰的代碼很是重要,個人代碼對於我來講清晰,但對於其餘人則否則。代碼複審也讓更多人有機會提出有用的建議。複審團隊必須保持精煉,最好是一個複審者搭配一個原做者,共同處理這些代碼。複審者提出修改意見,而後兩人共同判斷這些修改是否可以經過重構輕鬆實現。若是果然如此,就一塊兒動手修改。

五、爲何重構有用?

程序有兩面價值:「今天能夠爲你作什麼」和「明天能夠爲你作什麼」。大多數時候,咱們都只關注本身今天想要程序作什麼。不管是修復錯誤或者添加特性,咱們都是爲了讓程序能力更強,讓它在今天更有價值。

可是系統當下的行爲,只是整個故事的一部分,若是沒有認清這一點,你沒法長期從事編程工做。若是你爲求完成今天的任務而不擇手段,致使不可能在明天完成明天的任務,那麼最終仍是會失敗。可是,你知道本身今天須要什麼,卻不必定知道本身明天須要什麼。也許你能夠猜到明天的需求,也許吧,但確定還有些事情出乎你的意料。(Head First Design Patterns:Change is constant)

對於今天的工做,我瞭解得很充分;對於明天的工做,我瞭解得不夠充分。但若是我純粹只是爲今天工做,明天我將徹底沒法工做。

重構是一條擺脫困境的道路。若是你發現昨天的決定已經不適合今天的狀況,放心改變這個決定就是,而後你就能夠完成今天的工做了。明天回頭看今天的理解也許以爲很幼稚,那時你還能夠改變你的理解。

是什麼讓程序如此難以相與?眼下我能想起下述四個緣由,它們是:

(1)難以閱讀的程序,難以修改;

(2)輯重複的程序,難以修改;

(3)添加新行爲時須要修改已有代碼的程序,難以修改;

(4)帶複雜條件邏輯的程序,難以修改

所以,咱們但願程序:(1)容易閱讀;(2)全部邏輯都只在惟一地點指定;(3)新的改動不會危及現有行爲;(4)儘量簡單表達條件邏輯

六、間接層和重構

計算機科學是這樣一門科學:它相信全部問題均可以經過增長一個間接層來解決。

因爲軟件工程師對間接層如此醉心,你應該不會驚訝大多數重構都爲程序引入更多間接層。重構每每把大型對象拆成多個小型對象,把大型函數拆成多個小型函數。

可是,間接層是一柄雙刃劍。每次把一個東西分紅兩份,你就須要多管理一個東西。若是某個對象委託另外一個對象,後者又委託另外一個對象,程序會越加難以閱讀。

基於這個觀點,你會但願儘可能減小間接層。可是間接層有它的價值:

(1)容許邏輯共享。好比說一個子函數(對應另一個應該是主函數了)在兩個不一樣的地點被調用,或超類中的某個函數被全部子類共享(這個應該是繼承和多態了)。

(2)分開解釋意圖和實現。你能夠選擇每一個類和函數的名字,這給了你一個解釋本身意圖的機會。類或函數內部則解釋實現這個意圖的作法。若是類和函數內部又以更小單元的意圖來編寫,你所寫的代碼就能夠描述其結構中的大部分重要信息。(簡單能夠理解爲,類名應該能表現出這是一個什麼類,函數名應該能表示其功能,隨着重構,代碼塊變小,代碼的結構就慢慢清晰)

(3)隔離變化。極可能我在兩個不一樣地點使用同一個對象,其中一個地點我想改變對象行爲,但若是修改了它,我就要冒同時影響兩處的風險。爲此我作出了一個子類,並在須要修改處引用這個子類。如今,我能夠修改這個子類而沒必要承擔無心中影響另外一處的風險。

(4)封裝條件邏輯。對象有一種奇妙的機制:多態消息,能夠靈活而清晰地表達條件邏輯。將條件邏輯轉化爲消息形式(這個。。。不大理解,大家理解嗎?感受有點抽象),每每能下降代碼的重複、增長清晰度並提升彈性。


這一章講的基本上是重構原則上的知識。摘出了大半部分吧,沒有摘出來的包括

(1)須要重構的時候,怎麼跟經理說

(2)修改接口的一些想法

(3)什麼時候不該該重構

(4)重構與性能

。。。等等,感興趣的能夠去看看

相關文章
相關標籤/搜索