我给媳妇解释设计模式:第一部分
引子我跟媳婦曾經(jīng)就面向?qū)ο笤O(shè)計(jì)這個(gè)話題做過有趣的探討。當(dāng)我把它們發(fā)表在社區(qū)之后,得到了一些很不錯(cuò)的反饋,也大大鼓舞了我。所以,我很高興能把我們后面的一次談話繼續(xù)分享出來,那是關(guān)于面向?qū)ο蟮脑O(shè)計(jì)模式的,大家往下看吧。 | AlfredCheung |
| 其它翻譯版本(2) |
什么是設(shè)計(jì)模式丈夫:?我想你現(xiàn)在對面向?qū)ο蟮脑O(shè)計(jì)原則有了一些基本概念了吧。我們那次關(guān)于OOD原則(SOLID原則)的有趣談話被我發(fā)表在社區(qū)上了,你不會(huì)介意吧?網(wǎng)址在這里:?我怎么向妻子解釋OOD。 設(shè)計(jì)模式則是這些原則在某些特定和常用條件下的應(yīng)用,并且做了一些標(biāo)準(zhǔn)化。我們還是來一些例子吧。 媳婦:?好極了,我喜歡例子。 丈夫:?以我們的車為例吧。它是一個(gè)對象,不過有點(diǎn)復(fù)雜,是由幾千個(gè)其它對象組成的,包括引擎、車輪、轉(zhuǎn)向裝置、座位、車身,等等。
一輛車的各種零件。 | AlfredCheung |
| 其它翻譯版本(1) |
| 這輛車在制造的時(shí)候,制造商收集所有的零件,把它們組裝起來。這些零件本身也是復(fù)雜的對象,是由其它的制造商組裝的。但汽車公司并不關(guān)心這些零件是怎么造出來的(當(dāng)然,他們需要確信這些零件的質(zhì)量是過硬的)。他們只會(huì)關(guān)心如何通過不同的方式將不同的零件組裝起來,以便生產(chǎn)出不同型號(hào)的汽車。
由不同零件根據(jù)不同設(shè)計(jì)組裝成的不同型號(hào)的車。 媳婦:?每種型號(hào)的汽車應(yīng)該都有各自的設(shè)計(jì)和藍(lán)圖什么的,是吧? 丈夫:?非常正確。而且,這些設(shè)計(jì)是經(jīng)過深思熟慮的,花了很長的時(shí)間和很大的努力才得以誕生。完成設(shè)計(jì)之后,汽車的生產(chǎn)就只剩下遵循設(shè)計(jì)這么簡單的事了。 | AlfredCheung |
| 媳婦:?嗯……很不錯(cuò)的辦法,先想出一些優(yōu)秀的設(shè)計(jì),然后遵照這些設(shè)計(jì),就可以在很短的時(shí)間里造出不同的東西。如果制造商想要開發(fā)某種型號(hào)的產(chǎn)品,不需要從頭進(jìn)行設(shè)計(jì),或者說重新造輪子,只要遵循那些設(shè)計(jì)就可以了。
用于不同型號(hào)產(chǎn)品(車)的不同設(shè)計(jì)。 丈夫:?你說到點(diǎn)子上了。現(xiàn)在,回到現(xiàn)實(shí)里,我們是軟件廠商,我們需要根據(jù)需求,用不同的組件來創(chuàng)造出不同的軟件。在這個(gè)過程中,一定會(huì)碰到一些情形,是在許多不同的軟件里都有的,對不對? 媳婦:?對啊。而且,我們還常常在不同的軟件里碰到相同的設(shè)計(jì)難題呢。 | AlfredCheung |
| 丈夫: 我們嘗試著用一種面向?qū)ο蟮姆绞絹黹_發(fā)我們的軟件,利用OOD原則來讓我們的代碼更容易管理、重用和擴(kuò)展。就像你上面提到的那些相同的問題,如果我們預(yù)先就有一些良好的設(shè)計(jì),那是不是很棒呢? 媳婦: 是啊,那可以省下大把的時(shí)間,而且這樣打造的軟件質(zhì)量更好,更容易管理。 丈夫: 沒錯(cuò)。還有個(gè)好消息,我們并不需要自己造輪子。這么多年以來,遭遇同樣問題的人們早已發(fā)現(xiàn)了許多很棒的解決方案,而且把它們標(biāo)準(zhǔn)化過了。我們管這些方案叫設(shè)計(jì)模式。 我們要感謝四人幫(GoF),他們在設(shè)計(jì)模式: 可重用面向?qū)ο筌浖幕驹?/span>這本書里歸納了23個(gè)最基本的設(shè)計(jì)模式。想知道這四個(gè)牛人是誰嗎?Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides。面向?qū)ο蟮脑O(shè)計(jì)模式很多,但大家認(rèn)為這23個(gè)模式是其它模式的基礎(chǔ)。 | AlfredCheung |
| 媳婦:我能創(chuàng)建一個(gè)新模式嗎?有可能嗎? 丈夫:當(dāng)然可以,親愛的,為什么不行呢?設(shè)計(jì)模式并不是被科學(xué)家發(fā)明和創(chuàng)造的東西。他們只是被“發(fā)現(xiàn)”而已。也就是說,對任何一個(gè)普通的問題場景,肯定會(huì)有一些好的設(shè)計(jì)方案。如果我們能識(shí)別出一個(gè)能解決某個(gè)新問題的面向?qū)ο笤O(shè)計(jì),那我們就定義了一個(gè)新的設(shè)計(jì)模式。誰知道呢?如果我們發(fā)現(xiàn)一些設(shè)計(jì)模式,沒準(zhǔn)兒大家會(huì)叫我們“二人幫”呢...哈哈。 媳婦::) | SeabornLee |
我們怎么來學(xué)習(xí)設(shè)計(jì)模式呢?丈夫: 我始終堅(jiān)信,通過例子學(xué)習(xí)是最好的。在我們的學(xué)習(xí)過程中,我們不會(huì)“先理論后實(shí)踐”,因?yàn)槲艺J(rèn)為這是一種“壞”方法。設(shè)計(jì)模式不是基于理論發(fā)明的。相反,總是先有問題場景,再基于需求和情景不斷演化設(shè)計(jì)方案,最后把一些方案標(biāo)準(zhǔn)化成“模式”。所以,我們討論每一個(gè)設(shè)計(jì)模式時(shí),要盡量用生活中的真實(shí)問題來理解和分析。然后嘗試一步步地闡述設(shè)計(jì),并以一個(gè)能匹配某些模式的設(shè)計(jì)收尾。設(shè)計(jì)模式就是這樣被發(fā)現(xiàn)的,你覺得呢? 媳婦: 我覺得對我來說,這種方式可能更好使。如果我能通過先分析問題,然后闡述解決方案, 最后得到一個(gè)設(shè)計(jì)模式,我就不用死記那些圖形和定義了。就這么辦吧。 | SeabornLee |
基礎(chǔ)的設(shè)計(jì)問題和解決方案丈夫:?讓我們考慮一下下面的情況: 我們的家里都有家用電器(比如電燈和風(fēng)扇),他們都是由開關(guān)控制。?任何時(shí)候,你都可以在不改變其他東西的情況下做一些事。你可以在不更換開關(guān)的情況下?lián)Q掉燈泡,也可以在不接觸燈泡或者風(fēng)扇的情況下更換開關(guān),甚至可以在不接觸開關(guān)的情況下,把燈泡和風(fēng)扇的開關(guān)互換。 家用電器:風(fēng)扇和燈泡 兩種開關(guān)(第二個(gè)顯然比第一個(gè)要好看) | Naixjs |
| 媳婦:對啊,這看起來很自然,不是嗎? 丈夫:是的,非常自然,同時(shí)也應(yīng)該這樣安排。當(dāng)不同的事物聯(lián)系到一起時(shí),他們應(yīng)該在一個(gè)可以變更或者可以替換的系統(tǒng)中以便不相互影響,或者影響盡可能的小。這樣讓你更為方便、成本最小地去管理你的系統(tǒng)。可以想象,如果你要換一個(gè)你房間里的燈泡得要求你把開關(guān)也換了,你會(huì)考慮在你房子里使用這樣的一個(gè)系統(tǒng)嗎? 媳婦:當(dāng)然不會(huì)。 丈夫:現(xiàn)在,讓我們想一下電燈或者電風(fēng)扇是怎樣和開關(guān)聯(lián)系起來以便更換其中一個(gè)而不會(huì)影響到其他的。你想到什么了? 媳婦:當(dāng)然是電線啦。 | excepiton |
| 丈夫:正確,是電線以及其他的電工手段把電燈/電風(fēng)扇與開關(guān)連接起來。我們可以把這概括為溝通不同系統(tǒng)的橋梁。基本思想是,一個(gè)事物不能直接連接另一個(gè)事物。當(dāng)然,他們能夠通過一些橋梁或接口連接起來。在軟件世界里,我們稱之為“松耦合”。 媳婦:嗯,我明白這點(diǎn)。 丈夫:現(xiàn)在,我們來嘗試?yán)斫庖恍╊愃齐姛?電風(fēng)扇與開關(guān)類似的關(guān)鍵問題,同時(shí)嘗試?yán)斫馐窃鯓釉O(shè)計(jì)和關(guān)聯(lián)它們的。 媳婦:好的,我們開始吧。 在我們的列子里,有一些開關(guān),這些類似普通的開關(guān)、有不同的花式開關(guān)可能有不同的種類,但是,一般情況下,他們就是開關(guān)。同時(shí),每個(gè)開關(guān)都能開和關(guān)。 | excepiton |
這樣的話,我們就會(huì)得到如下的Switch基類: ?
同時(shí),我們可能也 需要一些特定類型的開關(guān),譬如正常的開關(guān)、不同花式的開關(guān)等等。同樣的我們擴(kuò)展Switch類來實(shí)現(xiàn)FancySwitch和NormalSwitch: ?
這兩個(gè)特定的開關(guān)類可能用于它們自己特有的行為和特征,但是到目前為止,我們還是保持它們現(xiàn)在的簡單形式。 丈夫:棒極了。現(xiàn)在,如何處理風(fēng)扇和燈呢? 媳婦:讓我試試。按照面向?qū)ο笤O(shè)計(jì)原則中的封閉原則,我認(rèn)為我們需要試著在任何可能的地方做抽象處理,對嗎? 丈夫:對。 | Tocy |
| 媳婦: 電扇和電燈情況有點(diǎn)不一樣,它們兩個(gè)不是同一種東西。對于不同的開關(guān),我們可以用同一個(gè)基本的Switch類,但對于電扇和電燈就不大合適了,感覺用接口會(huì)更合適一點(diǎn)。因?yàn)?#xff0c;從大體上講,它們都算是電器,那么我們可以就定義一個(gè)接口: IElectricalEquipment,用它來抽象電扇和電燈,對不對? 丈夫:?很對。 媳婦:?那么,所有電器都有一些共性,可以被打開和關(guān)閉。那么這個(gè)接口就可以是: ?
| AlfredCheung |
| 媳婦: 沒錯(cuò),開關(guān)并不知道電扇和電燈的存在。它只知道它可以打開或關(guān)閉某個(gè)電器IElectricalEquipment。那么,也就是說每個(gè)Switch應(yīng)該擁有一個(gè)IElectricalEquipment實(shí)例,是吧? 丈夫:?很對。這里,被封裝的實(shí)例,也就是IElectricalEquipment,就是這座橋。好,我們來修改一下Switch類,讓它把電器封裝進(jìn)去: ?
| AlfredCheung |
| 電扇類: ?
電燈類: ?
也就是說:
| AlfredCheung |
| 我們想要的功能基本上是這個(gè)樣子: ?
| AlfredCheung |
| 丈夫: 干得好。這個(gè)電扇顯示是可以換開關(guān)的。而且,反過來也是可以換的,可以不修改電扇和電燈,直接更換開關(guān),例如,我們可以把電燈的開關(guān)從FancySwitch換成NormalSwitch: ?
| AlfredCheung |
| 媳婦:酷!我懂了。一般來說,兩個(gè)系統(tǒng)不應(yīng)該直接地互相聯(lián)接和依賴。相反,他們應(yīng)該通過抽象來聯(lián)接或依賴(正如依賴倒置和開閉原則所言),這樣它們就是松耦合的,我們就可以在必要時(shí)輕松地修改實(shí)現(xiàn),而不對系統(tǒng)的其它部分造成太大影響。 我:親愛的,你得我真?zhèn)髁恕N覀儊砜匆幌聵蚪幽J降亩x吧: “把抽象和實(shí)現(xiàn)解耦,使得它們可以獨(dú)立地變化”我們的設(shè)計(jì)完全符合定義。如果你有類設(shè)計(jì)器(Visual Studio和其它流行的IDE都有這功能),你能看到一個(gè)和下圖相似的類圖:
| SeabornLee |
| 在我們的例子里,Abstraction是基礎(chǔ)的Switch類,RefinedAbstraction是某個(gè)具體的開關(guān)類(FancySwitch和NormalSwitch),Implementor是IElectricalEquipment接口,ConcreteImplementorA和ConcreteImplementorB分別是Fan和Light類。 媳婦: 我有點(diǎn)好奇。你不是說有很多模式么,干嘛先說橋梁模式呢?有什么特別重要的原因嗎? 丈夫: 問得好。我從橋梁模式開始,而不是其它模式,只有一個(gè)原因。我覺得它是所有面向?qū)ο笤O(shè)計(jì)模式的基礎(chǔ)。因?yàn)?
| AlfredCheung |
| 媳婦:?你覺得我理解的對么? 丈夫: 哦~親愛的,我覺得你理解的非常好。 媳婦:?那么,下一步呢? 丈夫:?通過了解橋接模式,我們才稍微的了解了設(shè)計(jì)模式的概念。在我們接下來的談話中,我們將會(huì)學(xué)習(xí)其他的涉及模式,希望你不會(huì)覺得它們無聊。 媳婦:?不會(huì)的,相信我。 Next請關(guān)注我們的下一次談話:)? |
from:?http://www.oschina.net/translate/how-i-explained-design-patterns-to-my-wife-part-1
英文原文:How I explained Design Patterns to my wife: Part 1
參與翻譯(8人): AlfredCheung,?SeabornLee,?excepiton,?Johni386,?不是小白,?Naixjs,?鉑金小龜,?Tocy總結(jié)
以上是生活随笔為你收集整理的我给媳妇解释设计模式:第一部分的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java之美[从菜鸟到高手演变]系列之博
- 下一篇: 《Head first设计模式》学习笔记