Java常用设计模式总结及应用场景分析
掌握常用的幾種(最起碼單例模式、工廠模式),了解其他的設計模式即可,做到手里有糧,心里不慌。首先,掌握每種模式的定義及使用場景。其次,掌握一個形象的例子,簡單的過一遍代碼。
學習設計模式的真正目的:編程時,有意識地面向接口編程,多用封裝、繼承、組合、多態等OOP思想,而不僅僅是死記幾類設計模式。
常用的設計模式分類:
創建型(創建一個對象):單例模式、工廠模式、抽象工廠模式
結構型(將幾個對象組織成一個結構):橋接模式、外觀模式、代理模式
行為型(多個對象間的通信):觀察者模式、策略模式
其中,工廠模式、橋接模式、策略模式有點像,放在一起理解(幾個對象具有共同特征,因此繼承共同的接口,然后通過工廠、橋去訪問)。另外,工廠模式和外觀模式(幾個對象間有先后關系,是串行的,而非工廠模式中的并行,因此幾個對象組合成一個外觀類,通過這個外觀類來訪問)區別很明顯,也因此放在一起理解。
參考引用:
http://www.runoob.com/design-pattern/proxy-pattern.html
https://www.cnblogs.com/maowang1991/archive/2013/04/15/3023236.html
https://www.cnblogs.com/chinajava/p/5880870.html
設計模式定義
被反復使用的,代碼設計經驗的總結。
設計模式的原則
總結起來,就是多用接口/抽象類,從而增加代碼的可擴展性(減少修改代碼)。降低模塊間的依賴和聯系。
體現了OOP的模塊化、可擴展性等特征。
工廠模式
定義與使用場合:現在需要創建幾個對象,且這幾個對象有共同特征,則不需要具體創建各個對象,而是創建對象工廠類即可。
一般常用靜態工廠模式。
例子:發送郵件和短信(共同特征:發送的消息)
- 1
- 2
- 3
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
抽象工廠模式
工廠方法模式有一個問題就是,類的創建依賴工廠類,也就是說,如果想要拓展程序,必須對工廠類進行修改,這違背了閉包原則。
定義與使用場景:同上。
例子:同上。
- 1
- 2
- 3
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
總結:如果要新增發送微信,則只需做一個實現類,實現Sender接口,同時做一個工廠類,實現Provider接口,就OK了,無需去改動現成的代碼。這樣做,拓展性較好!
所有工廠模式中,抽象工廠模式最先進。
策略模式及與工廠模式的區別
定義與使用場合:一個系統需要動態地在幾種類似的算法中選擇一種。
與工廠模式異同:實例化一個對象的位置不同。對工廠模式而言,實例化對象是放在了工廠類里面。而策略模式實例化對象的操作在調用的地方。本質都是繼承與多態。
例子: 現有 加/減/乘 幾種算法,輸入參數返回值都一樣(可以理解成類似的算法)。現在需要在調用時動態配置算法策略,實現對不同算法的調用。
- 1
- 2
- 3
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
單例模式
定義及使用場合:只有一個對象被創建。
例子:
建議采用 餓漢式 創建方法。線程安全,容易實現。初始化慢一點。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
觀察者模式
定義與使用場景:一個對象(subject)被其他多個對象(observer)所依賴。則當一個對象變化時,發出通知,其它依賴該對象的對象都會收到通知,并且隨著變化。
比如 聲音報警器和閃光燈報警器分別訂閱熱水器溫度,熱水器溫度過高時,發出通知,兩個報警器分別發聲、閃光以實現報警。
又比如很多人訂閱微信公眾號,該公眾號有更新文章時,自動通知每個訂閱的用戶。
**實現:**1,多個觀察者要訂閱這個對象 2,這個對象要發出通知
例子:
- 1
- 2
- 3
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
代理模式
定義與使用場景:一個代理類代表一個真實類的功能,通過訪問代理類來實現對真實類的訪問。
比如買火車票這件小事:黃牛相當于是火車站的代理,我們可以通過黃牛買票,但只能去火車站進行改簽和退票。
又比如需要對原有的方法進行修改,就是采用一個代理類調用原有的方法,以避免修改原有代碼。
例子:
一個真實對象realSubject提供一個代理對象proxy。通過proxy可以調用realSubject的部分功能*,并添加一些額外的業務處理*,同時可以屏蔽realSubject中未開放的接口。
1、RealSubject 是委托類,Proxy 是代理類;
2、Subject 是委托類和代理類的接口;
3、request() 是委托類和代理類的共同方法;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
橋接模式及與策略模式的區別
定義與使用場景:訪問多種數據庫驅動(多個具有共同特征的數據庫驅動),不是直接訪問,而是通過DriverManager橋來訪問。
例子: 不再具體實現了。
與策略模式的區別:(個人覺得較復雜,了解即可。本質都是面向接口編程,體現繼承與多態)
策略模式:我要畫圓,要實心圓,我可以用solidPen來配置,畫虛線圓可以用dashedPen來配置。這是strategy模式。
橋接模式:同樣是畫圓,我是在windows下來畫實心圓,就用windowPen+solidPen來配置,在unix下畫實心圓就用unixPen+solidPen來配置。如果要再windows下畫虛線圓,就用windowsPen+dashedPen來配置,要在unix下畫虛線圓,就用unixPen+dashedPen來配置。
所以相對策略模式,橋接模式要表達的內容要更多,結構也更加復雜。
外觀模式
定義與使用場景:見例子。又比如,去醫院看病,可能要去掛號、門診、劃價、取藥,讓患者或患者家屬覺得很復雜,如果有提供接待人員,只讓接待人員來處理,就很方便。
例子:計算機啟動,需要先啟動CPU,再啟動memory,最后啟動disk。這三個類之間具有先后關系(依賴關系)。
與工廠模式的區別:工程模式多個類具有共同特征(繼承一個共同的接口),是并列的。而外觀模式多個類是有先后關系,是串行的,用組合。
貼部分代碼:
public class Computer { //是組合,而非繼承。這是與工程模式的顯著區別。private CPU cpu; private Memory memory; private Disk disk; public Computer(){ cpu = new CPU(); memory = new Memory(); disk = new Disk(); } public void startup(){ System.out.println("start the computer!"); cpu.startup(); memory.startup(); disk.startup(); System.out.println("start computer finished!"); } public void shutdown(){ System.out.println("begin to close the computer!"); cpu.shutdown(); memory.shutdown(); disk.shutdown(); System.out.println("computer closed!"); } }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
生產者-消費者模式
定義與使用場景:生產者把數據放入緩沖區,而消費者從緩沖區取出數據。
例子:緩沖區一般為隊列(FIFO),但在生產消費較為頻繁時,隊列push,pop內存消耗較大,此時可以考慮環形緩沖區(以數組、鏈表方式實現)。
通過互斥鎖防止緩沖區同時讀寫。通過信號量控制緩沖區大小(滿的時候不允許寫,空的時候不允許讀)
作者:qq_14827935
來源:CSDN
原文:https://blog.csdn.net/qq_14827935/article/details/78618652
總結
以上是生活随笔為你收集整理的Java常用设计模式总结及应用场景分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++ 类中特殊的成员变量(常变量、引用
- 下一篇: java美元兑换,(Java实现) 美元