首先,祝大家國慶快樂更啄!
這又到國慶了,7天的假期是真滴舒服居灯,你們應(yīng)該也是玩的不亦樂乎了祭务。小編也是玩了快5天了,以至于答應(yīng)朋友的項(xiàng)目今天才匆匆忙忙的寫完部署好怪嫌。然后想到自己的的事情才瑟瑟發(fā)抖义锥。
那我們步入正題,前面的文章是將分布式架構(gòu)中的各個(gè)硬件部分搭配好了岩灭,那么我們也要準(zhǔn)備自己的軟件架構(gòu)解決方案了拌倍。在這之前,我想先講講設(shè)計(jì)模式,這是非常重要的一部分了柱恤,重要到小編高中的時(shí)候就手敲了22種基礎(chǔ)設(shè)計(jì)模式的Demo数初。
設(shè)計(jì)模式
設(shè)計(jì)模式是類與類之間關(guān)系的設(shè)計(jì)方式,包含了6種基本原則梗顺,24種基礎(chǔ)設(shè)計(jì)模式泡孩。他們有些相似,有些差別甚大寺谤。有些可以單獨(dú)使用仑鸥,有些卻是需要組合時(shí)候。學(xué)習(xí)它变屁,對(duì)我們最大的幫助在于眼俊,能看的懂別人的設(shè)計(jì),以及設(shè)計(jì)出更具有復(fù)用性粟关、擴(kuò)展性的程序疮胖。
https://github.com/SkylerSkr/DesignPatternDemo
有人說很討厭理論,沒什么用
小編經(jīng)常在一些群里看到一些程序員說誊役,最討厭面視被問到IOC获列、AOP、設(shè)計(jì)模式蛔垢。搞那么多理論有什么用击孩,只要會(huì)打就行了。小編這里發(fā)表一下自己的見解鹏漆。在公司里能學(xué)到的只是業(yè)務(wù)巩梢,只要時(shí)間夠了,業(yè)務(wù)都懂了就行艺玲,是個(gè)人就可以做括蝠。但是如果你想往更上面走,就應(yīng)該學(xué)習(xí)新的東西饭聚,現(xiàn)在是微服務(wù)分布式的天下忌警,像分布式事務(wù),分布式鎖這樣的秒梳,都是從理論上先行的法绵。那些覺得只要會(huì)打,不懂得理解為什么的程序員酪碘,可能一輩子只能做個(gè)普通的碼農(nóng)了朋譬。好了下面說正題!
本文源碼鏈接
https://github.com/SkylerSkr/DesignPatternDemo
六種設(shè)計(jì)原則
單一職責(zé)原則:對(duì)于一個(gè)類而言,應(yīng)該只有一個(gè)引起他變化的原因
開放封閉原則:是說軟件實(shí)體(類,模塊,函數(shù)等等)應(yīng)該可以擴(kuò)展,但是不可以修改
依賴倒轉(zhuǎn)原則:A.高層模塊不應(yīng)該依賴底層模塊兴垦。兩個(gè)都應(yīng)該依賴抽象徙赢。B.抽象不應(yīng)該依賴細(xì)節(jié)字柠。細(xì)節(jié)應(yīng)該依賴抽象。(面向接口編程,使用IOC管理生命周期)
里斯轉(zhuǎn)換原則:子類型必須能夠替換掉他們的父類型
迪米特原則:如果兩個(gè)類不必彼此直接通訊,那么這兩個(gè)類就不應(yīng)當(dāng)發(fā)生直接的相互作用狡赐。如果其中一個(gè)類需要調(diào)用另一個(gè)類的某一個(gè)方法的話,可以通過第三者轉(zhuǎn)發(fā)這個(gè)調(diào)用
合成復(fù)用原則:盡量使用合成/聚合(組合,聚合),盡量不使用類繼承 繼承是強(qiáng)耦合的關(guān)系 用組合可以避免增長成不可控制的龐然大物
22種基礎(chǔ)設(shè)計(jì)模式
1.簡單工廠模式
是最簡單的設(shè)計(jì)模式
工廠類根據(jù)客戶需要生成對(duì)應(yīng)的對(duì)象
更加易于維護(hù)窑业,擴(kuò)展,復(fù)用
2.策略模式
定義了算法家族,分別封裝起來,讓他們之間可以相互替換,讓算法的變換不會(huì)影響到使用算法的客戶
用來封裝算法 客戶端不需要知道怎么處理的
可以簡化單元測試 對(duì)每種算法單獨(dú)測試
3.裝飾模式
動(dòng)態(tài)的給一個(gè)對(duì)象添加一些額外的職責(zé),就增加功能來說,裝飾模式比生成子類更靈活阴汇。
為已有功能動(dòng)態(tài)的添加更多的功能的一種模式
這些新添加的功能裝飾了原有的核心的功能
當(dāng)需要執(zhí)行特殊行為的時(shí)候就可以使用裝飾模式
把核心功能和裝飾功能區(qū)分開
4.代理模式
為其他對(duì)象提供一種代理以控制對(duì)這個(gè)對(duì)象的訪問
遠(yuǎn)程代理 為一個(gè)對(duì)象在不同的地址空間提供局部地址 隱藏一個(gè)對(duì)象存在不同地址空間的事實(shí)
虛擬代理 存放實(shí)例化開銷很大的真是對(duì)象
安全代理 控制真實(shí)對(duì)象的訪問權(quán)限
5.工廠方法模式
定義一個(gè)對(duì)于創(chuàng)建對(duì)象的接口,讓子類決定實(shí)例化哪一個(gè)類数冬。工廠方法使一個(gè)類的實(shí)例化延遲到其子類
簡單工廠的升級(jí)版 更加貼近開放閉合原則
為每一個(gè)子類寫一個(gè)工廠類
6.原型模式
用原型模式指定創(chuàng)建對(duì)象的種類,并且通過拷貝這些原型來創(chuàng)建新的對(duì)象
淺度復(fù)制 深度復(fù)制
是想ICloneable接口 然后重寫Clone方法 (Object)this.MemberwiseClone();
深度復(fù)制有Copy不僅復(fù)制結(jié)構(gòu)還復(fù)制數(shù)據(jù)
7.模板方法模型
定義一個(gè)操作中算法的骨架,而將一些步驟延遲到子類中节槐。模板方法使得子類可以不改變一個(gè)算法的結(jié)構(gòu)即可改變算法的某些特定步驟
把不變的行為移動(dòng)到超類里面,去除子類里的重復(fù)代碼
可以說是靠父類方法調(diào)用自己的方法
8.外觀模式
為子系統(tǒng)中的一組接口提供一個(gè)一致的界面,此模式定義了一個(gè)高層接口,這個(gè)接口使得這一子系統(tǒng)更加容易使用搀庶。
給舊系統(tǒng)一個(gè)外觀 提供接口給新系統(tǒng)用Facade
9.建造者模式
將一個(gè)復(fù)雜的對(duì)象的構(gòu)建與它的表示分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示
用建造者模式,用戶只需要指定建造的類型就可以得到它們,具體建造的細(xì)節(jié)就不需要知道了
10.觀察者模式
觀察者模式定義了一種一對(duì)多的依賴關(guān)系,讓多個(gè)觀察者對(duì)象同時(shí)監(jiān)聽某一個(gè)主題對(duì)象。這個(gè)主題對(duì)象在狀態(tài)發(fā)生變化時(shí),會(huì)通知所有的觀察者對(duì)象,使它們能夠自動(dòng)的更新自己
在.net里面有委托這個(gè)概念
delegata void EventHandler();//定義一個(gè)事件處理程序
public event EventHandler eventHandler;//定義一個(gè)委托? 就是可以傳遞的方法
委托對(duì)象所搭載的所有方法必須具有相同的原型和形式,也就是擁有相同的參數(shù)列表和返回值
當(dāng)對(duì)象相互依賴的時(shí)候可以用
11.抽象工廠模式
提供一系列相互依賴對(duì)象的接口,而無需指定它們具體的類铜异。
更加復(fù)合依賴倒轉(zhuǎn)原則,開放封閉原則
工廠方法模型的升級(jí)版 當(dāng)工廠不止生產(chǎn)一種產(chǎn)品的時(shí)候
但是會(huì)擴(kuò)展起來很麻煩 可以用反射簡化
using System.Reflection;
(Object)Assembly.Load(string 程序集).CreateInstance(string 命名空間.類名);
就是可以根據(jù)類名創(chuàng)建對(duì)象 字符串
12.狀態(tài)模式
當(dāng)一個(gè)對(duì)象的內(nèi)在狀態(tài)改變時(shí)允許改變其行為,這個(gè)對(duì)象看上去像改變了其類哥倔。
把各個(gè)狀態(tài)對(duì)應(yīng)的行為都寫一個(gè)單獨(dú)的類 類里判斷是否時(shí)這個(gè)狀態(tài) 如果不是就把該類指向下一個(gè)狀態(tài)
每一個(gè)狀態(tài)都排好順序
不用寫很多的swith ifelse 語句
13.適配器模式
將一個(gè)類的接口改變成客戶希望的另外一個(gè)接口
用于更改已經(jīng)有的類 彌補(bǔ)程序設(shè)計(jì)的失誤
包含需要具體操作的類
14.備忘錄模式
在不破壞封裝性的前提下,捕獲一個(gè)對(duì)象的內(nèi)部狀態(tài),并在該對(duì)象之外保存這個(gè)狀態(tài),這樣之后就可將該狀態(tài)恢復(fù)到原來保存的狀態(tài)
適合比較功能比較復(fù)雜,但需要維護(hù)或者記錄屬性歷史的類,或需要保存部分屬性的類
或者對(duì)象屬性即將暫時(shí)改變的時(shí)候
15.組合模式
將對(duì)象組成的樹型結(jié)構(gòu)以表示 部分-整體 的層次結(jié)構(gòu)揍庄。組合模式使得用戶對(duì)單個(gè)對(duì)象和組合對(duì)象的使用具有一致性
安全模式 把單個(gè)對(duì)象不要的方法不要寫進(jìn)父類
透明模式 讓單個(gè)對(duì)象和組合對(duì)象具有相同的接口
希望忽略單個(gè)對(duì)象和組合對(duì)象的區(qū)別 可以統(tǒng)一使用的時(shí)候使用
16.迭代器模式
提供一種方法順序訪問一個(gè)聚合對(duì)象中各個(gè)元素,而不是暴露該對(duì)象的內(nèi)部表示
c#里時(shí)foreach 實(shí)現(xiàn)了Iterator和IEumerator接口
17.單例模式
保證一個(gè)類僅有一個(gè)實(shí)例,并提供一個(gè)訪問它的全局訪問點(diǎn)
把構(gòu)造方法私有化 并在類里面包含一個(gè)該類實(shí)例化的字段
鎖 lock(Object o){}安全性
靜態(tài)初始化 占內(nèi)存
public sealed class singleton 阻止發(fā)生派生 就是不讓創(chuàng)建對(duì)象
private static readonly Singleton instance=new Singleton();
普通的 需要加lock防止多線程里生成多個(gè)對(duì)象
18.橋接模式
將抽象部分和它的具體實(shí)現(xiàn)部分分離,使他們都可以獨(dú)立的變化
實(shí)現(xiàn)系統(tǒng)可能有多種分類的可能,沒一種分類都可能變化,那么就把多種角度分離出來讓他們獨(dú)立變化,減少他們之間的耦合
19.命令模式
將一個(gè)請(qǐng)求封裝成一個(gè)對(duì)象,從而使你可用不同的請(qǐng)求對(duì)客戶進(jìn)行參數(shù)化,對(duì)請(qǐng)求排隊(duì)或記錄請(qǐng)求日志,以及支持可撤銷的操作
命令類包含執(zhí)行者 命令管理者收集命令并指揮執(zhí)行者 使請(qǐng)求者和執(zhí)行者相互不認(rèn)識(shí) 迪米塔原則
不為代碼增加猜測會(huì)需要的功能
20.職責(zé)鏈模式
使多個(gè)對(duì)象都有機(jī)會(huì)處理請(qǐng)求,從而避免請(qǐng)求的發(fā)送者和接收者之間的耦合關(guān)系,將這個(gè)對(duì)象連成一條鏈咆蒿,并沿著這條鏈傳遞該請(qǐng)求,直到有一個(gè)對(duì)象處理該請(qǐng)求
和狀態(tài)模式很像
狀態(tài)模式:需要先定義好狀態(tài)的順序(在類里面),如果處理不了就重新給狀態(tài)賦值,再執(zhí)行對(duì)象的處理方法
職責(zé)鏈模式:可以按需求在客戶端定義順序,但是設(shè)置每一個(gè)對(duì)象的下一個(gè)對(duì)象使什么。如果處理不了就運(yùn)行下一個(gè)的對(duì)象的處理方法蚂子。
21.中介者模式
對(duì)象之間的相互連接會(huì)降低復(fù)用性
用一個(gè)中介對(duì)象來封裝一系列的對(duì)象交互沃测。中介者使各個(gè)對(duì)象不需要顯示的相互引用,從而使其耦合松散,而且可以獨(dú)立的改變它們之間的交互。
迪米特原則:如果兩個(gè)沒有相互包含的必要,就找一個(gè)第三方包含這兩個(gè)對(duì)象
中介者需要包含要協(xié)調(diào)的所有對(duì)象,需要被協(xié)調(diào)的對(duì)象要認(rèn)識(shí)中介者
但是中介者類責(zé)任會(huì)非常的重,一般用于一組對(duì)象以定義良好但是以復(fù)雜的方式進(jìn)行通信的場合
22.享元模式
運(yùn)用共享技術(shù)有效的地支持大量細(xì)顆粒的對(duì)象
享元模式可以避免大量相似實(shí)例的開銷食茎。當(dāng)大量實(shí)例里除了少數(shù)幾個(gè)屬性之外都相同,可以把者幾個(gè)屬性放到外面去蒂破,然后共享實(shí)例
類里提供use方法 這個(gè)方法傳遞不一樣的屬性 工廠里判斷是否包含
23.解釋器模式
給定一個(gè)語言,定義其語法的一種表示,并定義一個(gè)解釋器,用來翻譯語句
如果一種問題發(fā)生的頻率高 就把他弄成語句分析
正則表達(dá)式
24.訪問者模式
表示一個(gè)作用于某對(duì)象(訪問者)結(jié)構(gòu)中的各元素的操作别渔。它使你可以在不改變各元素的類的情況下定義對(duì)于這些元素的新操作
在被訪問的對(duì)象數(shù)量是固定的不會(huì)改變的時(shí)候,在訪問者里定義訪問了每一個(gè)元素的操作
一般不存在固定不變的元素,所以很少使用
把訪問者當(dāng)形式參數(shù)傳給元素 然后元素的內(nèi)部把自己傳給訪問者 訪問是再訪問者里執(zhí)行的
設(shè)計(jì)模式的分類
創(chuàng)建型模式:單例模式,工廠方法模式,抽象工廠模式,建造者模式,原型模式
結(jié)構(gòu)型模式:適配器模式,裝飾模式,橋接模式,組合模式,享元模式,代理模式,外觀模式
行為型模式:觀察者模式,模板方法模式,命令模式,狀態(tài)模式,職責(zé)鏈模式
? ? 解釋器模式,中介者模式,訪問者模式,策略模式,備忘錄模式,迭代器模式
常用的模式:工廠方法模式,外觀模式,觀察者模式(委托),策略模式,適配器模式
外觀模式:在業(yè)務(wù)邏輯和表示層間增加業(yè)務(wù)外觀層,這樣不管是bs還是cs都不會(huì)影響到業(yè)務(wù)和數(shù)據(jù)的統(tǒng)計(jì)
觀察者模式:按鈕點(diǎn)擊,事件驅(qū)動(dòng)
適配器模式:有些功能是第三方軟件,購買來的,用來適配
策略模式:把統(tǒng)計(jì)業(yè)務(wù)可以需要的算法封裝起來
工廠方法模式:對(duì)象管理者,優(yōu)先使用工廠方法,如果發(fā)現(xiàn)需要再考慮抽象工廠附迷、反射技術(shù)等
相似的設(shè)計(jì)模式
有很多相似的設(shè)計(jì)模式,他們的區(qū)別只在于處理的需求不一致哎媚。
代理模式和裝飾模式:一個(gè)是加以控制喇伯,一個(gè)是加強(qiáng)功能。
適配器模式和外觀模式:一個(gè)是封裝成自己想要的參數(shù)拨与,一個(gè)是在微服務(wù)中防止程序員為實(shí)現(xiàn)一個(gè)功能調(diào)用多個(gè)api稻据、將其封裝成一個(gè),便于擴(kuò)展买喧。
身邊的設(shè)計(jì)模式
IOC:依賴注入捻悯,用于將對(duì)象的生命周期交給框架管理,根據(jù)設(shè)定好的關(guān)系來執(zhí)行創(chuàng)建任務(wù)和執(zhí)行岗喉,這本身就是一種策略模式的體現(xiàn)秋度。
AOP:面向切面編程,在java中有spring這種強(qiáng)大的工具钱床,用于在代碼執(zhí)行前后做一些事情荚斯,如果權(quán)限限制,日志記錄,全局異常事期,性能檢測等等滥壕。在MVC架構(gòu)中,以過濾器的方式體現(xiàn)兽泣。
Stream:大家一定使用過很多的流绎橘,F(xiàn)ileStream等等,這是裝飾模式唠倦。
Foreach:迭代器模式称鳞。
正則表達(dá)式:解釋器模式。
拉姆達(dá)表達(dá)式:java8以后擴(kuò)展的功能稠鼻,.Net平臺(tái)的C#在08年就推出的技術(shù)冈止,是對(duì)委托的封裝,觀察者模式候齿。
還有很多很多的設(shè)計(jì)模式已經(jīng)在我們身邊被我們使用熙暴,只是大家沒有發(fā)現(xiàn)。但是不管怎么說慌盯。學(xué)習(xí)設(shè)計(jì)模式周霉,對(duì)我們編寫代碼的能力,是非常的的提升亚皂。
參考書籍:《大話設(shè)計(jì)模式》