PART1、 前言
TOPIC: 23種設(shè)計(jì)模式的趣談
收獲
- 初步理解各種設(shè)計(jì)模式
- 通過設(shè)計(jì)模式理解
- 封裝變化、多態(tài)
- 對象間松散耦合
- 針對接口編程
- 設(shè)計(jì)出易維護(hù)、擴(kuò)展、服用、靈活性好的pro
設(shè)計(jì)模式四境界
1、不會(huì)用設(shè)計(jì)模式,代碼很爛
2、學(xué)了幾個(gè)模式,胡亂套用而不自知
3、感覺很多模式很相似,不知差異處
4、靈活運(yùn)用,無劍勝有劍
PART2、創(chuàng)建型設(shè)計(jì)模式
簡單工廠模式
- 解決實(shí)例化哪個(gè)對象的問題
- 工廠類的方法一般用靜態(tài)方法,理論上可以不用靜態(tài)
- 工廠類用途:創(chuàng)建產(chǎn)品類的實(shí)例
-
UML圖
Paste_Image.png - 例子:計(jì)算器
工廠模式
- UML圖
- 比簡單工廠好在哪?
- 簡單工廠違背了開放-封閉原則
- 簡單工廠每次添加功能,都要修改工廠類
原型模式
- UML圖
-
在內(nèi)存中克隆對象
- 減少執(zhí)行new(構(gòu)造函數(shù))的次數(shù),提高執(zhí)行效率
-
使用:繼承IClonable接口,調(diào)用clone方法
-
缺點(diǎn):MemberWiseClone方法僅是淺復(fù)制
該方法作用與默認(rèn)拷貝構(gòu)造函數(shù)相同
-
實(shí)現(xiàn)深復(fù)制的方法
1、構(gòu)造函數(shù)中調(diào)用clone
2、clone中new對象
作用于拷貝構(gòu)造函數(shù)相同
-
例子:簡歷復(fù)印
建造者模式
- uml圖
- 例子:建造小人-頭-身-手-腿
- 例子:快餐流水線模式
- 將復(fù)雜對象的構(gòu)建與他的表示分離,使同樣的構(gòu)建過程可創(chuàng)建不同的表示
抽象工廠模式
-
UML
- 實(shí)質(zhì)是提供接口,創(chuàng)建一系列相關(guān)或獨(dú)立的對象,而不指定這些對象的具體類。
- 與工廠模式的區(qū)別
- 抽
- 多個(gè)抽象產(chǎn)品類,每個(gè)抽象產(chǎn)品類可以派生出多個(gè)具體產(chǎn)品類
- 一個(gè)抽象工廠類,可以派生出多個(gè)具體工廠類
- 每個(gè)具體工廠類可以創(chuàng)建多個(gè)具體產(chǎn)品類的實(shí)例
- 工
- 一個(gè)抽象產(chǎn)品類,可以派生出多個(gè)具體產(chǎn)品類
- 一個(gè)抽象工廠類,可以派生出多個(gè)具體工廠類
- 每個(gè)具體工廠類只能創(chuàng)建一個(gè)具體產(chǎn)品類的實(shí)例
- 抽
- 聯(lián)系MVC架構(gòu),多種類型數(shù)據(jù)庫實(shí)現(xiàn)形式
單例模式
- uml及代碼結(jié)構(gòu)
- 定義
- 保證一個(gè)類僅有一個(gè)實(shí)例
- 提供一個(gè)訪問他的全局訪問點(diǎn)
PART3、行為型設(shè)計(jì)模式
策略模式
定義了算法家族,分別封裝,各算法的替換不影響用戶的操作
ps:c#繼承父類的默認(rèn)訪問級別是:internal
-
簡單工廠和策略模式的差別
- 簡單工廠:
- instance = new Class(); Class.doSth();
- 傳遞相應(yīng)條件得到想要的對象,然后通過該對象實(shí)現(xiàn)算法的操作
- 策略模式:
- instance.doSomething();
- 創(chuàng)建一個(gè)想要的對象,將該對象作為參數(shù)傳遞進(jìn)策略類,通過該對象調(diào)用不同的算法
- 簡單工廠:
UML圖
- 例子:商場收銀系統(tǒng)
模板方法模式
- 將不變的行為放在父類,去除子類中重復(fù)的代碼
- 例子:.net中的母版模式
- 實(shí)現(xiàn)代碼復(fù)用
觀察者模式
- JAVA中的設(shè)置監(jiān)聽器Listener和C#中的時(shí)間響應(yīng)機(jī)制都運(yùn)用了該模式
- uml圖
- 概念
- 定義一對多的依賴關(guān)系,讓多個(gè)觀察者同時(shí)監(jiān)聽某一主題對象
- 主題對象狀態(tài)發(fā)生變化,會(huì)通知所有觀察者對象,使他們能自動(dòng)更新自己
- 應(yīng)用場合:當(dāng)一個(gè)對象的改變需要同時(shí)改變其他對象的時(shí)候
狀態(tài)模式
- 定義:允許一個(gè)對象在其內(nèi)部狀態(tài)改變時(shí)改變它的行為。對象看起來似乎修改了它的類
- 應(yīng)用場景
- 1、一個(gè)對象的行為取決于它的狀態(tài)
- 2、代碼中包含大量與對象狀態(tài)有關(guān)的條件語句
- UML圖
- 目的:消除龐雜的條件語句
備忘錄模式
- 定義
在不破壞封閉的前提下,捕獲一個(gè)對象的內(nèi)部狀態(tài),并在該對象之外保存這個(gè)狀態(tài) -
uml
- 缺點(diǎn):狀態(tài)數(shù)據(jù)過多的話,備忘錄對象會(huì)很耗內(nèi)存
迭代器模式
- 定義:順序訪問聚合對象中各個(gè)元素,且不暴露內(nèi)部表示
- 該模式已經(jīng)內(nèi)嵌于許多編程語言中了
- uml
命令模式
- uml
- 定義
- 將請求封裝為對象,將發(fā)出命令與執(zhí)行命令的責(zé)任分隔開
- 實(shí)現(xiàn)行為請求者和行為實(shí)現(xiàn)者的松耦合
職責(zé)鏈模式
- 定義
- 包含了一些命令對象和一系列的處理對象
- 處理對象形成一條鏈條
- 每一個(gè)處理對象決定它能處理哪些命令對象,不能處理的命令對象傳遞給該鏈中的下一個(gè)處理對象
- uml圖
- 職責(zé)鏈的設(shè)計(jì)動(dòng)機(jī):職責(zé)鏈將請求的發(fā)送者和請求的處理者解耦
中介者模式
- 定義
- 用一個(gè)中介對象來封裝一系列的對象交互
- 通過中介對象來封裝對象之間的關(guān)系,使各個(gè)對象在不知道其他對象的具體信息情況下通過中介者對象來與之通信
- 結(jié)構(gòu)圖:類似星型拓?fù)浣Y(jié)構(gòu)
- uml圖
- 缺點(diǎn)
- 需要知道所有的具體同事類,封裝具體同事類之間相互關(guān)系
- 中介者對象變得非常復(fù)雜,系統(tǒng)維護(hù)起來較為困難
解釋器模式
訪問者模式
PART4、結(jié)構(gòu)型設(shè)計(jì)模式
裝飾模式
- 動(dòng)態(tài)給對象添加額外職責(zé)
- 對已有功能動(dòng)態(tài)添加更多功能的一種方式
- 好處:區(qū)分類的核心職責(zé)和裝飾功能
- UML圖
- 例子:穿衣
代理模式
- 類似回調(diào)函數(shù)
- 為外部對象提供代理以控制內(nèi)部對象的訪問
應(yīng)用場景:
-
遠(yuǎn)程代理
- 隱藏一個(gè)對象存在于不同地址空間的事實(shí)
- 例子:webservice
`
-
虛擬代理
- 瀏覽器瀏覽網(wǎng)頁原理
- 通過使用過一個(gè)小的對象代理一個(gè)大對象
- 就可以減少系統(tǒng)的開銷
-
安全代理
- 控制真實(shí)對象訪問時(shí)的權(quán)限
-
智能指引
- 跟智能指針shared_ptr有什么關(guān)系?
UML圖
外觀模式
- uml圖
- 例子:炒股&炒基金
- 例子:三層架構(gòu)中層與層之間使用的就是外觀模式
- 例子:當(dāng)大型系統(tǒng)代碼臃腫難以維護(hù)時(shí),可用外觀模式重新定義接口,從而達(dá)到重構(gòu)的目的
適配器模式
- 定義
把一個(gè)類的接口變換成客戶端所期待的另一種接口
Adapter模式使原本因接口不匹配(或者不兼容)而無法在一起工作的兩個(gè)類能夠在一起工作。 - UML圖
-
應(yīng)用場景
- 兩個(gè)類所做的事情相同或類似,但有不同接口時(shí)使用
-
例子:.net中的DataAdapter
- 用途:用作DataSet和數(shù)據(jù)源之間的適配器,以便檢索和保存數(shù)據(jù)
- 數(shù)據(jù)源可來自SQL Server或者Oracle、mysql,數(shù)據(jù)組織形式上會(huì)有不同
- DataSet形式:實(shí)質(zhì)是XML數(shù)據(jù)形式
組合模式
- 定義
- 將對象組合成樹形結(jié)構(gòu)以表示“部分整體”的層次結(jié)構(gòu)
- 使得用戶對單個(gè)對象和組合對象的使用具有一致性
- uml
- 應(yīng)用場景
- 你想表示對象的部分-整體層次結(jié)構(gòu)
- 忽略組合對象與單個(gè)對象的不同
橋接模式
- uml圖
- 定義
- 將抽象部分與它的實(shí)現(xiàn)部分分離,使它們都可以獨(dú)立地變化
- 實(shí)現(xiàn)系統(tǒng)可能有多角度分類,每種分類都可能變化
- 策略:多角度分離出來讓他們獨(dú)立變化,減少耦合
- wiki
- 把事物對象和其具體行為、具體特征分離開來,使它們可以各自獨(dú)立的變化
- 例子
- “圓形”、“三角形”歸于抽象的“形狀”之下
- “畫圓”、“畫三角”歸于實(shí)現(xiàn)行為的“畫圖”類之下,然后由“形狀”調(diào)用“畫圖”。
享元模式
- 運(yùn)行共享技術(shù)有效地支持大量細(xì)粒度對象的復(fù)用
- 極大的減少系統(tǒng)中對象的個(gè)數(shù)
- 享元模式由于使用了外部狀態(tài),外部狀態(tài)相對獨(dú)立,不會(huì)影響到內(nèi)部狀態(tài),所以享元模式使得享元對象能夠在不同的環(huán)境被共享
- 缺點(diǎn):需要區(qū)分外部狀態(tài)和內(nèi)部狀態(tài)
- 應(yīng)用場景:一個(gè)系統(tǒng)中存在大量的相同或者相似的對象
PART5、面向?qū)ο笙嚓P(guān)要點(diǎn)、法則
1、UML圖的關(guān)系
- 接口繼承關(guān)系
- 關(guān)聯(lián)關(guān)系:類內(nèi)定義關(guān)聯(lián)類
- 依賴關(guān)系:傳參
- 聚合關(guān)系
- 組合關(guān)系
2、單一職責(zé)原則
- 就一個(gè)類而言,僅有一個(gè)引起類變化的原因
- 軟件設(shè)計(jì)要做的內(nèi)容:發(fā)現(xiàn)職責(zé),把職責(zé)相互分離
3、開放-封閉原則
- 軟件實(shí)體(類、模塊、函數(shù))推薦擴(kuò)展,不宜修改
- 對擴(kuò)展開放,對更改封閉
- 多擴(kuò)展、少修改
- 設(shè)計(jì)出易維護(hù)、不易出問題的最好方法
4、依賴倒轉(zhuǎn)原則
- 高層模塊不依賴底層模塊,而都應(yīng)該依賴抽象(接口)
- 抽象不依賴細(xì)節(jié),而應(yīng)細(xì)節(jié)依賴抽象
- 針對接口編程,不對實(shí)現(xiàn)編程
5、里氏代換原則
- 子類型必須能夠替換掉它的父類型
- 即是能實(shí)現(xiàn)多態(tài)?
6、迪米特法則
- 兩個(gè)類不必彼此直接通信的話,那么兩個(gè)類不應(yīng)發(fā)生直接相互作用
- 例子:IT部報(bào)到,小張,小李
- 強(qiáng)調(diào)松耦合
7、方法過長是壞味道