JAVA常用的七种设计模式
學習設計模式之前,我們先要了解一下設計模式的怎么來的?
對于設計人員,特別是開發人員嗎,往往受限于眼界或經驗不能夠體會到設計原則的實用性,或者在處理具體問題時,不知道如何把設計原則應用到到設計和代碼,因此產生了“模式”。
 隨著參與的項目越來越多,人們發現:很多問題并不是一個項目中出現的,它會在很多的項目中出現。于是人們就把這些問題總結出來,然后給出了解決這些問題的方案,而這些方案–“模式”(解決問題的套路)。
設計模式的分類
1.創建模式:創建一些特殊的對象,或者在特殊要求下創建對象。
 2.結構模式:主要利用組合/聚合或者繼承,讓類與類能夠形成某種關聯關系 – 代理。
 3.行為模式:刻畫了類和對象交換及分配職責的方式。
接下來我們正式介紹七種常用的設計模式
單例模式
1.餓漢模式(最基本的單例模式)
類加載時,會直接實例化單例對象,以后都返回該對象的引用。
- 缺點:類加載時,會直接實例化單例對象,不管是否使用到該單例對象,浪費內存。
 - 優點:沒有枷鎖,執行效率高,線程安全的實例。
 
2.懶漢模式(線程不安全、線程安全但效率低)
不要直接在類加載時實例化,而是在調用方法時,再實例化。
- 優點:不會占用內存
 - 缺點:安全方面 單線程情況下,是安全的,但是在多線程下,多個線程可能同時執行singleton == null 都為true,會創建多個實例在內存中。
 
2.1懶漢模式(雙重檢驗模式(線程安全,且效率高的) 把鎖的粒度變小,只鎖第一次初始化時)
- 實例會在調用getInstance方法時創建,僅在第一調用初始化時需要鎖住。
 
3.內部類實現模式
通過靜態內部類,完成單例模式的創建。
- 在外部類加載時,并不會加載內部類,也就是不會執行new 實例(),這屬于懶加載。
 - 只有第一次調用getInstance方法時,才會加載。
 
4.枚舉實現
通過枚舉創建 單例模式。
- 實現單例的最佳方法。簡潔,支持自動序列化機制,防止多次實例化,但目前還沒有被廣泛采用。
 
工廠模式
講使用者和對象的生產者進行分離。
在工廠模式中,幾乎都有三種角色,工廠(抽象工廠、具體工廠) 產品(抽象產品、具體產品) 使用者。使用者想要使用產品,不用自己去生產產品,把生產的動作交給工廠去做,使用者只需要從工廠提供產品的位置(方法)去拿就好。
-  
1.簡單工廠模式–顧客需要給出清單。
變化點在產品對象上,所以我們會抽象產品,然后通過一個工廠,根據不同的情況產生不同的產品對象。 -  
2.工廠方法模式–根據工廠能產生什么顧客拿什么。
工廠可以產生統一品牌的商品,會根據商品去抽象工廠,對每一個產品,提供一個工廠實現類。 -  
3.抽象工廠模式–根據工廠能產生什么顧客拿什么,但是工廠能產生的產品會有多種品牌。
超級工廠,可以生產不同品牌的各種產品,抽象出超級工廠,也要抽象出產品,然后根據不同的品牌給出該品牌商品的工工廠實現類。 
原型模式
根據一個已經存在的對象,創建一個和他一樣的對象。-- 克隆
淺克隆-- 利用Object中clone()實現
1.讓被克隆的類實現Cloneable接口。
2.重寫clone方法,方法訪問修飾符public。
3.對象.clone()的方式的到一個一樣的對象。
淺克隆指,被克隆的對象會產生一個新的,但是對象屬性不會產生。
public class Man implements Cloneable {private String name;public Car car = new Car();public Man clone() throws CloneNotSupportedException{Object obj = super.clone();return (Man)obj;}}深度克隆
1.克隆對象所涉及的自定義類,需要實現序列化接口。
2.在需要克隆的類中,添加一個方法,完成序列化反序列化即可。
public class Man implements Cloneable,Serializable {private String name;public Car car = new Car();public Man depthClone() throws IOException, ClassNotFoundException {//獲取對象信息,把當前對象寫入另一塊內存ByteArrayOutputStream bo = new ByteArrayOutputStream();ObjectOutputStream objOut = new ObjectOutputStream(bo);objOut.writeObject(this);//讀取內存 創建對象ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());ObjectInputStream objIn = new ObjectInputStream(bi);Object obj = objIn.readObject();return (Man) obj;}}代理模式
1.靜態代理
根據目標對象需要代理的行為,抽象出一個接口(包含了需要代理的行為),目標類和代理類都需要去實現該接口,然后將目標對象注入到代理類中,此時就可以在代理類中調用目標對象的行為,并為止附加非功能性邏輯。
2.動態代理之JDK代理
-  
第一步,實現接口InvocationHandler,然后重寫invoke方法,在invoke方法中調用目標對的方法。
 -  
第二步,提供一個自定義的方法,通過Proxy.newProxyInstance()得到代理對象。
 
3.動態代理之Cglib代理
-  
第一步,導入Cglib依賴(包)。
 -  
第二步,實現接口MethodInterceptor,重寫intercept方法,在其中完成目標對象的方法調用。
 -  
第三步,提供自定義方法,通過工具類獲取得到代理對象。
 
裝飾器模式
對象功能的擴展能夠根據需要來動態地實現。
以咖啡舉例:
-  
1.根據對象抽象一個公共的接口。
 -  
2.根據接口給出不同的實現類(主料類(主料類產生的對象就是被裝飾的對象) 和 配料類–裝飾類)。
 -  
3.在配料類中注入被裝飾的對象。
 -  
4.生產咖啡時,先生產主料(被修飾的對象),然后用配料不斷去修飾主料。
 
適配器模式
使得原本不兼容的兩個接口(功能)可以兼容 – 搭建了兩個接口間的橋梁。
class Tel{public void call(){}}class Carame{public void make(){}}class Phone extends Tel{private Carame c = new Carame();public void make(){c.make();}}實現適配器的方案,繼承或者依賴(推薦使用)
優點:
-  
可以讓沒有任何關聯的類,一起運行;
 -  
提高了類的復用
 -  
靈活性好
 
缺點:
-  
過多的使用適配器,會導致系統非常混亂,不容具體把控
 -  
java是單繼承。
 
觀察者模式
- 主題類(由它產生的對象 就是 被觀察的對象) 繼承 Observable的類。
在主題類,需要針對主題(價格的變化進行關注,設置變化點,然后通知觀察者價格有了變化)。 
- 觀察者類(由它產生的對象 就是 觀察者) 實現Observer接口。
重寫update(當主題發生變化時,會調用方法)。 
- 首先產生主題對象(被觀察對象),產生觀察者對象,然后給主題對象設置觀察者,最后通過更改主題的值,測試觀察者是否有觀測到主題值的改變。
 
總結
以上是生活随笔為你收集整理的JAVA常用的七种设计模式的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: 计算机类公务员如何提升自己,大学毕业才发
 - 下一篇: 微服务架构和SOA的区别