軟件設(shè)計模式來源于Christopher Alexander的建筑學模式和對象運動,。根據(jù)Alexander的觀點,模式就是一個對于特定的系統(tǒng)的通用解決方案本身的重復,。對象運動關(guān)注于將現(xiàn)實世界?;癁檐浖?nèi)部的關(guān)系?;谶@兩個原因,,軟件設(shè)計模式對于真實世界的物體而言同樣應(yīng)當是可以重復的。這篇文章呈現(xiàn)了現(xiàn)實的世界中的非軟件的模式實例,,這些模式來源于《設(shè)計模式-可復用面向?qū)ο筌浖幕A(chǔ)》(Design Patterns - Elements of Reusable Object-Oriented Software)[13]一書,。這篇文章也舉例討論了模式語言對非軟件的表現(xiàn)力和設(shè)計模式的練習。
作者(指《設(shè)計模式》的作者-譯注,下同)總結(jié)了五種創(chuàng)建型模式,。創(chuàng)建型模式的例子可以在制造業(yè),,快餐,生物和行政機構(gòu)中找到,。 抽象工廠(Abstract Factory)舉例 抽象工廠的目的是要提供一個創(chuàng)建一系列相關(guān)或相互依賴對象的接口,,而不需要指定它們具體的類。這種模式可以在日本汽車制造廠所使用的金屬沖壓設(shè)備中找到,。這種沖壓設(shè)備可以制造汽車車身部件,。同樣的機械用于沖壓不同的車型的右邊車門、左邊車門,、右前擋泥板,、左前擋泥板和引擎罩等等,。通過使用轉(zhuǎn)輪來改變沖壓盤,這個機械產(chǎn)生的具體類可以在三分鐘內(nèi)改變,。
圖2:使用兒童餐作為例子的生成器模式的對象作用表 工廠方法(Factory Method) 工廠方法定義一個用于創(chuàng)建對象的接口,,但是讓子類決定實例化哪個類,。壓注成型演示了這種模式。塑料玩具制造商加工塑料粉,,將塑料注入到希望形狀的模具中,。玩具的類別(車,人物等等)是由模具決定的,。 原型(Prototype)舉例 原型模式使用原型實例指定創(chuàng)建對象的種類,。新產(chǎn)品的原型通常是先于全部產(chǎn)品建立的,這樣的原型是被動的,,并不參與復制它自己,。一個細胞的有絲分裂,產(chǎn)生兩個同樣的細胞,,是一個扮演主動角色復制自己原型的例子,,這演示了原型模式。一個細胞分裂,,產(chǎn)生兩個同樣基因型的細胞,。換句話說,,細胞克隆了自己。 單件(Singleton)舉例 單件模式確保一個類僅有一個實例,,并提供一個訪問它的全局訪問點,。單件模式是模仿單集命名的,單集的定義是每個集合僅含有一個元素,。美國總統(tǒng)的職位是單件,,美國憲法規(guī)定了總統(tǒng)的選舉,任期以及繼任的順序,。這樣,,在任何時刻只能由一個現(xiàn)任的總統(tǒng)。無論現(xiàn)任總統(tǒng)的身份為何,,其頭銜"美利堅美利堅合眾國總統(tǒng)"是訪問這個職位的人的一個全局的訪問點,。 作者總結(jié)了七個結(jié)構(gòu)型模式,這些模式的例子可以在工具,、住宅配線,、數(shù)學、節(jié)日傳統(tǒng),、零售目錄和銀行業(yè)中找到,。 適配器(Adapter)舉例 適配器模式允許將一個類的接口轉(zhuǎn)換成客戶期望的另一個接口,使得原本由于接口不兼容而不能一起工作的類可以一起工作,。扳手提供了一個適配器的例子,。一個孔套在棘齒上,棘齒的每個邊的尺寸是相同的,。在美國典型的邊長為1/2''和1/4'',。顯然,如果不使用一個適配器的話,,1/2''的棘齒不能適合1/4''的孔,。一個1/2''至1/4''的適配器具有一個1/2''的陰槽來套上一個1/2''的齒,同時有一個1/4的陽槽來卡入1/4''的扳手,。 橋接(Bridge)舉例 橋接模式將抽象部分與它的實現(xiàn)分離,,使它們能夠獨立地變化。一個普通的開關(guān)控制的電燈,、電風扇等等,,都是橋接的例子。開關(guān)的目的是將設(shè)備打開或關(guān)閉,。實際的開關(guān)可以是簡單的雙刀拉鏈開關(guān),,也可以是調(diào)光開關(guān)。 圖7:使用電子開關(guān)例子的橋接對象圖 組合(Composite)例子 組合模式將對象組合成樹形結(jié)構(gòu)以表示"部分-整體"的層次結(jié)構(gòu),。讓用戶一致地使用單個對象和組合對象,。雖然例子抽象一些,,但是算術(shù)表達式確實是組合的例子。算術(shù)表達式包括操作數(shù),、操作符和另一個操作數(shù),。操作數(shù)可以是數(shù)字,也可以是另一個表達式,。這樣,,2+3和(2+3)+(4*6)都是合法的表達式。 裝飾(Decorator)舉例 裝飾模式動態(tài)地給一個對象添加額外的職責,。不論一幅畫有沒有畫框都可以掛在墻上,,但是通常都是有畫框的,并且實際上是畫框被掛在墻上,。在掛在墻上之前,,畫可以被蒙上玻璃,裝到框子里,;這時畫,、玻璃和畫框形成了一個物體。 外觀(Facade)舉例 外觀模式為子系統(tǒng)中的接口定義了一個統(tǒng)一的更高層次的界面,,以便于使用,。當消費者按照目錄采購時,則體現(xiàn)了一個外觀模式,。消費者撥打一個號碼與客服代表聯(lián)系,,客服代表則扮演了這個"外觀",他包含了與訂貨部,、收銀部和送貨部的接口,。 享元(Flyweight)舉例 享元模式使用共享技術(shù)有效地支持大量細粒度的對象。公共交換電話網(wǎng)(PSTN)是享元的一個例子,。有一些資源例如撥號音發(fā)生器,、振鈴發(fā)生器和撥號接收器是必須由所有用戶共享的,。當一個用戶拿起聽筒打電話時,,他不需要知道使用了多少資源。對于用戶而言所有的事情就是有撥號音,,撥打號碼,,撥通電話。 圖11:使用撥號音發(fā)生器例子的享元模式對象圖 代理模式提供一個中介以控制對這個對象的訪問,。一張支票或銀行存單是賬戶中資金的代理,。支票在市場交易中用來代替現(xiàn)金,并提供對簽發(fā)人賬號上資金的控制,。 作者總結(jié)了十一種行為模式,。這些模式可以在硬幣分類銀行,、餐館訂餐、音樂,、運輸,、汽車修理、自動售貨機和家庭建筑中找到例子,。 職責鏈(Chain of Responsibility)舉例 職責鏈模式使得多個對象都有機會處理請求,,從而避免請求的發(fā)送者和接收者之間的耦合關(guān)系。機械硬幣分揀銀行使用職責鏈,。這里并不是為每一種硬幣分配一個滑槽,,而是僅使用一個滑槽。當硬幣落下時,,硬幣被銀行內(nèi)部的機械導向至適當?shù)慕邮蘸小? 命令(Command)模式 命令模式將一個請求封裝為一個對象,,從而使你可以使用不同的請求對客戶進行參數(shù)化。用餐時的賬單是命令模式的一個例子,。服務(wù)員接受顧客的點單,,把它記在賬單上封裝。這個點單被排隊等待烹飪,。注意這里的"賬單"是不依賴于菜單的,,它可以被不同的顧客使用,因此它可以添入不同的點單項目,。 解釋器(Interpreter)舉例 解釋器模式定義了特定語言的文法表示和解釋該文法的解釋器,。音樂家是解釋器的例子。音階和它的持續(xù)時間可以用五線譜上的符號表示,。這些符號就是音樂語言[14],。音樂家按照樂譜演奏,就可以反復重現(xiàn)同樣的音樂,。 迭代器(Iterator)舉例 迭代器提供一種方法順序訪問一個集合對象中各個元素,,而又不需要暴露該對象的內(nèi)部表示。在早期的電視機中,,一個撥盤用來改變頻道,。當改變頻道時,需要手工轉(zhuǎn)動撥盤移過每一個頻道,,而不論這個頻道是否有信號?,F(xiàn)在的電視機,使用[后一個]和[前一個]按鈕,。當按下[后一個]按鈕時,,將切換到下一個預(yù)置的頻道。想象一下在陌生的城市中的旅店中看電視,。當改變頻道時,,重要的不是幾頻道,,而是節(jié)目內(nèi)容。如果對一個頻道的節(jié)目不感興趣,,那么可以換下一個頻道,,而不需要知道它是幾頻道。 中介者(Mediator)舉例 中介者模式用一個中介對象來控制一系列的對象交互,。通過中介者實現(xiàn)各個對象之間的松散耦合,,而不是彼此直接作用。機場的控制塔很好地演示了這種模式,。降落或者起飛的飛機直接與塔臺通訊,,而不是彼此間直接通訊。誰可以起飛或降落是由塔臺決定的,。這里需要注意的是塔臺并不控制整個飛行過程,。它只負責飛機在機場附近的區(qū)域。 備忘錄(Memento)舉例 備忘錄模式捕獲并且在外部保存一個對象的內(nèi)部狀態(tài),,使得以后可以將對象恢復到該狀態(tài),。這種模式通常體現(xiàn)在你自己修理汽車的剎車時。首先移開兩邊的擋板,,露出左右剎車片,。只能卸下一片,這時另一片作為一個備忘錄來表明剎車是怎樣安裝的,。在這片修理完成后,,才可以卸下另一片。當?shù)诙断聲r,,第一片就成了備忘錄,。 觀察者定義了對象間一對多的關(guān)系,當一個對象的狀態(tài)變化時,,所有依賴它的對象都得到通知并且自動地更新,。拍賣演示了這種模式。每個投標人都有一個標有數(shù)字的牌子用于出價,。拍賣師開始拍賣時,,他觀察是否有牌子舉起出價。每次接受一個新的出價都改變了拍賣的當前價格,,并且廣播給所有的投標人進行新的出價,。 狀態(tài)模式允許一個對象在其內(nèi)部狀態(tài)改變時改變它的行為。這種模式可以在自動售貨機上觀察到,。自動售貨機的狀態(tài)包括列商品清單,收款,,找錢和選擇商品等幾種狀態(tài),。當投入硬幣并選擇了一個商品時,,自動售貨機可以完成以下幾種操作,包括:送出商品不找錢,、送出商品并找錢,、由于投幣不足不送出商品、由于商品售完不送出商品,。 策略模式定義了一系列可以相互替換的算法,。不同的到飛機場去的方式就是一個策略模式的例子。有幾種選擇:自己開車,、坐出租車,、乘機場班車、乘公共汽車或使用專車服務(wù)等等,。對于某些機場,,地鐵和直升機也是可能的選擇。任何一種方式都可以把你送到機場,,它們可以相互代替,。你必須根據(jù)價格、便利性和時間做出選擇,。 模板方法(Template Method)舉例 模板方法定義了一個操作中算法的骨架,,房屋建筑師在開發(fā)新項目時會使用模板方法。一個典型的規(guī)劃包括一些建筑平面圖,,每個平面圖體現(xiàn)了不同部分,。在一個平面圖中,地基,、結(jié)構(gòu),、上下水和走線對于每個房間都是一樣的。只有在建筑的后期才開始有差別而產(chǎn)生了不同的房屋樣式,。 訪問者(Visitor)舉例 訪問者模式表示一個作用于對象結(jié)構(gòu)中各元素的操作,,定義這個操作并不會改變元素的類。這種模式可以在出租車公司的運轉(zhuǎn)中觀察到,。當一個人給出租車公司打電話時,,他(她)就成了公司所有顧客的一員。然后公司指定一輛車去服務(wù)(接受訪問者),。在進入出租車之后,,這個人(訪問者)就不再控制他(她)的旅程了,而是由出租車(駕駛員)負責,。 軟件設(shè)計模式有許多非軟件的例子存在,。也許有人想知道這些例子的實際意義。非軟件例子有助于增進模式語言的表達力和輔助模式的學習。 增加模式語言的表達能力 Alexander覺得真正的模式要融入一種通用的語言以便所有人都能夠分享,。在軟件設(shè)計的人群中,,模式被認為是在同事之間一種約定俗成的開發(fā)方式。模式提供了一種比模塊,、過程和對象更高層次的概念,。 一種語言中至關(guān)重要的因素是同語言形象所對應(yīng)的心靈影像。在一種語言中,,僅當一個人能夠領(lǐng)會一個符號的含義,,能夠在心里描繪出這種含義時,這個符號的外形才是有意義的,。Alexander沒有忽視模式語言的這種重要特征,,他規(guī)定:一種語言只有在它所產(chǎn)生的建筑類型能夠被具體地看到之后,這種語言才是完全形態(tài)化的,。在軟件設(shè)計中,,Richle和Züllighoven認識到具體的例子在指導我們對應(yīng)用領(lǐng)域的理解的重要性。 如果軟件設(shè)計模式成為程序員中通用的語言,,其基礎(chǔ)則是統(tǒng)一的含義,。如果設(shè)計決定下達了,但是沒有被理解,,則設(shè)計師被迫通過假設(shè)來完成工作,。平凡的例子更便于理解,其原因在于人們必須在記憶中找到相關(guān)聯(lián)的內(nèi)容才能夠理解,。在廣泛使用模式的AG Communication Systems公司的項目中,,常常使用非軟件例子來解釋模式之間的關(guān)系。這個例子有助于在設(shè)計師間提供統(tǒng)一的理解,。通過在設(shè)計過程的先期建立統(tǒng)一的理解,,使得在整個項目生命周期中,設(shè)計師間的溝通更加容易,。 在非軟件例子中軟件設(shè)計模式的體現(xiàn)表明了模式不是局限于特定領(lǐng)域的,。軟件設(shè)計師可以從這些日常事物的模式舉例中受益,哪怕這些例子并不是以程序設(shè)計語言表達的,。這篇文章盡可能舉一些大部分人所熟悉的例子(盡管某些傾向于北美文化),。通過對共同的經(jīng)歷的描述,這些例子有助于對特定的設(shè)計模式的理解,,并且能夠幫助對設(shè)計模式的學習,。 |
|
來自: xrzs > 《軟件設(shè)計》