国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
Martin Fowler:設(shè)計(jì)已死?
Martin Fowler:設(shè)計(jì)已死?
 

設(shè)計(jì)已死?
英文原文版權(quán)由Martin Fowler擁有
Original text is copyrighted by Martin Fowler

Martin Fowler
Chief Scientist, ThoughtWorks

原文出處| 繁體版 | 譯者:Daimler Huang

對(duì)很多粗略接觸到 Extreme Programming 的人來(lái)說(shuō),XP 似乎 宣告了軟件設(shè)計(jì)的死刑。不只很多的設(shè)計(jì)被嘲笑為 "BigUp Front Design"[譯注1],連很多技術(shù)像UML、富有彈性的程序架構(gòu) (framework),甚至連模式 (pattern)都不受重視,或是近似忽略了。事實(shí)上,XP內(nèi)含很多設(shè)計(jì)理念,但是它與現(xiàn)有的軟件流程有著不同的運(yùn)作方式。XP藉由多種實(shí)務(wù)技巧 (practice)賦予演進(jìn)式設(shè)計(jì) (evolutionary design) 嶄新的風(fēng)貌,讓演進(jìn)變成一種實(shí)用的設(shè)計(jì)方法。它也讓設(shè)計(jì)者(designer[譯注2]) 面臨新的挑戰(zhàn)與技巧,學(xué)習(xí)如何使設(shè)計(jì)精簡(jiǎn),如何使用重構(gòu)來(lái)保持一個(gè)設(shè)計(jì)的清楚易懂,以及如何逐步地套用模式。

(這篇文章是我在 XP2000 研討會(huì)發(fā)表的演說(shuō),它會(huì)公布在研討會(huì)講義中。)

      Planned and Evolutionary Design (經(jīng)過(guò)規(guī)劃的設(shè)計(jì)與演進(jìn)式的設(shè)計(jì))

      The Enabling Practices of XP (XP有效的實(shí)作技巧)

      The value of Simplicity (簡(jiǎn)單的價(jià)值)

      What on Earth is Simplicity Anyway (究竟什么是簡(jiǎn)單)

      Does Refactoring Violate YAGNI? (重構(gòu)違反了YAGNI嗎?)

      Patterns and XP (模式與XP)

      Growing an Architecture (發(fā)展結(jié)構(gòu))

      UML and XP (UML與XP)

      On Metaphor (關(guān)于隱喻)

      Do you wanna be an Architect when you grow up? (你將來(lái)想成為一個(gè)軟件結(jié)構(gòu)師嗎?)

      Things that are difficult to refactor in (很難重構(gòu)的東西)

      So is Design Dead? (所以,設(shè)計(jì)死了嗎?)

      Acknowledgements (致謝)

     Revision History (修訂的記錄)

Extreme Programming (XP) 挑戰(zhàn)很多軟件開(kāi)發(fā)常見(jiàn)的假設(shè)。其中最受爭(zhēng)議的就是極力排斥 up-frontdesign,而支持一種比較屬于演進(jìn)的方式。批評(píng)者說(shuō)這是退回到了 "code and fix"的開(kāi)發(fā)方式,頂多只能算是一般急就章的程序設(shè)計(jì)罷了。支持者也??吹?XP 對(duì)于設(shè)計(jì)方法 (如UML)、principle(設(shè)計(jì)準(zhǔn)則)、patterns 等的排斥。別擔(dān)心,仔細(xì)注意你的程序代碼,你就會(huì)看到好的 design 浮現(xiàn)出來(lái)。

我發(fā)現(xiàn)自己正陷于這個(gè)爭(zhēng)論當(dāng)中。我的工作著重在圖形化設(shè)計(jì)語(yǔ)言 - UML 以及 patterns,事實(shí)上我也寫過(guò) UML 和patterns 的書(shū)。我如此的擁抱 XP 是否表示我放棄了這些理論,或是將這些反漸進(jìn)式 (counter-revolutionary)的概念從腦中清除了?

嗯... 我不想讓你的心懸蕩在這兩種情境中。簡(jiǎn)單的說(shuō)并不是;接下來(lái)的文章就讓我來(lái)詳細(xì)說(shuō)明。

 

Planned and Evolutionary Design

 

我將在這篇文章中說(shuō)明軟件開(kāi)發(fā)的兩種設(shè)計(jì)方式是如何完成的。或許最常見(jiàn)的是演進(jìn)式設(shè)計(jì)。它的本質(zhì)是系統(tǒng)的設(shè)計(jì)隨著軟件開(kāi)發(fā)的過(guò)程增長(zhǎng)。設(shè)計(jì) (design) 是撰寫程序代碼過(guò)程的一部份,隨著程序代碼的發(fā)展,設(shè)計(jì)也跟著調(diào)整。

在常見(jiàn)的使用中,演進(jìn)式設(shè)計(jì)實(shí)在是徹底的失敗。設(shè)計(jì)的結(jié)果其實(shí)是一堆為了某些特殊條件而巧妙安排的決定所組成,每個(gè)條件都會(huì)讓程序代碼更難修改。從很多方面來(lái)看,你可能會(huì)批評(píng)這樣根本就沒(méi)有設(shè)計(jì)可言,無(wú)疑地這樣的方式常會(huì)導(dǎo)致很差勁的設(shè)計(jì)。根據(jù)Kent的陳述,所謂的設(shè)計(jì) (design)是要能夠讓你可以長(zhǎng)期很簡(jiǎn)單地修改軟件。當(dāng)設(shè)計(jì) (design)不如預(yù)期時(shí),你應(yīng)該能夠做有效的更改。一段時(shí)間之后,設(shè)計(jì)變得越來(lái)越糟,你也體會(huì)到這個(gè)軟件混亂的程度。這樣的情形不僅使得軟件本身難以修改,也容易產(chǎn)生難以追蹤和徹底解決的 bug。隨著計(jì)畫的進(jìn)行,bug 的數(shù)量呈指數(shù)地成長(zhǎng)而必須花更多成本去解決,這就是 "code and fix" 的惡夢(mèng)。

Planned Design的做法正好相反,并且含有取自其它工程的概念。如果你打算做一間狗屋,你只需要找齊木料以及在心中有一個(gè)大略的形象。但是如果你想要建一棟摩天大樓,照同樣的做法,恐怕還不到一半的高度大樓就垮了。于是你先在一間像我太太在波士頓市區(qū)那樣的辦公室里完成工程圖。她在設(shè)計(jì)圖中確定所有的細(xì)節(jié),一部份使用數(shù)學(xué)分析,但是大部分都是使用建筑規(guī)范。所謂的建筑規(guī)范就是根據(jù)成功的經(jīng)驗(yàn) (有些是數(shù)學(xué)分析)制定出如何設(shè)計(jì)結(jié)構(gòu)體的法則。當(dāng)設(shè)計(jì)圖完成,她們公司就可以將設(shè)計(jì)圖交給另一個(gè)施工的公司按圖施工。

Planned Design 將同樣的方式應(yīng)用在軟件開(kāi)發(fā)。Designer先定出重要的部份,程序代碼不是由他們來(lái)撰寫,因?yàn)檐浖⒉皇撬麄?"建造[譯注3]" 的,他們只負(fù)責(zé)設(shè)計(jì)。所以 designer 可以利用像UML 這樣的技術(shù),不需要太注重撰寫程序代碼的細(xì)節(jié)問(wèn)題,而在一個(gè)比較屬于抽象的層次上工作。一旦設(shè)計(jì)的部份完成了,他們就可以將它交給另一個(gè)團(tuán)隊(duì)(或甚至是另一家公司) 去 "建造"。因?yàn)?designer朝著大方向思考,所以他們能夠避免因?yàn)椴呗苑矫娌粩嗟母亩鴮?dǎo)致軟件的失序。Programmer 就可以依循設(shè)計(jì)好的方向 (如果有遵循設(shè)計(jì))寫出好的系統(tǒng)。

Planned design 方法從七○年代出現(xiàn),而且很多人都用過(guò)它了。在很多方面它比 code and fix漸進(jìn)式設(shè)計(jì)要來(lái)的好,但是它也有一些缺點(diǎn)存在。第一個(gè)缺點(diǎn)是當(dāng)你在撰寫程序代碼時(shí),你不可能同時(shí)把所有必須處理的問(wèn)題都想清楚。所以將無(wú)可避免的遇到一些讓人對(duì)原先設(shè)計(jì)產(chǎn)生質(zhì)疑的問(wèn)題??墒侨绻?designer 在完成工作之后就轉(zhuǎn)移到其它項(xiàng)目,那怎么辦?Programmer開(kāi)始遷就設(shè)計(jì)來(lái)寫程序,于是軟件開(kāi)始趨于混亂。就算找到designer,花時(shí)間整理設(shè)計(jì),變更設(shè)計(jì)圖,然后修改程序代碼。但是必須面臨更短的時(shí)程以及更大的壓力來(lái)修改問(wèn)題,又是混亂的開(kāi)端。

此外,通常還有軟件開(kāi)發(fā)文化方面的問(wèn)題。Designer 因?yàn)閷>募夹g(shù)和豐富的經(jīng)驗(yàn)而成為一位designer。然而,他們忙于從事設(shè)計(jì)而沒(méi)有時(shí)間寫程序代碼。但是,開(kāi)發(fā)軟件的工具發(fā)展迅速,當(dāng)你不再撰寫程序代碼時(shí),你不只是錯(cuò)失了技術(shù)潮流所發(fā)生的改變,同時(shí)也失去了對(duì)于那些實(shí)際撰寫程序代碼的人的尊敬。

建造者 (builder[譯注3])和設(shè)計(jì)者之間這種微妙的關(guān)系在建筑界也看得到,只是在軟件界更加凸顯而已。之所以會(huì)如此強(qiáng)烈是因?yàn)橐粋€(gè)關(guān)鍵性的差異。在建筑界,設(shè)計(jì)師和工程師的技術(shù)有清楚的分野;在軟件界就比較分不清楚了[譯注2]。任何在高度注重 design 的環(huán)境工作的 programmer都必須具備良好的技術(shù),他的能力足夠?qū)?designer 的設(shè)計(jì)提出質(zhì)疑,尤其是當(dāng) designer 對(duì)于新的發(fā)展工具或平臺(tái)越來(lái)越不熟悉的狀況下。

現(xiàn)在這些問(wèn)題也許可以獲得解決。也許我們可以處理人與人之間的互動(dòng)問(wèn)題。也許我們可以加強(qiáng) designer的技術(shù)來(lái)處理絕大部份的問(wèn)題,并且訂出一個(gè)依照準(zhǔn)則去做就足夠改變?cè)O(shè)計(jì)圖的流程。但是仍然有另外一個(gè)問(wèn)題:變更需求。變更需求是軟件項(xiàng)目中最讓我感到頭痛的問(wèn)題了。

處理變更需求的方式之一是做有彈性的設(shè)計(jì),于是當(dāng)需求有所更改,你就可以輕易的變更設(shè)計(jì)。然而,這是需要先見(jiàn)之明去猜測(cè)將來(lái)你可能會(huì)做怎樣的變更。一項(xiàng)預(yù)留處理易變性質(zhì)的設(shè)計(jì)可能對(duì)于將來(lái)的需求變更有所幫助,但是對(duì)于意外的變化卻沒(méi)有幫助(甚至有害)。所以你必須對(duì)于需求有足夠的了解以隔離易變的部份。照我的觀察,這是非常困難的。

部份有關(guān)需求的問(wèn)題應(yīng)該歸咎于對(duì)需求的了解不夠清楚,所以有人專注于研究需求處理,希望得到適切的需求以避免后來(lái)對(duì)設(shè)計(jì)的修改。但是即使朝這個(gè)方向去做一樣無(wú)法對(duì)癥下藥。很多無(wú)法預(yù)料的變更起因于瞬息萬(wàn)變的商場(chǎng),你只有更加小心處理需求問(wèn)題來(lái)應(yīng)付無(wú)法避免的情況。

這么說(shuō)來(lái),planned design 聽(tīng)起來(lái)像是不可能的任務(wù)。這種做法當(dāng)然是一種很大的挑戰(zhàn)。但是,跟演進(jìn)式設(shè)計(jì)(evolutionary design) 普遍以 code and fix 方式實(shí)作比較起來(lái),我不覺(jué)得 planned design會(huì)比較差。事實(shí)上,我也比較喜歡 planned design。因?yàn)槲伊私?planned design 的缺點(diǎn),而且正在尋找更好的方法。

 

The Enabling Practices of XP

 

XP 因?yàn)樵S多原因而備受爭(zhēng)議,其中之一就是它主張演進(jìn)式設(shè)計(jì) (evolutionary design) 而不是 planned design。我們也知道,演進(jìn)式設(shè)計(jì)可能因?yàn)樘囟ǖ脑O(shè)計(jì)或是軟件開(kāi)發(fā)趨于混亂而行不通。

想了解這些爭(zhēng)論的核心,就是軟件研發(fā)異動(dòng)曲線。曲線的變化說(shuō)明,隨著項(xiàng)目的進(jìn)行,變更所需要的成本呈現(xiàn)指數(shù)的增加。這樣的曲線常以一句話來(lái)表示:在分析階段花一塊錢所作的變更,發(fā)行之后要花數(shù)千元來(lái)補(bǔ)救。諷刺的是大部分的計(jì)畫仍然沒(méi)有分析過(guò)程而以非標(biāo)準(zhǔn)的方式進(jìn)行,但是這種成本上的指數(shù)關(guān)系還是存在著。這種指數(shù)曲線意味著演進(jìn)式設(shè)計(jì)可能行不通,它同時(shí)也說(shuō)明著為什么 planned design要小心翼翼地規(guī)劃,因?yàn)槿魏蔚腻e(cuò)誤還是會(huì)面對(duì)同樣的問(wèn)題。

XP 的基本假設(shè)是它可以將這種指數(shù)曲線拉平,這樣演進(jìn)式設(shè)計(jì)就行得通了。XP 使曲線更平緩并能運(yùn)用這種優(yōu)勢(shì)。這是因?yàn)?XP實(shí)作技巧之間的耦合效果:換句話說(shuō),不使用那些能夠拉平軟件開(kāi)發(fā)曲線的實(shí)作技巧來(lái)工作,這條曲線也不會(huì)趨向平緩。這也是爭(zhēng)論的來(lái)源,因?yàn)樵u(píng)論家不了解這其間的關(guān)系。通常這些批評(píng)是根據(jù)評(píng)論家自身的經(jīng)驗(yàn),他們并沒(méi)有實(shí)行那些有效的實(shí)作技巧,當(dāng)他們看到結(jié)果不如預(yù)期,對(duì)于 XP 的印象也就是這樣了。

這些有效的實(shí)作技巧有幾個(gè)部份,主要是 Testing 和 Continuous Integration。如果沒(méi)有 testing提供保障,其它的 XP 實(shí)作技巧都不可行。Continuous Integration可以保持團(tuán)隊(duì)成員信息同步,所以當(dāng)你有改變的部份,不必?fù)?dān)心與其它成員資料整合會(huì)有問(wèn)題。同時(shí)運(yùn)用這些實(shí)作技巧能夠大大影響開(kāi)發(fā)曲線。這讓我再次想起在ThoughtWorks 導(dǎo)入 testing 和 continuous integration之后,明顯的改善了研發(fā)成果。改善的程度好到令人懷疑是不是像 XP 所主張的,必須要用到所有的實(shí)作技巧才能大幅改善效率。[譯注4]

Refactoring 具有類似的成效。那些曾經(jīng)采用 XP 建議的原則來(lái)對(duì)程序代碼進(jìn)行refactoring的人發(fā)現(xiàn),這么做要比無(wú)章法或是特殊方式的 restructuring 明顯的更有效率。那也曾經(jīng)是 Kent 指導(dǎo)我適當(dāng)?shù)?refactor得到的難忘經(jīng)驗(yàn),也因?yàn)檫@么一次巨大的轉(zhuǎn)變促使我以這個(gè)主題寫了一本書(shū)。

Jim Highsmith 寫了一篇很棒的文章 "summary of XP",他把 planned design 和refactoring 放在天秤的兩端。大部份傳統(tǒng)的做法假設(shè)構(gòu)想不變,所以 planned design占優(yōu)勢(shì)。而當(dāng)你的成本越來(lái)越不允許變更,你就越傾向于采用 refactoring。Planned design并不是完全消失,只是將這兩種做法互相搭配運(yùn)用取得平衡。對(duì)我來(lái)說(shuō),在設(shè)計(jì)進(jìn)行 refactoring 之前,總覺(jué)得這個(gè)設(shè)計(jì)不夠健全。

Continuous integration、testing 和 refactoring 這些有效的實(shí)作方法讓 evolutionarydesign 看似很有道理。但是我們尚未找出其間的平衡點(diǎn)。我相信,不論外界對(duì) XP 存有什么印象,XP 不僅僅是 testing、coding和 refactoring。在 coding 之前還有 design 的必要。部份的 design 在 coding 之前準(zhǔn)備,大部份的design 則發(fā)生在實(shí)作每一項(xiàng)詳列的功能之前。總之,在 up-front design 和 refactoring 之間可以找到新的平衡。

 

The value of Simplicity

 

XP 大聲疾呼的兩個(gè)口號(hào)是 "Do The Simplest Thing that Could PossiblyWork"(只做最簡(jiǎn)單可以正常運(yùn)作的設(shè)計(jì)) 和 "You Aren‘t Going to Need It"(就是 YAGNI -你將不會(huì)需要它)。兩項(xiàng)都是XP實(shí)務(wù)中簡(jiǎn)單設(shè)計(jì)的表現(xiàn)形式。

YAGNI 一詞時(shí)常被討論,它的意思是現(xiàn)在不要為了將來(lái)可能用到的功能加入任何程序代碼。表面上聽(tīng)起來(lái)好象很簡(jiǎn)單,問(wèn)題則出在像framework、重用組件、和彈性化設(shè)計(jì),這些東西本來(lái)就很復(fù)雜。你事先付出額外的成本去打造它們,希望稍后將這些花費(fèi)都賺回來(lái)。這個(gè)事先彈性設(shè)計(jì)的想法被認(rèn)為是軟件設(shè)計(jì)有效率的關(guān)鍵部份。

但XP的建議是,在處理第一個(gè)問(wèn)題時(shí)不要因?yàn)榭赡苄枰稠?xiàng)功能,就建造出彈性的組件組及框架出來(lái)。讓整體結(jié)構(gòu)隨著需要成長(zhǎng)。假如我今天想要一個(gè)可以處理加法但是不用乘法的 Money 類別,我就只在 Money類別中建造加法的功能。就算我確定下一個(gè)階段也需要乘法的運(yùn)算,而且我知道很簡(jiǎn)單,也花不了多少時(shí)間,我還是會(huì)留到下一階段再去做它。

其中一個(gè)理由是效益。如果我要花時(shí)間在明天才需要的功能,那就表示我沒(méi)有將精神放在這個(gè)階段應(yīng)該完成的事情上。發(fā)表計(jì)畫詳列目前要完成的事項(xiàng),現(xiàn)在做以后才需要的事情違背開(kāi)發(fā)人員和顧客之間的協(xié)議。這種做法有讓現(xiàn)階段的目標(biāo)無(wú)法達(dá)成的可能。而且這個(gè)階段的 stroies[譯注5]是否具有風(fēng)險(xiǎn),或是需不需要做額外的工作,都是由顧客來(lái)決定的 - 還是可能不包括乘法功能。

這種經(jīng)濟(jì)效益上的限制是因?yàn)槲覀冇锌赡艹鲥e(cuò)。就算是我們已經(jīng)確定這個(gè)功能應(yīng)該如何運(yùn)作,都有可能出錯(cuò) - 尤其是這時(shí)候我們還沒(méi)有取得詳細(xì)需求。提前做一件錯(cuò)誤的事情比提前做一件對(duì)的事情更浪費(fèi)時(shí)間。而且XP專家們通常相信我們比較有可能會(huì)做錯(cuò)而不是做對(duì)(我心有戚戚)。

第二個(gè)支持 simple design 的理由是復(fù)雜的設(shè)計(jì)違反光線行進(jìn)的原理。復(fù)雜的設(shè)計(jì)比簡(jiǎn)單的設(shè)計(jì)還要令人難懂。所以隨著漸增的系統(tǒng)復(fù)雜度,更加難以對(duì)系統(tǒng)做任何修改。如此,若系統(tǒng)必須加入更復(fù)雜的設(shè)計(jì)時(shí),成本勢(shì)必增加。

現(xiàn)在很多人發(fā)現(xiàn)這樣的建議是無(wú)意義的,其實(shí)他們那樣想是對(duì)的。因?yàn)槟闼胂笠话愕难邪l(fā)并沒(méi)有被 XP 有效的技巧所取代。然而,當(dāng)規(guī)劃式設(shè)計(jì)和漸進(jìn)式設(shè)計(jì)之間的平衡點(diǎn)有了變化 (也只有當(dāng)這樣的變化發(fā)生時(shí)),YAGNI 就會(huì)變成好的技巧。

所以結(jié)論是,除非到了往后的階段有所需要,否則你不會(huì)浪費(fèi)精神去增加新的功能。即使不會(huì)多花成本,你也不會(huì)這樣做,因?yàn)榫退悻F(xiàn)在加入這些功能并不增加成本,但是卻會(huì)增加將來(lái)做修改時(shí)的成本。總之,你可以在套用 XP 時(shí)明智的遵守這樣的方法,或是采取一種能降低成本的類似的方法。

 

What on Earth is Simplicity Anyway

 

因此,我們希望程序代碼能夠越簡(jiǎn)單越好,這聽(tīng)起來(lái)沒(méi)什么好爭(zhēng)論的,畢竟有誰(shuí)想要復(fù)雜呢?但問(wèn)題來(lái)了,究竟 "什么才叫簡(jiǎn)單呢?"

在 XPE 一書(shū)中,Kent 對(duì)簡(jiǎn)單系統(tǒng)訂了四個(gè)評(píng)量標(biāo)準(zhǔn),依序是 (最重要排最前面):

通過(guò)所有測(cè)試。

呈現(xiàn)所有的意圖。

避免重復(fù)。

最少數(shù)量的類別或方法。

 通過(guò)所有測(cè)試是一項(xiàng)很普通的評(píng)量標(biāo)準(zhǔn),避免重復(fù)也很明確,盡管有些研發(fā)人員需要?jiǎng)e人的指點(diǎn)才能做到。比較麻煩的是 "呈現(xiàn)所有的意圖"這一項(xiàng),這到底指的是什么呢?

 這句話的本意就是簡(jiǎn)單明了的程序代碼。XP 對(duì)程序代碼的易讀性有很高的標(biāo)準(zhǔn)。雖然在 XP 當(dāng)中,"巧妙的程序代碼 (clevercode)" 這個(gè)字眼經(jīng)常被濫用,不過(guò)意圖清楚的程序代碼,對(duì)其他人來(lái)說(shuō)真的是一種巧妙。Josh Kerievsky 在 XP 2000論文中舉了一個(gè)很好的例子,檢視在 XP 領(lǐng)域可能是大家最熟知的 JUnit 的程序代碼。JUnit 使用 decorators 在 testcases 中加入非必要的功能,像是同步機(jī)制及批次設(shè)定等,將這些程序代碼抽出成為 decorator,的確讓一般的程序代碼看起來(lái)清楚許多。

 但是你必須捫心自問(wèn),這樣做之后的程序代碼夠簡(jiǎn)單嗎?我覺(jué)得是,因?yàn)槲伊私?Decorator 這個(gè)patterns。但是對(duì)于不了解的人來(lái)說(shuō)還是相當(dāng)復(fù)雜的。類似的情況,JUnit 使用 pluggablemethod,一種大部分的人剛開(kāi)始接觸時(shí)都不會(huì)覺(jué)得簡(jiǎn)單的技巧。所以,也許我們可以說(shuō) JUnit對(duì)有經(jīng)驗(yàn)的人來(lái)說(shuō)是比較簡(jiǎn)單的,新手反而會(huì)覺(jué)得它很復(fù)雜。

 XP 的 "Once and Only Once" 以及 Pragmatic Programmer(書(shū)名) 的 DRY(Don‘tRepeat Yourself)都專注在去除重復(fù)的程序代碼。這些良好的建議都有很顯著而且驚人的效果。只要依照這個(gè)方式,項(xiàng)目就可以一路順利的運(yùn)作。但是它也不能解決所有問(wèn)題,簡(jiǎn)單化還是不容易達(dá)成。

 最近我參與一個(gè)可能是過(guò)度設(shè)計(jì)的項(xiàng)目,系統(tǒng)經(jīng)過(guò) refactor 之后去除部份彈性的設(shè)計(jì)。但是就像其中一位開(kāi)發(fā)者所說(shuō)的"重構(gòu)過(guò)度設(shè)計(jì)的系統(tǒng)要比重構(gòu)沒(méi)有設(shè)計(jì)的要來(lái)的容易多了" 做一個(gè)比你所需要簡(jiǎn)單一點(diǎn)的設(shè)計(jì)是最好的,但是,稍微復(fù)雜一點(diǎn)點(diǎn)也不是什么嚴(yán)重的事情。

我聽(tīng)過(guò)最好的建議來(lái)自 Bob 大叔 (Robert Martin)。他的建議是不要太在意什么是最簡(jiǎn)單的設(shè)計(jì)。畢竟后來(lái)你可以,應(yīng)該,也會(huì)再重構(gòu)。愿意在最后重構(gòu),比知道如何做簡(jiǎn)單的設(shè)計(jì)重要得多。

 

Does Refactoring Violate YAGNI?

 

這個(gè)主題最近出現(xiàn)在 XP 討論區(qū)上,當(dāng)我們審視設(shè)計(jì)在 XP 扮演的角色時(shí),我覺(jué)得很值得提出來(lái)討論。

基本上這個(gè)問(wèn)題起因于重構(gòu)需要耗費(fèi)時(shí)間卻沒(méi)有增加新的功能。而 YAGNI 的觀點(diǎn)是假設(shè)你為了眼前的需要做設(shè)計(jì)而不是未來(lái),這樣算是互相抵觸嗎?

YAGNI 的觀點(diǎn)是不要增加一些現(xiàn)階段不需要的復(fù)雜功能,這也是簡(jiǎn)單設(shè)計(jì)這項(xiàng)技巧的部份精神。重構(gòu)也是為了滿足盡可能保持系統(tǒng)的簡(jiǎn)單性這個(gè)需要,所以當(dāng)你覺(jué)得可以讓系統(tǒng)變得更簡(jiǎn)單的時(shí)候,就進(jìn)行重構(gòu)。

簡(jiǎn)單設(shè)計(jì)不但利用了 XP的實(shí)務(wù)技巧,本身也是其中一項(xiàng)有用的實(shí)務(wù)技巧。唯有伴隨著測(cè)試,持續(xù)整合,及重構(gòu)的運(yùn)用,才能有效地做出簡(jiǎn)單設(shè)計(jì)。同時(shí),讓研發(fā)異動(dòng)曲線保持平緩的基礎(chǔ)也就是保持設(shè)計(jì)的簡(jiǎn)單。任何不必要的復(fù)雜都會(huì)讓系統(tǒng)變得難于調(diào)整,除非這個(gè)復(fù)雜性是你為了所預(yù)測(cè)的彈性而加入的。不過(guò),人們的預(yù)測(cè)通常都不太準(zhǔn)確,所以最好還是努力地保持簡(jiǎn)單性。

不管怎樣,人們不太可能第一次就能夠獲得最簡(jiǎn)單的東西,因此你需要重構(gòu)來(lái)幫助你更接近這個(gè)目標(biāo)。

 

Patterns and XP

 

JUnit 的例子讓我不得不想到 patterns。XP 和 patterns 之間的關(guān)系很微妙,也常常被問(wèn)起。JoshuaKerievsky 認(rèn)為 patterns 在 XP被過(guò)分輕視,而且他所提出的理由也相當(dāng)令人信服,我不想再重提。不過(guò)值得一提的是,很多人都認(rèn)為 patterns 似乎與 XP 是有沖突的。

 爭(zhēng)論的本質(zhì)在于 patterns 常被過(guò)度濫用。世上有太多傳奇性的 programmer,第一次讀到四人幫以 32 行程序代碼闡述16 種 patterns 這樣的事情還記憶猶新[譯注6]。我還記得有一晚與 Kent 喝著醇酒一起討論一篇文章 "Not Designpatterns: 23 cheap tricks (不要用設(shè)計(jì)模式-23 個(gè)簡(jiǎn)單的訣竅)"。我們認(rèn)為那不過(guò)是以 if 條件式來(lái)取代strategy 這個(gè) pattern 罷了。這樣的笑話有個(gè)重點(diǎn),patterns 被濫用了。但并不表示 patterns是不足取的,問(wèn)題在于你要怎么運(yùn)用它。

其中一項(xiàng)論點(diǎn)是簡(jiǎn)單設(shè)計(jì)的力量自然會(huì)將項(xiàng)目導(dǎo)向patterns。很多重構(gòu)的例子明確地這么做,或者甚至不用重構(gòu),你只要遵從簡(jiǎn)單設(shè)計(jì)的規(guī)則就會(huì)發(fā)現(xiàn) patterns,即使你還不知道patterns 是什么。這樣的說(shuō)法也許是真的,不過(guò)它真的是最好的方式嗎?當(dāng)然如果你先對(duì)于 patterns有個(gè)大略的了解,或者手邊有一本書(shū)可以參考,會(huì)比自己發(fā)明新的 patterns 要好些。當(dāng)我覺(jué)得一個(gè) pattern快浮現(xiàn)的時(shí)候,我必定會(huì)去翻翻 GOF 的書(shū)。對(duì)我來(lái)說(shuō),有效的設(shè)計(jì)告訴我們 pattern 值得付出代價(jià)去學(xué)習(xí)-那就是它特有的技術(shù)。同樣地就像Joshua 所建議的,我們需要更熟悉于如何逐步地運(yùn)用 patterns。就這一點(diǎn)而言,XP 只是與一般使用 patterns的方式不同而已,并沒(méi)有抹煞它的價(jià)值。

但是從討論區(qū)一些文章看來(lái),我覺(jué)得很多人明顯地認(rèn)為 XP 并不鼓勵(lì)使用 patterns,盡管 XP 大部分的提倡者也都是之前patterns 運(yùn)動(dòng)的領(lǐng)導(dǎo)者。因?yàn)樗麄兛吹搅瞬煌?patterns 的觀點(diǎn)嗎?或是他們已經(jīng)將 patterns融入思考而不必再去理解它?我不知道其它人的答案是什么,但是對(duì)我來(lái)說(shuō),patterns 仍然是非常重要的。XP 也許是開(kāi)發(fā)的一種流程,但patterns 可是設(shè)計(jì)知識(shí)的骨干,不管是哪種流程這些知識(shí)都是很有用的。不同的流程使用 patterns 的方式也就不同,XP強(qiáng)調(diào)等到需要時(shí)才使用 patterns 以及透過(guò)簡(jiǎn)單的實(shí)作逐步導(dǎo)入 patterns。所以 patterns 仍然是一種必須獲得的關(guān)鍵知識(shí)。

我對(duì)于采用 XP 的人使用 patterns 的建議:

花點(diǎn)時(shí)間學(xué)習(xí) patterns。

留意使用 patterns 的時(shí)機(jī) (但是別太早)。

留意如何先以最簡(jiǎn)單的方式使用 patterns,然后再慢慢增加復(fù)雜度。

如果用了一種 pattern 卻覺(jué)得沒(méi)有多大幫助-不用怕,再次把它去掉。

我認(rèn)為XP應(yīng)該要更加強(qiáng)調(diào)學(xué)習(xí) patterns。我不確定它要怎么和 XP 的實(shí)務(wù)技巧搭配,不過(guò)相信 Kent 會(huì)想出辦法來(lái)的。

 

Growing an Architecture

 

軟件架構(gòu)是指什么呢?對(duì)我來(lái)說(shuō),架構(gòu)這個(gè)字眼代表系統(tǒng)核心組件的概念,也就是難以改變的部份,剩下的都必須建造在這基礎(chǔ)上。

 那么當(dāng)你使用演進(jìn)式設(shè)計(jì)時(shí),架構(gòu)又扮演著什么樣的角色呢?XP 的批評(píng)者再一次地聲稱 XP 忽視架構(gòu),因?yàn)?XP使用的方法是盡快地寫程序,然后相信重構(gòu)會(huì)解決所有設(shè)計(jì)的問(wèn)題。很有趣地,他們說(shuō)得沒(méi)錯(cuò),這有可能是 XP 的缺點(diǎn)。無(wú)疑地,最積極的 XP 專家-像Kent Beck, Ron Jeffries, 及 BobMartin-盡其所能地避免預(yù)先結(jié)構(gòu)性的設(shè)計(jì)。在你知道真的要用到數(shù)據(jù)庫(kù)之前,不要加入數(shù)據(jù)庫(kù),先用檔案來(lái)代替,在之后的階段再用重構(gòu)加入數(shù)據(jù)庫(kù)。

 我常被認(rèn)為是一個(gè)膽小的 XP 專家,這點(diǎn)我不同意。我認(rèn)為一個(gè)概括性的初始架構(gòu)有它的用處在。像是一開(kāi)始要怎么將應(yīng)用分層,如何與數(shù)據(jù)庫(kù)互動(dòng) (如果你需要的話),要使用哪種方式去處理網(wǎng)站服務(wù)器。

 基本上,我認(rèn)為這些就是近年來(lái)我們所研究的 patterns。尤其當(dāng)你對(duì) patterns的認(rèn)識(shí)越深,你就會(huì)越熟悉要怎么去善用它們。不過(guò),關(guān)鍵性的差異是在于這些初期架構(gòu)的決定是可以更改的,只要團(tuán)隊(duì)認(rèn)為他們?cè)缙诘呐袛嘤姓`時(shí),就應(yīng)該要有勇氣去修正它們。有人跟我講了一個(gè)項(xiàng)目的故事,就在項(xiàng)目快要發(fā)表時(shí),決定了不再需要EJB,并且要將它們從系統(tǒng)中移除。這是一個(gè)相當(dāng)大規(guī)模的重構(gòu),不過(guò)最后還是完成了。這些有效的實(shí)務(wù)技巧不僅讓事情變得可能,而且很值得去做。

 如果以不同的方式來(lái)做這件事呢?如果你決定不采用 EJB,將來(lái)會(huì)難以加入嗎?你是否要在試過(guò)各種方式卻發(fā)現(xiàn)依然欠缺什么,然后才使用EJB?這是一個(gè)牽涉很多因素的問(wèn)題。不使用復(fù)雜的組件當(dāng)然可以增加系統(tǒng)的簡(jiǎn)單度,而且可以讓事情進(jìn)展比較快,但有時(shí)候從系統(tǒng)中抽掉某個(gè)部份會(huì)比加入它要容易多了。

 所以我建議從評(píng)估架構(gòu)可能的樣子開(kāi)始。假如你看到將會(huì)有多個(gè)使用者使用到大量的資料,一開(kāi)始就直接使用數(shù)據(jù)庫(kù)。若你看到很復(fù)雜的商業(yè)邏輯,就套用domain model。你會(huì)懷疑是否偏離簡(jiǎn)單的特性,這當(dāng)然不是 YAGNI的精神。所以你要有所準(zhǔn)備,在發(fā)現(xiàn)所使用的結(jié)構(gòu)沒(méi)有幫助時(shí)盡快簡(jiǎn)化你的結(jié)構(gòu)。

 

UML and XP

 

在我投身于 XP 領(lǐng)域之后,由于我與 UML 的關(guān)系讓我遇到一個(gè)揮之不去最大的問(wèn)題:這兩者不是不兼容嗎?

 當(dāng)然有些不兼容。XP 顯然不重視 diagram。雖然臺(tái)面上大家對(duì) "好用就用" 有共識(shí),但是實(shí)際上卻是 "實(shí)際上采用 XP的人不畫藍(lán)圖"。這種印象因?yàn)槿?Kent 這些人不習(xí)慣作圖的現(xiàn)象而強(qiáng)化了。事實(shí)上我也從來(lái)沒(méi)看過(guò) Kent 主動(dòng)使用固定的標(biāo)記法畫下軟件藍(lán)圖。

 我覺(jué)得這種情形來(lái)自兩個(gè)因素,其一是有人覺(jué)得軟件藍(lán)圖有用,而有人不覺(jué)得有用。難就難在覺(jué)得藍(lán)圖有用的人不是真正必須動(dòng)手做的人,而必須動(dòng)手做的人卻不覺(jué)得有其必要性。事實(shí)上我們應(yīng)該接受有人喜歡用,而有人不喜歡用。

 另一種情形是軟件藍(lán)圖常引人進(jìn)入繁重的流程中,這些流程耗時(shí)費(fèi)力卻不見(jiàn)得有用,甚至還會(huì)產(chǎn)生壞處。我認(rèn)為應(yīng)該教導(dǎo)人們?nèi)绾问褂盟{(lán)圖卻不落入這樣的陷阱,而不是像那些提倡者僅僅消極的說(shuō) "必要時(shí)才用"。

 所以,我對(duì)于有效使用藍(lán)圖的建議是:

 首先別忘了你畫這些圖的目的,主要的價(jià)值在于溝通。有效的溝通意味著選擇重要的部份而忽略不重要的部份。這樣的選擇也是有效運(yùn)用 UML的關(guān)鍵。不必把全部的 class 都畫出來(lái),畫出重要的就好。對(duì)于每個(gè) class 也只顯示關(guān)鍵的 attribute 和operation,而不是全部顯示出來(lái)。也不要為所有的 use case 和步驟畫循序圖...除非你已經(jīng)有完整的想象。有一個(gè)使用藍(lán)圖的通病就是人們通常希望詳細(xì)完整的把圖表現(xiàn)出來(lái)。其實(shí)程序代碼就是提供完整信息的最佳來(lái)源,同時(shí)程序代碼本身也是保持信息同步最簡(jiǎn)單的方式。因?yàn)閳D形的巨細(xì)靡遺就是一目了然的敵人。

 藍(lán)圖的用途是在開(kāi)始撰寫程序代碼之前探討設(shè)計(jì)內(nèi)容。印象中總是覺(jué)得這樣的動(dòng)作在 XP 是不合法的,但并不是這樣。很多人都說(shuō)如果你遇到棘手的問(wèn)題,就值得先做些設(shè)計(jì)。但是當(dāng)你進(jìn)行設(shè)計(jì)時(shí):

保持簡(jiǎn)短。

不要做得太詳細(xì)(只挑重要的做)。

把結(jié)果當(dāng)作是草圖,而不是定案。

最后一點(diǎn)值得深入探討。當(dāng)你做預(yù)先式設(shè)計(jì),無(wú)可避免的會(huì)發(fā)現(xiàn)一些錯(cuò)誤,而且是在撰寫程序代碼的時(shí)候才發(fā)現(xiàn)。如果你適時(shí)變更設(shè)計(jì),它就不是問(wèn)題。麻煩的是如果你認(rèn)定設(shè)計(jì)已經(jīng)定案,沒(méi)有從 coding 過(guò)程學(xué)到經(jīng)驗(yàn)而跟著先前的設(shè)計(jì)將錯(cuò)就錯(cuò)。

 變更設(shè)計(jì)不代表一定要更改藍(lán)圖。畫這些藍(lán)圖來(lái)幫助你了解設(shè)計(jì),然后就把圖扔開(kāi),這么做是非常合理的。這些圖能夠幫上忙就有它的價(jià)值了。它們不必永遠(yuǎn)存在,最有用的 UML 圖形也不會(huì)是收藏品。

 不少實(shí)行 XP 的人使用 CRC 卡,這與 UML 并不沖突。我常常交互運(yùn)用 CRC 卡和UML,我也總是依照手上的工作選擇最有用的技巧。UML 圖形的另一個(gè)用途是持續(xù)修訂的文件。它一般的形式,就是在 case tool中看到的模型。最初的想法是留著這樣的資料有助于建構(gòu)系統(tǒng)。事實(shí)上卻常常沒(méi)什么用。

保持圖形的更新太花時(shí)間,最后常無(wú)法與程序代碼同步。

它們隱含在 CASE tool 或 thick binder,讓人忽略它。

所以要希望這種持續(xù)修訂的文件有用,就從這些看到的問(wèn)題下手:

只用一些改起來(lái)不至于讓人覺(jué)得痛苦的圖。

把圖放在顯眼的地方。我喜歡畫在墻上,鼓勵(lì)大家一起動(dòng)手修改。

檢討這些圖是不是有人在用,沒(méi)用的就擦掉。

使用 UML 的最后一個(gè)問(wèn)題是文件的交接,像是不同團(tuán)隊(duì)的接手。XP 的想法是文件就像說(shuō)故事,所以文件的價(jià)值由顧客來(lái)決定。于是 UML 又派上用場(chǎng),所提供的圖形可以幫助溝通。別忘了程序代碼本身就蘊(yùn)含了所有詳細(xì)的信息,圖形的作用只是提供概觀以及標(biāo)示重要的部份。

 

On Metaphor

 

好吧,我也許該坦承 - 我一直沒(méi)有抓住 metaphor 的精神。它有用,而且在 C3 項(xiàng)目中運(yùn)用得很好,但是并不表示我知道怎么用它,更不用說(shuō)要解釋怎么用了。

 XP 實(shí)務(wù)技巧中的 Metaphor 是建立在 Ward Cunningham‘s 為系統(tǒng)命名的做法上。重點(diǎn)是想出一個(gè)眾所周知的詞匯,以這樣一個(gè)字來(lái)比喻整個(gè)范疇。這個(gè)代表系統(tǒng)的名字會(huì)套用在 class 和 method 的命名上。

 我以不同領(lǐng)域的觀念性模型,利用 UML和它的前身與領(lǐng)域?qū)<乙黄鸾⒘艘粋€(gè)命名系統(tǒng)。我發(fā)現(xiàn)你必須很小心,你要保持最精簡(jiǎn)的注釋,而且要當(dāng)心別讓技術(shù)性的問(wèn)題不知不覺(jué)的影響這個(gè)模型。但是一旦你完成這個(gè)工作,你就可以為各種領(lǐng)域建立一組詞匯,這些詞匯是大家都能了解并且可用來(lái)與研發(fā)人員溝通的。這種模型無(wú)法與 class設(shè)計(jì)完美的吻合,但是足夠給整個(gè)領(lǐng)域一個(gè)通用的代名詞。

 目前我找不到任何理由說(shuō)明為何這樣的一個(gè)字匯無(wú)法成為一個(gè)比喻,就像 C3 這個(gè)成功的例子;我也不覺(jué)得以系統(tǒng)為主找到在該專業(yè)領(lǐng)域的一個(gè)詞匯有什么壞處。同時(shí)我也不會(huì)放棄可以運(yùn)作自如的為系統(tǒng)命名的技巧。

 人們常批評(píng) XP 乃是基于覺(jué)得一個(gè)系統(tǒng)實(shí)在是至少需要一個(gè)大概的設(shè)計(jì)。XP 專家則以 "就是 metaphor ?。? 來(lái)響應(yīng)。但是我還是沒(méi)有看到一個(gè)對(duì)于 metaphor 令人信服的解釋。這是 XP 的缺憾,必須由 XP 專家來(lái)理出頭緒。

 

Do you wanna be an Architect when you grow up?

 

近幾年來(lái) "software architect (軟件設(shè)計(jì)師)"越來(lái)越熱門,這是一個(gè)就我個(gè)人而言難以接受的名詞。我太太是結(jié)構(gòu)工程師,工程師和建筑師之間的關(guān)系是... 有趣的。我最喜歡的一句話是:建筑師對(duì)三種B 是好的,燈泡、灌木叢、和鳥(niǎo)。因?yàn)榻ㄖ煯嫵鲞@些美麗的圖畫,但卻要工程師保證能做出來(lái)。結(jié)論是我避免 software architect一詞,畢竟如果連我的太太都不能尊重我的專業(yè),我又怎么能對(duì)其他人有所期望呢?

對(duì)軟件來(lái)說(shuō),architect 一詞可以代表很多事情。(軟件界很多詞都可以代表很多事。)這通常符合一句話:我不僅是一個(gè)程序員,我還是一個(gè)設(shè)計(jì)師[譯注2]。還可以進(jìn)一步解譯成:我現(xiàn)在是一個(gè)設(shè)計(jì)師 -我對(duì)于完成所有程序來(lái)說(shuō)太重要了。然后這個(gè)問(wèn)題就變成,當(dāng)你要展現(xiàn)技術(shù)領(lǐng)導(dǎo)的時(shí)候,你是不是該把自己與煩瑣的程序撰寫分清楚?

這個(gè)問(wèn)題引起眾多的不滿。我看到人們對(duì)于再也無(wú)法擔(dān)任設(shè)計(jì)角色這樣的想法感到生氣。我最常聽(tīng)到:在 XP 沒(méi)有設(shè)計(jì)師的揮灑空間。

就設(shè)計(jì)本身的角色來(lái)說(shuō),我不覺(jué)得 XP 不重視經(jīng)驗(yàn)或好的設(shè)計(jì)。事實(shí)上多位 XP 的提倡者 - Kent Back、BobMartin、當(dāng)然還有 Ward Cunningham -都是我從而學(xué)習(xí)設(shè)計(jì)的對(duì)象。然而這也代表著他們的角色從大家既有的印象中開(kāi)始轉(zhuǎn)變成為技術(shù)領(lǐng)導(dǎo)者。

我將以一位 ThoughtWorks 的技術(shù)領(lǐng)導(dǎo)者 Dave Rice 為例。Dave 參與了很多個(gè)研發(fā)周期,并且非正式的指導(dǎo)一個(gè) 50人的項(xiàng)目。他擔(dān)任指導(dǎo)的角色意味著要花很長(zhǎng)的時(shí)間與程序員為伍。當(dāng)程序員需要幫助,他就介入,否則就留意著看誰(shuí)需要協(xié)助。他的座位有一個(gè)明顯的特征,擔(dān)任一位長(zhǎng)期的思考工作者,他可以在任何形式的辦公環(huán)境適應(yīng)良好。他曾經(jīng)與發(fā)行部經(jīng)理 Cara共享辦公室一段時(shí)間。而在最后幾個(gè)月,他更是搬到工程師們工作的開(kāi)放式空間 (就像 XP 小組喜歡的開(kāi)放式"戰(zhàn)斗空間")。這么做對(duì)他很重要,他可以知道事情的進(jìn)展,并適時(shí)伸出援手。

知道 XP 的人就能夠了解我描述的是 XP "教練" 的清楚角色。的確,在 XP 玩的文字游戲中提到領(lǐng)導(dǎo)技術(shù)就是在描繪 "教練"這個(gè)角色。其意義是很清楚的:在 XP 技術(shù)的領(lǐng)導(dǎo)特質(zhì)是透過(guò)教導(dǎo)程序員和幫助他們做決定而呈現(xiàn)。這是一種需要良好人際管理和技術(shù)并重的技巧。JackBolles 在 XP2000 說(shuō):孤單的大師有點(diǎn)機(jī)會(huì)了,合作和教導(dǎo)是成功的關(guān)鍵。

在研討會(huì)的晚餐會(huì)上,我和 Dave 在談話時(shí)對(duì) XP 有了些對(duì)立的意見(jiàn)。當(dāng)我們討論到以前的經(jīng)驗(yàn),我們的方法有相當(dāng)?shù)念愃啤N覀兌计胊daptive,iterative development,也認(rèn)為測(cè)試是重要的。所以我們都對(duì)他反對(duì)的立場(chǎng)感到疑惑。然而他提到"最后我要的是程序員照著設(shè)計(jì)忙于重構(gòu)"。事情一下子明朗起來(lái)。后來(lái) Dave 又對(duì)我說(shuō)"如果我不信任我的程序員,我何必要用他們呢?",觀念上的隔閡就更加清楚了。在 XP里頭,有經(jīng)驗(yàn)的研發(fā)人員所能做的最重要的一件事就是盡量將所有技術(shù)傳繼給新手。不同于一個(gè)決定所有重要事情的建筑師,你有一個(gè)能夠教導(dǎo)研發(fā)人員如何做重大決定的教練。就像 Ward Cunningham 指出,這么做不只是增進(jìn)了新手的能力,對(duì)項(xiàng)目的好處更大于一個(gè)孤立無(wú)援的超人所能做的。[ 譯注7]

 

Things that are difficult to refactor in

 

我們能用 refactoring 來(lái)處理所有設(shè)計(jì)方面的決定嗎?或者,有些問(wèn)題太普遍而且難以在將來(lái)加入設(shè)計(jì)中?此時(shí),XP的正統(tǒng)做法是所有需求都可以輕易的在需要的時(shí)候增加,所以 YAGNI總是能夠適用。我猜是不是有例外?有一個(gè)不錯(cuò)的,被討論到的例子是軟件的國(guó)際化。這是不是一種現(xiàn)在應(yīng)該立即進(jìn)行,否則以后再加入時(shí)會(huì)覺(jué)得痛苦的事情?

我能輕易的想象一些事情就是這種情形。事實(shí)上我們?nèi)匀徽莆仗俚男畔?。如果你必須陸續(xù)加入一些功能,如國(guó)際化,而你知道那需要多少工夫。你比較不容易意識(shí)到在你真正需要他之前,你要花多少時(shí)間加入它,并且要長(zhǎng)時(shí)間的維護(hù)它。你也比較不容易察覺(jué)到也許你可能做錯(cuò)了,所以到頭來(lái)還是需要做些refactoring。

有一部份能夠?yàn)?YAGNI 辯護(hù)的理由是有些預(yù)先做的功能可能最后并不需要,或者它并不如預(yù)期的結(jié)果。不做這些所省下的力氣比用 refactoring 來(lái)更改成為符合需要所用的力氣要少。

另外一個(gè)要想的問(wèn)題是你是否真的知道怎么做。如果你有很多次做軟件國(guó)際化的經(jīng)驗(yàn),你會(huì)知道該用什么模式來(lái)作。那樣的情形下你應(yīng)該會(huì)把它作好。這時(shí)你所加入的預(yù)留的結(jié)構(gòu)可能會(huì)比你頭一次處理這種問(wèn)題要好。所以我的想法是,如果你知道怎么做,你就要考慮現(xiàn)在做和將來(lái)做,兩種情形之間不同的成本。反過(guò)來(lái)說(shuō),如果你沒(méi)有處理過(guò)那樣的問(wèn)題,不僅是你無(wú)法正確判斷需要的成本,你也比較不可能把事情作好。這種情形,你就要選擇將來(lái)再做。如果你還是執(zhí)意做了,而且嘗到苦果,可能會(huì)比不做的情況更糟。當(dāng)你的組員更有經(jīng)驗(yàn),你對(duì)相關(guān)領(lǐng)域有更多認(rèn)識(shí),你對(duì)需求也會(huì)更了解。通常到這時(shí)你回頭看才會(huì)發(fā)現(xiàn)事情有多簡(jiǎn)單。提早加入的設(shè)計(jì)比你想象中要難多了。

這個(gè)問(wèn)題也跟 stories 的順序密切相關(guān)。在 Planning XP 一書(shū)中,Kent 和我公開(kāi)的指出我們的歧見(jiàn)。Kent偏向于只讓商業(yè)價(jià)值這一個(gè)因素影響 stories 的順序。在短暫的意見(jiàn)不合之后 Ron Jeffries也同意這種想法。我仍保持懷疑。我相信在商業(yè)價(jià)值和技術(shù)風(fēng)險(xiǎn)之間能找到平衡點(diǎn)?;谶@樣的理由讓我提早為軟件國(guó)際化做準(zhǔn)備以降低風(fēng)險(xiǎn)。但是這種做法也只有當(dāng)?shù)谝浑A段發(fā)行就需要將軟件國(guó)際化才能成立。盡快達(dá)到一個(gè)階段的發(fā)行是非常重要的。任何原來(lái)不需要而后來(lái)必須增加的復(fù)雜性都值得在第一階段發(fā)行之后才開(kāi)始。發(fā)行之后運(yùn)作中的程序有強(qiáng)大的力量,它抓住顧客的注意,增加信任感并且是一個(gè)學(xué)習(xí)的好機(jī)會(huì)。就算是在初次發(fā)行之后會(huì)有更多的事情要做,還是要盡所有努力將第一階段日期往前推。

 

So is Design Dead?

 

沒(méi)什么原因,只是設(shè)計(jì)的本質(zhì)已經(jīng)改變。XP 的設(shè)計(jì)追求以下的技巧:

持續(xù)保持清爽的程序代碼,越簡(jiǎn)單越好。

重構(gòu)的技巧,所以當(dāng)你覺(jué)得必要的時(shí)候都可以有信心的動(dòng)手。

具有 patterns 的知識(shí):不只是照它的解法,更要感覺(jué)何時(shí)可以應(yīng)用,或是如何導(dǎo)入 patterns。

知道如何將設(shè)計(jì)說(shuō)給必要的人了解[譯注8],用程序代碼、或是圖形、或上述所有的工具:交談。

以上挑出來(lái)的技巧看來(lái)都挺嚇人,但是要成為一個(gè)優(yōu)秀的設(shè)計(jì)師本來(lái)就很難。XP 也不是要讓它變得簡(jiǎn)單,至少我就不覺(jué)得。但是我想 XP 讓我們對(duì)有效率的設(shè)計(jì)有全新的看法,因?yàn)樗対u進(jìn)式設(shè)計(jì)聽(tīng)起來(lái)是可行的方式。而且我也很支持演進(jìn) - 否則誰(shuí)知道我會(huì)變成什么呢?

 

Acknowledgements[譯注9]

 

過(guò)去這些年我從很多好朋友身上偷學(xué)到不少好的想法,很多都已經(jīng)記不起來(lái)。但是我記得從 Joshua Kerievski那里偷到的好東西。我也記得 Fred George 和 Ron Jeffries 給我很好的建議。我當(dāng)然也不能忘記 Ward 和 Kent不斷有好的想法。

我也感謝曾經(jīng)提出問(wèn)題和指出打字錯(cuò)誤的朋友。同時(shí)感謝 Craig Jones 提醒我好幾個(gè)漏掉的 “a”。

 

Revision History

以下是這篇文章重大的修改記錄:

      2001 年 2 月:對(duì) growing an architecture、the role of anarchitect、和 where things that are difficult to add with refactoring等段落做修改。

      2000 年 7 月:原始文件在 XP 2000 發(fā)表,并刊載于 MartinFowler.com 網(wǎng)頁(yè)。

 

[譯注1] 一種在著手進(jìn)行程序代碼的撰寫之前,就先按照既定的程序分析、設(shè)計(jì)、制圖、撰寫文件等等耗時(shí)費(fèi)力的工作方式。

[譯注2] 在臺(tái)灣你覺(jué)得 “程序設(shè)計(jì)師”、“軟件設(shè)計(jì)師” 和 “軟件工程師”有什么不同嗎?相信大部分的人覺(jué)得都是同一種角色。但是從英文字意就比較容易區(qū)別“programmer”、”designer”、”architect”等等不同的角色。這樣的語(yǔ)言文化差異性,也是我在內(nèi)文中留下不少原文的原因。在部份字句中,留下原文并不影響閱讀的順暢,但是可以避免文意因?yàn)榉g所造成的模糊或扭曲。

[譯注3] 在建筑業(yè)應(yīng)該是稱呼 “施工人員” 比較順耳,而在軟件業(yè)應(yīng)該是 “programmer” 比較恰當(dāng)。但是這兩者都是 “builder”。

[譯注4] 關(guān)于這一點(diǎn),譯者也提供一個(gè)實(shí)際的經(jīng)驗(yàn),也就是翻譯這篇文章的過(guò)程。我和一位朋友一起翻譯這篇文章,而且因?yàn)槎枷瓤催^(guò) XPDistilled 一文,所以決定采用 XP 12 個(gè)有效的實(shí)務(wù)技巧其中的 Continuous Integration、PairProgramming、Small Releases、Refactoring、Coding Standards、Collective CodeOwnership 等等技巧。因?yàn)?XP Distilled 一文的經(jīng)驗(yàn)我們首先對(duì)于部份翻譯名詞提出彼此的統(tǒng)一版本,這就是一種 CodingStandards。我們同時(shí)都對(duì)這篇文章進(jìn)行翻譯,不同的人進(jìn)行同一項(xiàng)工作進(jìn)度就不會(huì)相同,每翻譯幾個(gè)段落就將進(jìn)度寄給對(duì)方,這就是 SmallReleases。當(dāng)我收到朋友寄來(lái)的部份,我就對(duì)照兩方的差異將文章針對(duì)譯意的正確性和辭句的通暢做初步的整理和修正,這就是 ContinuousIntegration。我整理過(guò)的部份再寄回給朋友進(jìn)行檢查,如果發(fā)現(xiàn)不妥的部份,就進(jìn)行討論或修改,這就是Refactoring。從頭到尾的過(guò)程中,我們都收到彼此的翻譯版本,也擁有整理過(guò)的版本,對(duì)于每個(gè)部份也都清楚了解,符合 CollectiveCode Ownership 的精神。最后,因?yàn)槲覀儎偤檬莾蓚€(gè)人,不巧又可以冠上另一個(gè)技巧Pair Programming。所以,我們使用了XP 一半的方法,對(duì)于工作上有幫助的方法。但并不是非得每一項(xiàng)技巧都利用到。我想,更重要的一點(diǎn)是,XP并不是只能用在軟件研發(fā),我們的翻譯過(guò)程不也借來(lái)用了!

[譯注5] Story 是一種類似 use case 的描述。

[譯注6] 按照原文的意思就是以 32 行的程序代碼而能夠表現(xiàn)出 16 種 patterns!這樣的傳奇性功力實(shí)在不是經(jīng)驗(yàn)及見(jiàn)識(shí)淺薄的譯者所能想象,所以我們只能按照原文翻譯,而無(wú)法對(duì)這句話提出左證。如果讀者見(jiàn)過(guò)作者提到的例子,很感謝您提供相關(guān)資料給我。

[譯注7] 這一點(diǎn)也是譯者對(duì)于臺(tái)灣軟件環(huán)境非常憂心的問(wèn)題,大家都能體會(huì)中國(guó)人的一種不知道能不能說(shuō)是重大缺點(diǎn)的民族習(xí)性“藏私”。我在不同的機(jī)會(huì)從文章中以及朋友的口中聽(tīng)到一種想法,要提升團(tuán)隊(duì)的整理效率,一種最簡(jiǎn)單的方法就是將技術(shù)落后的成員教育提升到與技術(shù)領(lǐng)先的成員相同的水平。這樣的想法實(shí)在是一種非常有用而且深刻的體認(rèn),更是一種感嘆。在臺(tái)灣能夠在口頭上同意這種做法,而實(shí)際上更能夠進(jìn)而實(shí)踐這種精神的人有多少??有些人都擔(dān)心自己的技術(shù)被人窺透之后,個(gè)人地位恐將遭到取代,更遭的是可能有老板真的會(huì) “狡兔死走狗烹”的在榨取經(jīng)驗(yàn)的傳承之后,將有貢獻(xiàn)卻成本高的成員以各種方式逼走,這實(shí)在是讓人憂心又灰心的現(xiàn)象?。∽g者相信,再困難的技術(shù)只要是你能了解,就已經(jīng)存在了競(jìng)爭(zhēng)對(duì)手,如果不能將身邊成員的技術(shù)水平同時(shí)迅速提升,只有等著被快速超越,更可能被淘汰。譯者也實(shí)踐著 XP這方面的精神,雖然譯者所擁有的技術(shù)知識(shí)非常粗淺,但是只要同事朋友需要我的協(xié)助,我總是知無(wú)不言,言無(wú)不盡。譯者要向流星許愿,希望能夠找到越來(lái)越多的同類。

[譯注8]有效的溝通也是譯者常遭遇的問(wèn)題之一,有些人無(wú)法以不同的方式為事情下批注,有些人對(duì)于門外漢還是滿口專業(yè)術(shù)語(yǔ),有些人不能觀察顧慮到聽(tīng)者是不是已經(jīng)了解所闡述的精髓。這些都不是有效的溝通。我們似乎還不夠重視人際溝通這門學(xué)問(wèn),如何以對(duì)方能懂的方式說(shuō)給對(duì)方聽(tīng),真是不容易呢!譯者只是發(fā)出感嘆,卻也亟需要培養(yǎng)溝通能力,才不會(huì)讓共事的同事?lián)u頭。

[譯注9] 譯者之一的我 (Daimler) 也要搭個(gè)順風(fēng)車,感謝朋友 (S.H.Chen)在百忙之中抽空與我完成這篇文章的翻譯,這位朋友在軟件工程方面的知識(shí)給我的幫助非常關(guān)鍵。翻譯本身就存在不少爭(zhēng)議,應(yīng)該按照句子逐字翻譯,還是要考慮依據(jù)本國(guó)文字的用語(yǔ)習(xí)慣做適當(dāng)?shù)恼{(diào)整,以求字句的通順,真的讓人難以取舍抉擇。我 (Daimler)是比較傾向于在不扭曲原著作文意的原則下,對(duì)句子做適當(dāng)?shù)闹亟M和調(diào)整。但是這個(gè)動(dòng)作本身就存在著非常大的危險(xiǎn),我對(duì)于原文是否有足夠的認(rèn)識(shí)?我對(duì)于本國(guó)文字的造詣是否及格?希望這篇文章對(duì)于國(guó)內(nèi)讀者能有所幫助,至少是效率上的幫助。更期盼來(lái)自各方的指教。

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
步步為營(yíng) .NET 代碼重構(gòu)學(xué)習(xí)筆記 一、為何要代碼重構(gòu)
極限編程
軟件設(shè)計(jì)經(jīng)典書(shū)籍推薦
敏捷思維: 架構(gòu)設(shè)計(jì)中的方法學(xué)(6)
重構(gòu)
軟件工程師必讀技術(shù)書(shū)籍推薦<1>
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服