《重構(gòu):改善既有代碼的設(shè)計(jì)》 讀書(shū)筆記 第二章
第二章 重構(gòu)的原則
2.1 何謂重構(gòu)
重構(gòu)分為了動(dòng)詞和名詞兩種意義。
重構(gòu)(名詞):對(duì)軟件內(nèi)部結(jié)構(gòu)的一種調(diào)整,目的是不改變軟件可觀察行為的前提下,提高其可理解性,降低修改成本。
(問(wèn)題來(lái)了,重構(gòu)真的降低了可理解性嗎)
重構(gòu)(動(dòng)詞):使用一系列重構(gòu)首發(fā),在不改變軟件可觀察行為的前提下,調(diào)整其結(jié)構(gòu)。
重構(gòu)和代碼清理的區(qū)別是:重構(gòu)的關(guān)鍵在于用大量且微小,保證軟件行為的步驟,一步一步達(dá)到大規(guī)模的修改。每個(gè)單獨(dú)的重構(gòu)要么很小,要么由若干小步驟組合而成。
(問(wèn)題來(lái)了,我換一個(gè)代碼架構(gòu)重寫(xiě),這個(gè)過(guò)程算重構(gòu)嗎?從作者的定義來(lái)看,這并不算重構(gòu),叫做“結(jié)構(gòu)調(diào)整”)
如果有人說(shuō)他們的代碼在重構(gòu)過(guò)程中有一兩天時(shí)間不可用,基本上可以確定,他們做的事不是重構(gòu)
重構(gòu)并不等同于性能優(yōu)化,重構(gòu)理論上不會(huì)帶來(lái)任何的性能優(yōu)化,可能會(huì)變快,也可能會(huì)變慢。性能優(yōu)化的目標(biāo)只是使得代碼運(yùn)行的更快,但可能會(huì)使得代碼變得更難理解。
2.2 兩頂帽子
這里作者指的兩頂帽子,分別是重構(gòu),和添加新功能。
重構(gòu):不再添加新功能,且不加任何的測(cè)試。
添加功能:添加功能,添加測(cè)試。
在編寫(xiě)程序的過(guò)程中,你可能會(huì)隨時(shí)的切換這兩種狀態(tài),但是你要知道,你什么時(shí)候戴的是什么帽子。
2.3 為何重構(gòu)
重構(gòu)可以改變軟件的設(shè)計(jì)
如果沒(méi)有重構(gòu),程序的內(nèi)部設(shè)計(jì)會(huì)逐漸腐敗變質(zhì)。因?yàn)楫?dāng)人們只為了短期目的而修改代碼的時(shí)候,他們經(jīng)常會(huì)沒(méi)有完全理解架構(gòu)的整體設(shè)計(jì),于是代碼就逐漸失去了自己的結(jié)構(gòu)。設(shè)計(jì)就會(huì)腐敗。
設(shè)計(jì)欠佳的程序修改起來(lái),成本會(huì)很大。
(我個(gè)人覺(jué)得,目前國(guó)內(nèi)的編碼環(huán)境,很少有人能夠愿意抽出時(shí)間來(lái)交給大家來(lái)進(jìn)行重構(gòu),大家都只會(huì)提出一些短期目標(biāo),自然而然代碼就越來(lái)越shi了。代碼好不好看,只能取決于寫(xiě)代碼的這個(gè)人的個(gè)人節(jié)操了。)
重構(gòu)使軟件更容易理解
計(jì)算機(jī)根本不在乎你代碼的可讀性,但是幾個(gè)月后來(lái)維護(hù)這個(gè)代碼的程序員在乎。
重構(gòu)可以幫助找到bug
因?yàn)槟阒貥?gòu),你就會(huì)去讀代碼,然后你就會(huì)發(fā)現(xiàn)bug。
(有時(shí)候重構(gòu)也會(huì)引入bug,但我覺(jué)得bug這個(gè)東西應(yīng)該由測(cè)試來(lái)保證,這個(gè)不算是重構(gòu)的有點(diǎn))
重構(gòu)提高編程速度
內(nèi)部質(zhì)量良好的軟件可以讓我們很容易就知道怎么去修改,在哪兒修改。
2.4 何時(shí)重構(gòu)
三次法則:第一次做這件事情,那就只管去做;第二次做類似的失去,你還是可以去做;第三次遇到這件事情,你就應(yīng)該去重構(gòu)它。
預(yù)備性重構(gòu)
重構(gòu)的最佳時(shí)機(jī)就是在添加新功能之前。
幫助理解的重構(gòu):使代碼更易懂
如果你覺(jué)得這個(gè)代碼看不懂,就應(yīng)該重構(gòu)它。
撿垃圾式重構(gòu)
如果我發(fā)現(xiàn)了垃圾代碼,我就應(yīng)該重構(gòu)它;但是重構(gòu)的優(yōu)先級(jí)并沒(méi)有新增功能的優(yōu)先級(jí)高。
有計(jì)劃的重構(gòu)和見(jiàn)機(jī)行事的重構(gòu)
重構(gòu)并不是一件與編程割裂的行為,你不需要專門安排時(shí)間來(lái)進(jìn)行重構(gòu)。重構(gòu)是在做某些事情的過(guò)程中自然而然的發(fā)生的。
但是有計(jì)劃的重構(gòu)并不是沒(méi)有意義的,但大部分重構(gòu)應(yīng)該是不起眼且見(jiàn)機(jī)行事的。
骯臟的代碼必須重構(gòu),但漂亮的代碼也需要重構(gòu)。
(這個(gè)我不太茍同,我不知道漂亮的定義是什么,我覺(jué)得一個(gè)代碼可讀性好,且容易修改,那么他就是一個(gè)漂亮的代碼)
每次要修改的時(shí)候,首先令修改很容易,再進(jìn)行這次容易的修改。
長(zhǎng)期重構(gòu)
大部分的重構(gòu)幾分鐘,幾個(gè)小時(shí)就能搞定。但是部分重構(gòu)需要幾個(gè)星期,但是不推薦讓一支團(tuán)隊(duì)專門負(fù)責(zé)做重構(gòu)。建議讓大家逐步的遷移過(guò)去,這樣做的好處是重構(gòu)不會(huì)破壞代碼,每次進(jìn)行小的改動(dòng)后,整個(gè)系統(tǒng)仍然照常工作。例如,如果想替換掉一個(gè)正在使用的庫(kù),可以先引入一層新的抽象,使其兼容新舊兩個(gè)庫(kù)的接口。一旦調(diào)用方已經(jīng)完全改為使用這層抽象,替換下面的庫(kù)就會(huì)容易得多。
這個(gè)策略叫做 “Branch By Abstraction[mf-bba]”
(強(qiáng)烈贊同!!!!!重寫(xiě)整個(gè)架構(gòu),然后打算無(wú)損替換過(guò)去,這種行為是真的傻逼。先立個(gè)flag,我這輩子不會(huì)干第二次這種事情了。)
code review 的時(shí)候重構(gòu)
如果說(shuō),在進(jìn)行cr的時(shí)候,寫(xiě)代碼的人能夠和審核代碼的人在一起,效果會(huì)非常好。
這個(gè)叫做結(jié)對(duì)編程。
怎么對(duì)經(jīng)理說(shuō)
如果經(jīng)理不懂技術(shù),你就別和經(jīng)理說(shuō)。
如果懂技術(shù),直說(shuō)就行。
(建議默認(rèn)經(jīng)理不懂技術(shù)比較好,反正經(jīng)理不care你究竟是怎么寫(xiě)的代碼,他們只在乎結(jié)果而已。)
何時(shí)不應(yīng)該重構(gòu)
只有在我需要理解其工作原理的時(shí)候,我才需要去重構(gòu)它,否則對(duì)于我而言是沒(méi)有價(jià)值的。
另外一種情況是,重寫(xiě)比重構(gòu)更簡(jiǎn)單。
重構(gòu)的挑戰(zhàn)
重構(gòu)是有挑戰(zhàn)的。
延緩新功能的開(kāi)發(fā)
重構(gòu)的唯一目的是讓我們開(kāi)發(fā)更快,用更少的工作量創(chuàng)造更大的價(jià)值。
重構(gòu)需要花費(fèi)時(shí)間,如果添加功能非常小,你可以先把功能加上,再進(jìn)行重構(gòu),這個(gè)需要程序員的專業(yè)判斷。
(你就是hxd?)
從較多的情況而言,重構(gòu)不足的情況遠(yuǎn)大于重構(gòu)過(guò)度的情況,所以絕大多數(shù)人應(yīng)該嘗試多做重構(gòu)。代碼庫(kù)的健康與否,到底會(huì)對(duì)生產(chǎn)率造成多大的影響,很多人可能說(shuō)不出來(lái),因?yàn)樗麄儧](méi)有太多在健康的代碼庫(kù)上工作的經(jīng)歷————輕松地把現(xiàn)有代碼組合配置,快速構(gòu)造出復(fù)雜的新功能,這種強(qiáng)大的開(kāi)發(fā)方式他們沒(méi)有體驗(yàn)過(guò)。
如果你是leader,你應(yīng)該向團(tuán)隊(duì)表示,你是重視重構(gòu)的,對(duì)于缺乏重構(gòu)經(jīng)驗(yàn)的年輕人要有意的知道,才能幫助他們加速經(jīng)驗(yàn)的積累。
重構(gòu)并不需要使得代碼變得很好快,而是使得代碼能夠添加功能更快,修復(fù)bug更快。重構(gòu)提高的是經(jīng)濟(jì)利益。
代碼的所有權(quán)
推薦團(tuán)隊(duì)所有制,讓大家擁有更多的權(quán)限。
分支
特性分支存在的時(shí)間越短越好,應(yīng)該頻繁的從master同步代碼。
測(cè)試
你應(yīng)該使得你的代碼是自測(cè)試的,這樣就會(huì)使得能夠快速發(fā)現(xiàn)錯(cuò)誤。
有人會(huì)覺(jué)得滿足自測(cè)試的代碼,這個(gè)對(duì)團(tuán)隊(duì)的要求會(huì)很高。但是從作者的角度而言,團(tuán)隊(duì)投入時(shí)間和精力在測(cè)試上的收益絕對(duì)是劃算的。
(國(guó)內(nèi)就別想了,上線前能肉眼看一下log是否符合預(yù)期就算不錯(cuò)了。。。更別說(shuō)自測(cè)試了)
遺留代碼
遺留代碼的特征是,無(wú)測(cè)試,復(fù)雜,且代碼是別人的。
建議再買一本《修改代碼的藝術(shù)》書(shū)來(lái)讀。
數(shù)據(jù)庫(kù)的修改
假設(shè)你要改一個(gè)字段的名,正確的做法是新建一列,然后雙寫(xiě),直到測(cè)試完成后,再刪掉之前的那列。
2.6 重構(gòu)、架構(gòu)和YAGNI
在很久之前,有人會(huì)說(shuō),在開(kāi)始寫(xiě)代碼的時(shí)候,你就應(yīng)該設(shè)計(jì)好。
但實(shí)際上,做好這個(gè)的前提是,你在寫(xiě)軟件前就已經(jīng)充分理解了未來(lái)可能的需求,但實(shí)際上這個(gè)假設(shè)是不切實(shí)際的。
以前的做法是應(yīng)該增加靈活性機(jī)制,給這個(gè)函數(shù)增加很多個(gè)參數(shù),使得函數(shù)更加通用。
但有了重構(gòu)技術(shù),與其猜測(cè)未來(lái)需要什么技術(shù),更應(yīng)該只在乎當(dāng)前的需求構(gòu)造軟件。隨著用戶需求的增加,我再進(jìn)行重構(gòu)。
這種東西叫做YAGNI,you aren't going to need it. 你不會(huì)需要他的~
2.7 重構(gòu)與軟件開(kāi)發(fā)過(guò)程
極限編程的三個(gè)要點(diǎn):自測(cè)試代碼,持續(xù)繼承,重構(gòu)。
在這三大核心實(shí)踐的基礎(chǔ)上,才談得上敏捷開(kāi)發(fā)。這樣才可以做到一天多次的發(fā)布,且每次發(fā)布都是高質(zhì)量可用的。
2.8 重構(gòu)與性能
重構(gòu)并不會(huì)優(yōu)化時(shí)間,但是會(huì)使得代碼可以調(diào)優(yōu)。你的做法是先寫(xiě)出調(diào)優(yōu)的軟件,然后再調(diào)優(yōu)它以求獲取更加足夠的速度。
性能的優(yōu)化請(qǐng)不要靠想像,應(yīng)該由數(shù)據(jù),圖表來(lái)證明。
作者的做法是,做好監(jiān)控,在實(shí)現(xiàn)功能期間并不在乎性能,在真正在乎性能的時(shí)候,再專門的去優(yōu)化性能。
2.9 重構(gòu)的起源
這句話全是廢話
2.10 自動(dòng)化重構(gòu)
JB系列套件很牛逼。

浙公網(wǎng)安備 33010602011771號(hào)