什麼是設計模式

什麼是設計模式

設計面向對象的軟件很難,設計可複用的面向對象軟件更難。你必須找到相關的對象,以適當的粒度將它們歸類,定義類的接口和繼承層次,並建立對象之間的關鍵關係。你的設計應該能夠處理手中特定的問題,同時還能夠通用,以便處理將來的問題或其他需求,你還希望避免重新設計,或者至少以最低的代價來完成設計。有經驗的面向對象設計者都會說如果想第一次就得到正確的結果,那麼完成一種可重用的、靈活的設計將會非常困難。事實上,在完成一種設計之前,他們通常會重試多次,修改多次。

然而,這些內行設計者依然能完成良好的設計,與之對比的是,一些新手卻因太多的選擇而感到困惑,他們還常常傾向於依賴曾用過的非面嚮對象的技術來思維,對於新手來說,需要花很長的時間來了解良好的面向對象的設計,內行的人設計者就很明顯的知道這些新手的問題出在哪裏,這是什麼原因呢?

內行的設計者知道不要做的一件事是:解決任何問題都從頭做起。他們都是重用過去曾用過的方案,當發現一個好的方案時,他們會反覆的使用,這種經歷是成爲行家的必需部分。因此,你會在許多面向對象系統中看到雷和相互通信的對象的重複模式,這些模式能解決特定的設計問題並使面向對象的設計更靈活,優雅以及極度便利的可複用,它們輔助設計者根據先前的設計經驗來重用成功的設計,熟悉這些模式的設計者能夠在不用重新查找的情況下立即應用到相關的設計問題中。

用類比的方法可以證明這個觀點。小說家和劇作家幾乎很少從零開始來設計他們的情節,相反他們採取一些模式,如帶有悲劇性缺陷的主人公或者充滿浪漫色彩的小說。用同樣的方式,面向對象的設計者也使用一些模式,如用對象來表示狀態,通過添加或者移除功能的方式來裝飾對象,等等。一旦你知道這些模式,就能自動的作出很多設計決策。

我們都知道擁有設計經歷的價值,你是否曾有多次這樣的錯覺:都不知道問題出在哪裏或者怎樣解決問題就把難題給解決了!如果你還記得上一次問題的細節以及怎樣解決它的,然後你就可以重新藉助上次的經歷來完成問題而不用又重新去尋找方法。遺憾的是,我們還沒有做好把這種設計經歷用記錄的形式那個他人使用。

本書旨在記錄面向對象的軟件設計中前輩們的經驗,也可稱爲設計模式。每種模式都有系統的命名,解釋意義以及能評估相應系統的設計。我們目標是獲取人們能有效使用的設計經驗,爲此目的,我們編寫了一些最重要的設計模式,並以編目分類的形式展現出來。

設計模式可以容易的重用那些成功的設計和架構,模式中的用到的技術對於新系統的開發者也很容易獲取到,設計模式幫助你選擇可用的設計,避免影響到已有的系統結構,設計模式還可以通過提供類與對象交互的明確的規範來提高已有系統的文檔化和可維護性。僅僅使用設計模式後,設計者就可以得到更快更正確的設計。

Christopher Alexander說每種模式都描述了在我們的周遭中常常出現的問題,並提出該問題的核心解決方案,同時還用一種可以重用多次的方式來呈現。雖然Alexander談論的是建築上的模式,但他說的以適用於面向對象的設計模式。我們是方案是用對象和接口來表達而非牆壁和門窗,但是兩者共通的地方實際場景中解決問題的方法。

一般而言,每種模式有如下四種必要的元素:

1. 模式的名稱。它負責描述設計問題,解決方法以及簡短的處理結果。有名稱的模式能立即增加我們的設計詞彙,讓我們在一個更高層的抽象上做設計,可以和同事談論,還可以在文檔中使用這些詞彙。我們能輕易的思考它們,還能與其他人交流。在我們編目分類時,爲每個模式取一個合適的名稱都成了很艱難的一部分。

2. 模式應用的問題場景。它負責解釋問題場景,它可能會描述特定的設計問題,比如用對象來表示算法。也可能描述不靈活設計中的類或對象的結構。有時,當針對某些問題時,需要滿足一系列的條件才能應用相應的模式。        

3. 模式中的解決方案。它負責解釋內部的關係,職責以及協作方式。方案不會描述特定的具體的設計或實現,因爲模式就像一種模板,它可以應用在許多不同的場景中。相反,模式提供了一種抽象的描述以及一種通用的元素(類和對象)的組織。

4. 模式的處理結果。當我們描述設計決策時,即使它的結果微不足道,但是這些結果對於評估設計以及應用模式後產生的代價和收益卻很關鍵。對於軟件的影響結果常常會在時間和空間上權衡,有可能會帶來編程語言的更改或造成其他實現問題。由於在面向對象的軟件設計中,重用是很重要的考慮因素,對於模式的應用,其產生的影響就應該考慮系統的靈活性、可擴展性以及可移植性。把這些影響結果清晰的列出來有助於你理解和評估他們。

 

一個人的觀點可影響模式具體的解釋,某個人自己創建的模式可能成爲另一個人的原始基礎。對於本書,我們關注的模式是抽象的,這些模式主要描述在特定的應用場景中,通過自定義類和對象來解決常規的設計問題。

對於可複用的面向對象的設計,設計模式提供了名稱,問題的抽象,還有結構中關鍵的因素。設計模式可以確定系統中的類和實例,定義他們的角色和協作關係還有責任的分配,每種模式都關注特定的設計問題,描述了使用該模式後的一些限制以及產生的影響結果。由於,最終我們必須要實現我們的設計,我們提供了C++和SmallTalk版本的代碼來作爲演示。

即使設計模式描述的是面向對象的設計,但他們是基於主流的面嚮對象語言的,我們選擇C++的原因是:經驗源於此,而且他們也很常用。

編程語言的選擇是非常重要的,因爲它可以影響一個人的認知觀點。我們的模式語言假設是擁有Smalltalk/C++的特徵,因此這也決定了是否能實現相應的功能。如果我們選用過程語言,我們依然會在模式中涵蓋繼承、封裝、多態這些語義於,同樣,其他的面嚮對象語言也是支持這些模式的。比如,CLOS(公共Lisp對象系統,Common Lisp Object System)有多方法機制,這種特徵會造成訪問者模式的不便。事實上,Smalltalk和C++有很多不同,這足以容易的表達和區分我們的設計模式。

發佈了46 篇原創文章 · 獲贊 5 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章