設計引導---設計模式基礎


新手閱讀Gof的《設計模式》有點難度,這里,要講述的是,幫助大家奠定一下基礎,使大家更好的去學習設計模式,去提升我們的思想,設計包含着抽象,又有些哲學,靜下心來,你也可以學到優秀程序員的技術。

設計模式,起初是從建築學中開始發展的。在此來講個故事。

很久很久以前~~~(^_^),有一個建築師,他修建了許多建築,當地的人都十分尊敬他,因為他修建的房屋,是最牢固最美觀的,但是他自己一直在問自己:“質量可以客觀評價嗎?”這位建築師最感興趣的一種美就是建築質量:是什么讓我感覺一個建築設計是優秀的?

   

    “評價一個建築物是否美觀”不僅僅是一個品味的問題。還需要通過可以衡量的客觀標准來描述美觀程度,比如質量,創意什么的。

    我們軟件的構建,也如同建築學一樣。需要設計,需要規划,它們有太多的相似的地方了。

    我們也可以試着問自己:

        優秀設計能表現而劣質設計不能表現什么?

        劣質設計能表現而優秀設計不能表現的又是什么?

    嗨!是否很矛盾呢?

    沒關系,故事還沒講完,建築師觀察了許多的建築,城鎮,街道,以及人們的生活環境。他發現,對於任何特定的建築物,優秀的結構之間,總有一些相同之處。

    建築結構不相同,他們類型相同,盡管如此,他們仍是高質量的。

    比如說我們每天使用的電腦,新產品的型號不同,但是他們終究是電腦,他們既然要銷售,電腦就必須是高質量的。(你見過劣質電腦,能打鋪天蓋地的廣告嗎?)

    建築師通過這樣的方式,觀察解決相似問題的不同解決方案,一步步縮小他的關注焦點,他可以洞察出優質設計之間的相似之處,並把這些相似之處稱為”模式”。

    聰明的建築師,把模式定義為“在某一個情景下的問題解決方案”。

    每個模式,通過一種讓你可以無數次使用這一解決方案、而不必再次重復同樣的工作方式,描述一個在我們環境中重復出現的問題,並描述該問題解決方案的核心。

    用簡單的例子來描述一下這個有點復雜的概念:

        建築師需要修建一個庭院

        然后建築師就會對於這個庭院有自己的構思:庭院可以享受陽光,享受星辰,要有私有的戶外空間,需要些花花草草,有條件修建個小水池也不錯。

        然后建築師,再向庭院主人詳細問下個人的獨特需求,然后建築師就能開工

在這里,建築師的思考過程,就是我們所提到的模式,模式它有一個名稱,在這里就是個庭院模式。然后他有個目的:幫助人們在其中生活。

    為什么說這個庭院是一個優秀的庭院?建築師修建了許許多多的庭院,他知道什么樣的庭院才是適合人們的,符合人們習慣的,他有經驗。然后它可以復用自己的經驗,優秀的建築師所設計的,一定是美的。

經驗,可以使人們少走彎路,借鑒經驗,從而加速達成目的。

模式幾乎存在所有的設計問題中。

每個模式描述,都由下面4個組成部分:

  • 模式的名稱
  • 模式的目的,它要解決的問題
  • 我們如何實現它
  • 為了實現它我們必須考慮的限制和約束

建築師有一顆追求美的心。

 

好啦^_^,故事講完啦,我們回到正題,軟件設計模式。

“四人組”的《設計模式》是一部經典之作,很經典。

也許你都看過這本書了,知道這里面收錄了23個模式。

在這需要認識到的是:

    這幾位作者並不是書中這些模式的創建者。幾位作者識別除了那些已經存在於軟件社群中的模式,“從特定問題的優質設計中學到的經驗”。

任何一個模式描述都需要包括下面的基本要素:

名稱 每個模式都有一個獨一無二名稱,人們用名稱來鑒別模式
意圖
模式的目的
問題 模式視圖解決的問題
解決方案 對於自己出現的場景中的問題,模式怎樣提供一個解決方案
參與者和協作者
模式包括的實體
效果 使用模式的效果,使用模式的同時研究其約束
實現 怎樣實現模式。實現只是模式的具體表現形式。
Gof參考 在四人組的書中得到更多信息的位置

現在大家應該知道什么是設計模式了吧?現在再來完成一個大家疑惑的問題。

為什么要學習它們?

我們知道,學習寫模塊化的軟件,能使軟件復用

現在要讓大家知道,學習設計模式,能夠復用解決方案,通過復用已經建立的設計,能為自己遇到的問題找到更高的起點,並避免了繞彎路。

受益於學習別人的經驗。不必再為普通、重復的問題重新設計解決方案。有沒用聽起來很熱血澎湃的感覺?最起碼我是如此,代碼重用不厲害,思想重用才厲害^_^。

第二點:

建立通用的術語,在交流於協作時,都需要一個共同的詞匯基礎、一個對問題的共同觀點。設計模式在項目的分析和設計階段提供了一個通用的參考點。

第三點:

對於問題、設計過程和面向對象,模式給你一個更高的層次的視角。你能從過早處理細節的通病中解放出來。(別以為處理細節不嚴重,繁瑣的細節,讓我崩潰,深有感觸T-T)

不好理解這一點? 沒關系,看個簡單的模擬場景:

假設有兩個木匠正在討論如何為櫥櫃制作抽屜的問題。

木匠1:”你認為我們應該怎樣制作這些抽屜呢?“

木匠2:“我想我們應該這樣做結合部分,在木材上直鋸下去,然后回轉45°鋸,然后再直鋸下去,再朝另一個方向回轉45°鋸,再....然后......”(他在扯細節問題!!)

現在,你的的工作就是弄明白他們究竟在說些什么!看看分解之后的:

這里有些誇大了,真正的木匠師傅,並不會真的在細節的層次上說話,他們會用專業術語。

木匠1:我們應該用一個燕尾接合還是一個斜面接合?

這就是上面說的,建立通用術語,然后在高層次講述問題。假如讓你選擇和他們其中一個人合作,你會選擇誰?

模式能讓我們同時看到樹木和森林。

第四點:

學習設計模式,最重要的原因:它,能改表你的思想,讓你成為更有力的分析者。

第五點:

它能提高你的效率,頭腦思考的效率。別人是單核,而你是雙核,這多么爽呀?

五點足夠讓你很有成就感了,其實好處不僅僅只有這些。

 

當在團隊中,設計模式既可以幫助單個開發者學習,也可以幫助團隊開發。這是因為,團隊中的低級成員看到懂得設計模式的高級開發者從模式中獲益,於是這些低級成員也想得到這些好處,這為他們學習這概念提供了有理的動機。

    大多數設計模式還讓軟件更具可修改性,需求永遠都在變,能適應變換的設計模式,讓維護軟件成為一種輕松的工作,還有什么理由不去學習?

我們知道,底層建築決定高層建築,在某種程度上,高層建築能也能反饋底層建築更多的信息。

  在設計模式被正確傳授時,可以大大增加學習者對基本面向對象設計原則的理解。(對於這一點,我是深有感觸)在我學習設計模式時,使用它們來說明基本面向對象概念(封裝、繼承、多態等)在你學習了一些設計模式之后,即使你並不直接使用設計模式,你也會在自己的設計問題中使用這些策略。

    設計模式還有一個優點,能讓你或你的Team可以為不需要巨大繼承體系的復雜問題創建設計方案。

    總結:

    學習這些可以幫助你:

  • 復用現有的、高質量的、針對常見的重復出現問題的解決方案。
  • 建立通用的術語,改善團隊內部的溝通。
  • 將思考轉移到更高的視角。
  • 判斷是否擁有正確的設計,而不僅僅是一個可以運行的設計。
  • 改善個人學習和團隊學習。
  • 改善代碼的可修改性。
  • 促進對改良設計的選用,升值在沒有明確使用模式的時候。
  • 發現“龐大的繼承體系”的替代方案。

(吐血,下面又是第二寫!!!自動保存個又坑我。以后再也不拿這個網頁寫隨筆!憤怒

好處差不多講完了,現在來看些能夠提高理解設計模式的具體方法。

has-a關系和is-a關系:

為什么要講這個關系?園子里其實有人已經講過這兩個關系。我覺得這兩個關系本該通俗易懂的,用簡單的例子里整合一下,免得新手再去找相關關系去理解,太麻煩。(知道此關系的可以跳過此處,看看下面的UML介紹^_^)

has-a關系:

一個類“包含”另一個類。

一個簡單的比喻就是,汽車他就是一個has-a的關系,汽車由各種配件組成,方向盤,發動機,輪胎等。

使用組合的可以把簡單的東西組合成一個系統。組合就意味着可替換,一部分壞了,你可以選擇修,也可以選擇換。換好之后意味着,整個系統依舊良好的運行。

組合還有個優點,使用組合可以獨立創建系統和子系統,更重要的是可以獨立的進行測試和維護。(我深知其中好處,各種復用啊)

組合有兩種類型,一種是關聯(也叫組合,為了區別一下,我用關聯),一種聚合。

關聯:汽車就是關聯,它由各個組件組合而成。

聚合:輪胎就是個很好的例子。

is-a關系:

“是一個”關系。看看圖:

dogUML圖可能大家還沒熟悉,下面我也會簡單介紹一下,幫助大家打下閱讀UML圖的基礎。

在這里我可以說:狗是一種動物,代碼表示就如下

Dog D=new Dog();

Mammal M = D;

這沒錯,狗和頭有關系,但我們不能這么寫:

Dog D = new Dog();

Head H = D;

這明顯是錯的,狗有頭,但有頭的不一定是狗,它可以是別的。比如貓。

在這個圖的關系中,我們還可以給狗命名,就好像這樣寫:

Dog D = new Dog();

Nameable N = D;

它運行的很好,也很自然,一個名字代表一條狗。

在這個關系圖中,我們用到了繼承和接口。

我們知道,能繼承的不僅是基類,它也可以是接口。

繼承和接口都是構成is-a關系的簡單而有效的證據。啰嗦一點,接口其實也有個關系在里面:

    can-do關系:看一個接口的時候,主要看它能做什么。例如:一個類型能將自己的實例轉換為另一個類型(IConvertible),用過Framework 提供的接口的同學,更能體會。

組合和繼承是創建類的主要形式。

包含往往比繼承更可取,除非你要對“is-a“關系建模。

繼承是一種有用的工具,但它卻會增加復雜度,復雜度是軟件管理的首要殺手。

UML基本語法注解:

方法內"+"表示Public,“-”表示Private,還有一個“#”這里沒有提到,表示Protected,它很少用到。

在方法后面,還有一些setName:void和getName:String只代表這個方法的返回類型。

括號內的就是參數列表。

這張圖我們要關注的就是那個空心箭頭,它表示繼承金毛獵犬繼承於狗類。

這個就關注空心棱形。它表示組合,方向盤是汽車的一部分。

這個也簡單。連接線就是代表關聯,客戶端和服務端就是關聯的,再看一張前面介紹過的圖:

dog

虛線三角箭頭代表繼承自接口,而接口的描述方式就是箭頭指向的樣子interface。

 

使用UML來輔助設計非常有用,這里簡單的介紹是為了讓大家更能看懂設計模式的類圖說明,UML的完整講述就需要一本書了。

盡管UML重要,但學習OO技能更為重要,先學習OO的基礎概念,才能看懂UML圖。

 

圖是輔助,輔助大腦更好的思考。

但這里提議的是:

無論你用什么例子,都應該把注意力放在OO概念上。

 好了,基礎就講述這么多了,願大家在設計模式的學的輕松^_^


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM