難以通過(guò)重構(gòu)手法完成的設(shè)計(jì)改動(dòng)
比如說(shuō)在一個(gè)項(xiàng)目中,我們很難(但還是有可能)將“無(wú)安全需求情況下構(gòu)造起來(lái)的系統(tǒng)”重構(gòu)為“安全性良好的系統(tǒng)”。
這種情況下我的辦法就是“先想象重構(gòu)的情況”。考慮候選設(shè)計(jì)方案時(shí),我會(huì)問(wèn)自己:將某個(gè)設(shè)計(jì)重構(gòu)為另一個(gè)設(shè)計(jì)的難度有多大? 如果看上去很簡(jiǎn)單,我就不用擔(dān)心選擇是否得當(dāng),于是我就會(huì)選擇最簡(jiǎn)單的設(shè)計(jì),哪怕它不能覆蓋所有潛在需求也沒(méi)關(guān)系。但如果預(yù)先看不出簡(jiǎn)單的重構(gòu)辦法,我就會(huì)在設(shè)計(jì)上投入更多力氣。
何時(shí)不該重構(gòu)?
重寫(而非重構(gòu))的一個(gè)清楚的訊號(hào)就是:現(xiàn)有代碼根本不能正常工作。你可能只是試著做點(diǎn)測(cè)試,然后就發(fā)現(xiàn)代碼中滿是錯(cuò)誤,根本無(wú)法穩(wěn)定運(yùn)作。記住,重構(gòu)之前,代碼必須起碼能夠在大部分情況下正常運(yùn)作。
另外,如果項(xiàng)目自己已近最后期限,你也應(yīng)該避免重構(gòu)。在此時(shí)機(jī),從重構(gòu)過(guò)程中贏得的生產(chǎn)力只有在最后期限過(guò)后才能體現(xiàn)出來(lái),而那個(gè)時(shí)候已經(jīng)時(shí)不我予。
Wrad Cunningharn的看法:未完成的重構(gòu)工作是“債務(wù)”。過(guò)于復(fù)雜的代碼所造成的維護(hù)和擴(kuò)展的額外開(kāi)銷,就是利息。你可以承受一定程度的利息,但如果利息太高你就會(huì)被壓垮。把債務(wù)管理好是很重要的,你應(yīng)該通過(guò)重構(gòu)來(lái)償還部分債務(wù)。
重構(gòu)與設(shè)計(jì)
Alistair Cockburn:有了設(shè)計(jì),我可以思考更快,但是其中充滿小漏洞。
有一種觀點(diǎn)認(rèn)為:重構(gòu)可以成為“預(yù)先設(shè)計(jì)”的替代品。這意思是你根本不必做任何設(shè)計(jì),只管按照最初想法開(kāi)始編碼,讓代碼有效運(yùn)作,然后再將它重構(gòu)成型。極限編程的支持者極力提倡這種辦法。
但這不是最有效的途徑。極限編程的愛(ài)好者們也會(huì)進(jìn)行預(yù)先設(shè)計(jì)。他們會(huì)使用CRC卡或類似的東西來(lái)檢驗(yàn)各種不同的想法,然后才得到第一個(gè)可被接受的解決方案,然后才開(kāi)始編碼,然后才能重構(gòu)。關(guān)鍵在于:重構(gòu)改變了“預(yù)先設(shè)計(jì)”的角色。如果沒(méi)有重構(gòu),就必須保證“預(yù)先設(shè)計(jì)”的正確無(wú)誤,這個(gè)壓力太大了。
在可以重構(gòu)的前提下,你只需要得到一個(gè)足夠合理的解決方案就夠了。
如果你在預(yù)先設(shè)計(jì)時(shí)在所有有可能出現(xiàn)變化的地方都建立起靈活性,卻在最后發(fā)現(xiàn)這些靈活性都毫無(wú)必要,這才是最大的失敗。你知道,這其中肯定有些靈活性的確派不上用場(chǎng),但你卻無(wú)法預(yù)測(cè)到底哪些派不上用場(chǎng)。
而有了重構(gòu),則只需要考慮:把一個(gè)簡(jiǎn)單的解決方案重構(gòu)成這個(gè)靈活的解決方案有多大難度?如果答案是“相當(dāng)容易”,那么你就只需實(shí)現(xiàn)目前的簡(jiǎn)單方案就可以了。
重構(gòu)與性能
雖然重構(gòu)必然會(huì)使軟件運(yùn)行更慢,但它也使軟件的性能優(yōu)化更易進(jìn)行。除了對(duì)性能有嚴(yán)格要求的實(shí)時(shí)系統(tǒng),其他任
何情況下“編寫快速軟件”的秘密就是:首先寫出可調(diào)軟件,然后調(diào)整它以求獲得足夠速度。
編寫快速軟件的方法:
1、時(shí)間預(yù)算法。
為每個(gè)組件分配資源(包括時(shí)間資源和執(zhí)行軌跡);每個(gè)組件絕對(duì)不能超過(guò)自己的預(yù)算,就算擁有“可在不同組件之間調(diào)度預(yù)配時(shí)間”的機(jī)制也不行。例如心律調(diào)節(jié)器,在這樣的系統(tǒng)中,遲來(lái)的數(shù)據(jù)就是錯(cuò)誤的數(shù)據(jù)。
2、持續(xù)關(guān)切法。
要求程序員在任何時(shí)間做任何事時(shí),都要設(shè)法保持系統(tǒng)的高性能。
這種方式通常不會(huì)起太大作用。任何修改如果為了提高性能,通常會(huì)使程序難以維護(hù),因而減緩開(kāi)發(fā)速度。性能一旦被分散到程序各個(gè)角落,每次改善都只不過(guò)是從“對(duì)程序行為的一個(gè)狹隘視角”出發(fā)而已。
3、利用90%統(tǒng)計(jì)數(shù)據(jù)
90%的優(yōu)化都是白費(fèi)勁,因?yàn)殡y得被執(zhí)行。
所以以一種“良好的分解方式”來(lái)建造自己的程序,不對(duì)性能投以任何關(guān)切,直至進(jìn)入性能優(yōu)化階段。
優(yōu)化的過(guò)程:測(cè)量-->優(yōu)化-->編譯-->測(cè)試-->再次測(cè)量.
使用性能熱點(diǎn)測(cè)量工具“發(fā)現(xiàn)熱點(diǎn)、去除熱點(diǎn)”,直到獲得客戶滿意的性能。
McConnell提供了關(guān)于這項(xiàng)技術(shù)的更多信息。