Design Patterns Explained: A New Perspective on Object-Oriented Design一書的前言部分。通過,讀者可以大概了解學(xué)習(xí)設(shè)計(jì)模式的過程和效果。同時(shí),謙虛謹(jǐn)慎的態(tài)度也是非常值得我們中國軟件開發(fā)者學(xué)習(xí)的。
這本書的很多地方都復(fù)述了我自己學(xué)習(xí)設(shè)計(jì)模式的經(jīng)驗(yàn)。在學(xué)習(xí)設(shè)計(jì)模式之前,我認(rèn)為自己理所當(dāng)然是面向?qū)ο蠓治龊驮O(shè)計(jì)的專家。我曾經(jīng)為各種行業(yè)的客戶做過一些還算給人深刻印象的設(shè)計(jì)和實(shí)現(xiàn)。我會(huì)使用C++并且已經(jīng)開始學(xué)習(xí)JAVA。我的代碼中的對(duì)象格式優(yōu)美封裝緊密。我可以在繼承體系中設(shè)計(jì)優(yōu)秀的數(shù)據(jù)抽象。我想我已經(jīng)懂得面向?qū)ο罅。mda.com
現(xiàn)在回頭看看,我發(fā)現(xiàn)那時(shí)其實(shí)我還根本不知道面向?qū)ο笤O(shè)計(jì)的全部能力,盡管我一直按照專家建議的方式來做。直到我開始學(xué)習(xí)設(shè)計(jì)模式,我的面向?qū)ο笤O(shè)計(jì)能力才得到了擴(kuò)展和深化。學(xué)習(xí)設(shè)計(jì)模式使我成為了一個(gè)更好的設(shè)計(jì)者,甚至是我還沒有直接使用那些模式的時(shí)候。
我從1996年開始學(xué)習(xí)設(shè)計(jì)模式。當(dāng)時(shí)我正在西北部一家大型航天公司擔(dān)任C++/面向?qū)ο笤O(shè)計(jì)顧問。有幾個(gè)人勸說我領(lǐng)導(dǎo)一個(gè)設(shè)計(jì)模式學(xué)習(xí)組。正是在那里我遇到了本書的另一個(gè)Jim Scott。在那個(gè)學(xué)習(xí)組中發(fā)生了幾件有趣的事情。首先,我開始對(duì)設(shè)計(jì)模式著迷。我可以把自己的設(shè)計(jì)和其他更有經(jīng)驗(yàn)的人的設(shè)計(jì)相比較,我愛上了這種感覺。另一方面,我發(fā)現(xiàn)我并沒有完全做到"對(duì)接口做設(shè)計(jì)",也沒有隨時(shí)注意"一個(gè)對(duì)象是否可以在不知道另外對(duì)象的類型的情況下使用另外對(duì)象"。同時(shí)我注意到,那些面向?qū)ο蟮某鯇W(xué)者--通常他們被認(rèn)為過早開始學(xué)習(xí)設(shè)計(jì)模式--從這個(gè)學(xué)習(xí)組得到的收益與那些面向?qū)ο蟮膶<也幌嗌舷。設(shè)計(jì)模式向?qū)W習(xí)者展現(xiàn)出優(yōu)秀的面向?qū)ο笤O(shè)計(jì)實(shí)例并闡述基本的面向?qū)ο笤O(shè)計(jì)原則,而這些使學(xué)習(xí)者的設(shè)計(jì)更快地成熟起來。在整個(gè)學(xué)習(xí)進(jìn)程結(jié)束之后,我確信:設(shè)計(jì)模式,這是面向?qū)ο笤O(shè)計(jì)被發(fā)明之后軟件設(shè)計(jì)中最好的東西。
但是,看看那個(gè)時(shí)候我自己的工作,我發(fā)現(xiàn)我根本還沒有在自己寫的代碼中結(jié)合任何一個(gè)設(shè)計(jì)模式。
當(dāng)時(shí)我只是認(rèn)為自己還沒有學(xué)到足夠的設(shè)計(jì)模式,還需要學(xué)習(xí)更多。那時(shí)候,我只知道六個(gè)設(shè)計(jì)模式。然后我可以說是得到了頓悟。我在一個(gè)項(xiàng)目中擔(dān)任面向?qū)ο笤O(shè)計(jì)顧問,并需要為這個(gè)項(xiàng)目創(chuàng)建一個(gè)高層設(shè)計(jì)。這個(gè)項(xiàng)目的領(lǐng)導(dǎo)人極其聰明,但在面向?qū)ο笤O(shè)計(jì)領(lǐng)域,他可以說是一個(gè)新手。
這個(gè)問題本身并不困難,但需要非常注意確保代碼容易維護(hù)。按照慣例,在看過問題兩分鐘之后,我便有了一個(gè)設(shè)計(jì)--采用了我常用的數(shù)據(jù)抽象的途徑。很不幸的是,很顯然這不會(huì)是一個(gè)好的設(shè)計(jì)。簡單的數(shù)據(jù)抽象已經(jīng)讓我嘗到過失敗的滋味。我必須找到一些更好的設(shè)計(jì)思路。
兩個(gè)小時(shí)過去了。在使用了我所知道的所有設(shè)計(jì)技術(shù)之后,情況仍然沒有好轉(zhuǎn)。我的設(shè)計(jì)基本上都還是和從前一樣。而最讓我感覺受挫的是,我知道一定有一個(gè)更好的設(shè)計(jì),但我就是找不到它。更具諷刺意義的是,我甚至還知道四個(gè)設(shè)計(jì)模式就"生活"在我的問題中,但我看不出應(yīng)該如何使用它們。在這里,我,一個(gè)被認(rèn)為是面向?qū)ο笤O(shè)計(jì)專家的人,被一個(gè)簡單的問題困住了!
我實(shí)在覺得很受挫,于是我停了下來,開始繞墻行走以清醒頭腦,并告訴自己:至少10分鐘里我不再想這個(gè)問題。呵呵,30秒之后,我又開始想它了!但我獲得了一種領(lǐng)悟并完全改變了我對(duì)設(shè)計(jì)模式的看法:設(shè)計(jì)模式無法作為獨(dú)立的條款使用;我應(yīng)該把設(shè)計(jì)模式放在一起使用。
模式是應(yīng)該被結(jié)合在一起來共同解決一個(gè)問題的。
以前我曾經(jīng)聽到過這句話,但那時(shí)我并沒有真正理解它。因?yàn)檐浖_發(fā)中的模式往往被介紹為"設(shè)計(jì)模式",所以我總是在"模式最主要的貢獻(xiàn)是在設(shè)計(jì)階段"的假設(shè)下努力。我的想法是:在設(shè)計(jì)世界里,模式就好象是類之間優(yōu)美的聯(lián)系。然后,我閱讀了Christopher Alexander那本令人驚訝的書--The Timeless Way of Building。我學(xué)到了:模式存在在所有的階段--分析、設(shè)計(jì)以及實(shí)現(xiàn)--之中。Alexander在書中討論了如何使用模式來幫助理解(乃至描述)問題領(lǐng)域,而不是僅僅在理解了問題領(lǐng)域后使用模式來創(chuàng)建一個(gè)設(shè)計(jì)。
我的錯(cuò)誤是:我嘗試先創(chuàng)建問題領(lǐng)域中的類,然后將這些類縫合起來形成最終的系統(tǒng)--lexander把這樣的過程稱為"一個(gè)壞主意"。我從來沒有問過自己:我是否擁有正確的類?僅僅因?yàn)檫@些類看起來如此正確、如此明顯。我擁有的,是在我開始分析時(shí)立刻進(jìn)入了我的腦海的類,是我們的老師告訴我們應(yīng)該在系統(tǒng)的描述中尋找的"名詞"。但是我的錯(cuò)誤就是我僅僅嘗試把它們簡單的放在一起。
當(dāng)我回過頭,開始使用設(shè)計(jì)模式和Alexander的方式來指導(dǎo)自己創(chuàng)建我的類時(shí),僅僅幾分鐘之后,一個(gè)優(yōu)秀得多的解決方案在我的腦海中顯露出來。這是一個(gè)很好的設(shè)計(jì),于是我們把它應(yīng)用在產(chǎn)品之中。我很興奮--為我設(shè)計(jì)了一個(gè)好的解決方案,更為設(shè)計(jì)模式的威力。從此,我開始在自己的開發(fā)工作和教學(xué)中結(jié)合設(shè)計(jì)模式。