怎么對(duì)經(jīng)理說?
技術(shù)復(fù)審是減少錯(cuò)誤,提高開發(fā)速度的一條重要途徑,隨便找一些關(guān)于復(fù)審、審查或軟件的開發(fā)程序的書看看,從中找些最新引證,應(yīng)該可以讓大多數(shù)經(jīng)理認(rèn)識(shí)復(fù)審的價(jià)值。然后你就可以把重構(gòu)當(dāng)作“將復(fù)審意見引入代碼內(nèi)”的方法來使用。
間接層的價(jià)值
允許邏輯共享。比如說一個(gè)子函數(shù)在兩個(gè)不同的地點(diǎn)被調(diào)用,或superclass中的某個(gè)函數(shù)被所有subclasses共享。
分開解釋"意圖"和"實(shí)現(xiàn)"。你可以選擇每個(gè)class和函數(shù)的名字,這給了你一個(gè)解釋自己意圖的機(jī)會(huì)。class或函數(shù)內(nèi)部則解釋實(shí)現(xiàn)這個(gè)意圖的做法。如果class和內(nèi)部函數(shù)又以“更小單元的意圖”來編寫,你所寫的代碼就可以“與其結(jié)構(gòu)中的大部分重要信息溝通”。
將變化加以隔離。很可能我在兩個(gè)不同地點(diǎn)使用同一對(duì)象,其中一個(gè)地點(diǎn)我想改變對(duì)象行為,但如果修改了它,我就要冒“同時(shí)影響兩處”的風(fēng)險(xiǎn)。為此我做出一個(gè)subclass,并在需要修改處引用這個(gè)subclass。這樣我就可以修改這個(gè)subclass而不必承擔(dān)“無意中影響另一處”的風(fēng)險(xiǎn)。
將條件邏輯加以編碼。對(duì)象有一種匪夷所思的機(jī)制:多態(tài)消息,可以靈活而清晰的表達(dá)條件邏輯。只要顯式條件邏輯被轉(zhuǎn)化為消息形式,往往便能夠降低代碼的重復(fù),增加清晰度并提高彈性。
推測(cè)性設(shè)計(jì)總是試圖在任何一行代碼誕生之前就先讓系統(tǒng)擁有所有優(yōu)秀質(zhì)量,然后程序員將代碼塞進(jìn)這個(gè)強(qiáng)健的骨架就行了。這個(gè)過程的問題在于:太容易猜錯(cuò)。如果運(yùn)用重構(gòu),你就永遠(yuǎn)不會(huì)面臨全盤錯(cuò)誤的危險(xiǎn)。
還有一種比較少見的重構(gòu)游戲:找出不值得的間接層,并將它拿掉。這種間接層常以中介函數(shù)的形式出現(xiàn),也許曾有有過貢獻(xiàn),但芳華已逝。它也可能是個(gè)組件,你本來期望在不同地點(diǎn)共享它,或讓他表現(xiàn)出多態(tài)性,最終卻只在一處使用之。如果你找到這種“寄生式間接層”,請(qǐng)把它扔掉。如此一來你會(huì)獲得一個(gè)更有價(jià)值的程序,不是因?yàn)樗〉昧烁嗟乃姆N優(yōu)秀質(zhì)量,而是因?yàn)樗愿俚拈g接層獲得一樣多的優(yōu)秀質(zhì)量。
數(shù)據(jù)庫(kù)
就算你非常小心的將系統(tǒng)分層,將database schema和對(duì)象模型間的依賴降至最低,但database schema的改變還是讓你不得不遷移所有數(shù)據(jù),這可能是件漫長(zhǎng)而繁瑣的工作。
修改接口
只有當(dāng)需要修改的接口被那些找不到,即使找到也不能修改的代碼使用時(shí),接口的修改才會(huì)成為問題。這種接口被稱之為“已發(fā)布接口”。比公開接口更進(jìn)一步。接口一旦發(fā)布,你就再也無法僅僅修改調(diào)用者而能夠安全的修改接口了。
如果重構(gòu)手法改變了已發(fā)布接口,你必須同時(shí)維護(hù)新舊兩個(gè)接口,直到你的所有用戶都有時(shí)間對(duì)這個(gè)變化做出反應(yīng)。幸運(yùn)的是這不太困難。你通常都有辦法把事情組織好,讓舊接口繼續(xù)工作。請(qǐng)盡量這么做:讓舊接口調(diào)用新接口。當(dāng)你需要修改某個(gè)函數(shù)名稱時(shí),請(qǐng)留下舊函數(shù),讓它調(diào)用新函數(shù)。千萬不要拷貝函數(shù)實(shí)現(xiàn)碼,那會(huì)讓你陷入“重復(fù)代碼”的泥淖中難以自拔。你還應(yīng)該使用java提供的deprecated(反對(duì))關(guān)鍵字,標(biāo)記舊接口。這么一來你的調(diào)用者就會(huì)注意它了。
過渡強(qiáng)調(diào)代碼擁有權(quán)的團(tuán)隊(duì)常常會(huì)犯過量發(fā)布接口的錯(cuò)誤。除非真有必要,別發(fā)布接口。讓每個(gè)人都可以修改別人的代碼,以運(yùn)應(yīng)接口的改動(dòng)。Pair Programming通常是個(gè)好主意。
對(duì)于會(huì)出現(xiàn)不可控異常的情況,通常可以在包中創(chuàng)建一個(gè)超類異常,然后讓所有的public函數(shù)只在自己的throws 子句中聲明這個(gè)異常。這樣就可以隨心所欲的定義子類異常,不會(huì)影響調(diào)用者。因?yàn)檎{(diào)用者永遠(yuǎn)只知道subperclass異常。
這里可以 寫一個(gè)例子:
開始的時(shí)候,我的電腦只有鍵盤這種輸入工具,所以我可以這樣定義我的“電腦”類:
public interface Computer {
void input() throws KeyBoardException;
}
它會(huì)拋出鍵盤異常。后來,我的電腦又有了鼠標(biāo)這種設(shè)備,所以要想保證鼠標(biāo)的使用過程中所產(chǎn)生的錯(cuò)誤是可控的,只能這樣修改接口:
public interface Computer {
void input() throws KeyBoardException,MouseException;
}
這樣就導(dǎo)致了接口被修改,涉及這個(gè)接口的實(shí)現(xiàn)者需要作出修改,否則不能編譯通過;但是不這樣做的話,鼠標(biāo)輸入的異常就會(huì)變?yōu)椴豢煽禺惓!K詴刑岢@樣做:
public interface Computer {
void input() throws InputDeviceException;
}
其中InputDeviceException是所有輸入設(shè)備異常的超類,這樣既不用修改實(shí)現(xiàn)者的代碼,也保證了這些異常是可控的。
posted on 2007-06-22 22:59
littlegai 閱讀(174)
評(píng)論(0) 編輯 收藏 引用