1. 什麼是設計模式
在四人幫的書中,引用了christopher alexander說過的一句話:「每乙個模式描述了乙個在我們周圍不斷重**生的問題,以及該問題解決方案的核心」。一般而言,乙個模式具有四個基本要素,如下:
(1)模式名稱:乙個助記名,它用一兩個詞來描述模式的問題,解決方案和效果。
(2)問題:描述了應該何時使用設計模式。它解釋了設計問題和問題存在的前因後果,它可能描述了特定的設計問題,如怎麼用物件表示演算法。
(3)解決方案:描述了設計的組成部分,他們之間的相互關係和各自的職責和協作方式。
(4)效果:描述了模式應用的效果及使用模式應權衡的問題。儘管我們描述設計決策時,並不總提到模式效果,但它們對於評價設計學則和理解使用模式的代價及好處具有重要意義。軟體效果大多關注的是時間和空間的衡量,它們也表述了語言和實現問題。因為復用是物件導向的要素之一,所以模式效果包括對系統的靈活性、擴充性或可以可移植性的影響。顯示地列出這些效果對理解和評價這些模式很有幫助。
2. 常用的23種設計模式列表
一般模式是根據兩條準則對模式進行分類,第一是目的準則,即模式是用來完成什麼工作的。模式依據其目的可分為建立型、結構型、行為型三種。建立型模式與物件的建立有關,結構型模式處理類或者物件的組合;行為模型對類或物件怎樣互動和怎樣分配職責進行描述。第二是範圍準則,指定模式主要是用於類還是用於物件。類模式處理類和子類之間的關係,這些關係通過繼承建立,是靜態的。在編譯時刻便確定下來了。物件模式處理物件間的關係,這些關係在執行時刻是可以變化的,更具動態性。在某種意義上來說,所有的模式都適用繼承機制,所以「類模式」只指哪些集中於處理類間關係的模式,而大部分模式都屬於物件模式的範疇。
建立型類模式將物件的部分建立工作延遲到子類,而建立型物件模式則將它延遲到另乙個物件種。結構型類模式使用基層機制來組合類,而結構型物件模式則描述了物件的組裝方式。行為型模式使用繼承描述演算法和控制流,而行為型模式物件則描述一組物件怎樣協作完成單個物件無法完成的任務。
3.設計模式怎樣解決設計問題
設計模式採用多種方法解決物件導向設計者經常碰到的問題,簡要列出幾個問題,並且用設計模式解決它們的方法。
(1)需找合適的物件:物件導向程式由物件組成,物件包括資料和對資料進行操作的過程,過程通常稱為方法或操作。物件在收到客戶的請求後,執行相應的操作。客戶請求是使物件執行操作的唯一方法,操作又是物件改變內部資料的唯一方法。
(2)決定物件的粒度:物件在大小和數目上變化極大,設計模式中講述了如何用物件來表示完整的子系統。
(3)指定物件的介面:物件宣告的每乙個操作指明操作名、作為引數的物件和返回值,稱為操作的型構。物件操作所定義的所有操作型構的集合稱為該物件的介面。物件介面描述了該物件所能接受的所有請求的集合。
(4)描述物件的實現:c++中介面繼承的標準方法是共有繼承乙個虛函式的類。c++中純介面繼承接近於公有繼承抽象類。純實現繼承或純類繼承接近於似有繼承。對介面程式設計而不是對類程式設計,類繼承是乙個通過復用父類功能而擴充套件應用功能的基本機制,允許你從舊物件中快速定義新物件,它允許你從已存在的類中繼承所需要的絕大部分功能,從而無需任何代價獲取新的實現。當繼承被恰當使用時,所有從抽象類中匯出的類將共享該抽象類的介面。這意味著子類僅新增或重定義操作,而沒有隱藏父類的操作,所有的子類都能響應抽象類介面中的請求,從而子類的型別都是抽象類的子型別。
只根據抽象類中的介面操作物件有兩個好處:
針對介面程式設計,而不是針對實現程式設計。不將變數宣告為某個特定的具體類的例項物件,而是讓它遵從抽象類所定義的介面,是設計模式常見的主題。當你不得不在系統某個地方例項化具體的類時,建立型模式可以幫你。通過抽象物件的建立過程,這些模式提供不同方式以是例項化建立介面和實現的透明鏈結。建立型模式確保你的系統是採用針對介面的方式書寫,而不是針對實現而書寫的。
(5)運用復用機制:物件導向系統中復用的兩種最常用的技術是類繼承和物件組合。類繼承允許你根據其他類的實現定義乙個類的實現,這種通過生成子類的復用通常稱為白箱復用。(就如測試中的白盒測試,我們知道裡面的實現細節,這裡我們知道繼承的父類的具體細節)。而物件組合要求物件具有良好定義的介面,這種復用風格被稱為黑箱復用。類繼承是在編譯時刻靜態定義的,且可直接使用,因為程式語言直接支援類繼承,類繼承可以較方便地改變被復用地實現,當乙個子類重定義一些而不是全部操作時,它也能影響它所繼承的操作,只要在這些操作中呼叫了被重定義的操作。但是類繼承也有一些不足,首先,因為繼承在編譯時刻就定義了,所以無法在執行時刻改變從父類繼承的實現,更糟糕的是,父類至少定了部分子類的具體表示。因為繼承對子類揭示了其父類的實現細節,所以繼承常被認為「破壞了封裝」。子類中的實現與父類有如此緊密的依賴關係,以至於父類實現中的任何變化必然會導致子類發生變化。當你需要復用子類時,實現上的以耐性就會產生一些問題,如果繼承下來的實現不適合解決新的問題,則父類必須重寫或被其他適合的類替換。這種依賴關係限制了靈活性並最終限制了復用性。乙個可用的解決方法就是只繼承抽象類。物件組合是通過獲得對其他物件的引用而在執行時刻動態定義的。組合要求物件遵守彼此的介面約定,進而要求更仔細得定義介面,而這些介面並不妨礙你將乙個物件和其他物件一起使用。這還會產生良好地結果,因為物件只能通過介面訪問,所以我們並不破壞分裝性,只要型別一致,執行時刻還可以用乙個物件來替換另乙個物件,更進一步,因為物件的實現是基於介面寫的,所以是實現上存在較少的依賴關係。物件組合對系統設計還有另乙個作用,即優先使用物件組合有助於你保持每個類被封裝。所以優先使用組合,而不是類繼承。委託是一種組合方法它使組合具有與繼承相同的復用能力。在委託方式下,有兩個物件參與處理乙個請求,接受請求的物件將操作委託給它的**者。
委託可以如下**所示:
class window {
public:
area()
private:
rectangle * m_rectangle;
class rectangle
private:
int width;
int height;
(6)繼承與引數型別的比較:另一種功能復用技術是引數化型別,也就是類屬或模版。它允許你在定義乙個型別時並不指定該型別所用到的其他所有型別。未經指定的型別在使用時以引數形式提供。
(7)關聯執行時刻和編譯時刻的結構:聚合和相識時這兩種結構的代表。聚合意味著乙個物件擁有另乙個物件,它們具有相同的生命期。相識意味著乙個物件僅僅知道另乙個物件,有時相識也被稱為「關聯」或「引用」關係。相識的物件可能請求彼此的操作,但是它們不為對方負責。相識是一種比聚合要弱的關係。c++中聚合通過表示真正的例項的成員變數來實現。
(8)設計應支援變化:獲得最大限度的復用的關鍵在於對新需求和已有需求發生變化時的預見性,要求你的系統設計要能夠相應得改進。一般導致重新設計原因,以及解決這些問題得設計模式:
Python設計模式(1) 設計模式的定義和分類
設計模式是經過總結 優化的,對我們經常會碰到的一些程式設計問題的可重用解決方案。乙個設計模式並不像乙個類或乙個庫那樣能夠直接作用於我們的 反之,設計模式更為高階,它是一種必須在特定情形下實現的一種方法模板。設計模式不會繫結具體的程式語言,乙個好的設計模式應該能夠用大部分程式語言實現 如果做不到全部的...
23個設計模式定義助記
1,命令模式 定義 將乙個請求封裝為乙個物件,從而使你可用不同的請求對客戶進行引數化,對請求排隊或記錄請求日誌,以及支援可撤銷的操作。2,觀察者模式 定義 定義物件間的一種一對多的依賴關係。當乙個物件的狀態發生改變時,所有依賴於它的物件都得到通知並被自動更新。3,模式 定義 為其他物件提供一種 以控...
HeadFirst設計模式之定義和分類
定義 設計模式是某種情境下,針對某類問題的解決方案。它的分類有很多,常用的分類方式有兩種。一種是按照模式的職責來劃分為的,分為建立型 結構型 行為型。建立型主要涉及到物件的建立,涉及到的模式主要有abstract factory factory method singleton builder pr...