1. 程式人生 > >十年Java”老兵“淺談源碼的七大設計模式

十年Java”老兵“淺談源碼的七大設計模式

delegate use 集中 提取 私有構造函數 經紀人 返回 課程 房子

一個專業的程序員,總是把代碼的清晰性,兼容性,可移植性放在很重要的位置。他們總是通過定義大量的宏,來增強代碼的清晰度和可讀性,而又不增加編譯後的代碼長度和代碼的運行效率;他們總是在編碼的同時,就考慮到了以後的代碼維護和升級。甚至,只要分析百分之一的代碼後,你就會深刻地體會到,什麽樣的代碼才是一個專業的程序員寫的,什麽樣的代碼是一個業余愛好者寫的。而這一點是任何沒有真正分析過標準代碼的人都無法體會到的。

本文會介紹一些經典的設計模式思想:

Proxy代理模式

代理模式:為其他對象提供一種代理以便控制對這個對象的訪問。

可以詳細控制訪問某個類(對象)的方法,在調用這個方法前作的前置處理(統一的流程代碼放到代理中處理)。調用這個方法後做後置處理。

代理模式分類:

1.靜態代理(靜態定義代理類,我們自己靜態定義的代理類。比如我們自己定義一個明星的經紀人類)

2.動態代理(通過程序動態生成代理類,該代理類不是我們自己定義的。而是由程序自動生成)比較重要!!

JDK自帶的動態代理

javaassist字節碼操作庫實現

CGLIB

ASM(底層使用指令,可維護性較差)

結構組成

代理模式主要涉及到三個角色:抽象角色、代理角色、真實角色(被代理的角色)。

抽象角色:聲明真實對象和代理對象的共同接口。即真實對象和代理對象共同要實現的行為動作(好比房東和中介都要能夠實現租房的行為,都能把房子租給你)。

代理角色:代理角色內部含有對真實角色的引用,從而可以去操作真實對象,同時代理對象提供與真實對象的接口,以便在任何時候都能代替真實對象。同時,代理對象在執行真實對象的操作時,也能附加它自己的操作,相當於對真實對象的封裝

真實角色:代理角色所代理的對象,亦即我們最終要引用的對象。

Factory工廠模式

工廠模式主要是為創建對象提供過渡接口,以便將創建對象的具體過程屏蔽隔離起來,達到提高靈活性的目的。

工廠模式可以分為三類:

簡單工廠模式(Simple Factory)

工廠方法模式(Factory Method)

抽象工廠模式(Abstract Factory)

這三種模式從上到下逐步抽象,並且更具一般性。GOF在《設計模式》一書中將工廠模式分為兩類:工廠方法模式(Factory Method)與抽象工廠模式(Abstract Factory)。將簡單工廠模式(Simple Factory)看為工廠方法模式的一種特例,兩者歸為一類。

區別:

工廠方法模式:

一個抽象產品類,可以派生出多個具體產品類。

一個抽象工廠類,可以派生出多個具體工廠類。

每個具體工廠類只能創建一個具體產品類的實例。

抽象工廠模式:

多個抽象產品類,每個抽象產品類可以派生出多個具體產品類。

一個抽象工廠類,可以派生出多個具體工廠類。

每個具體工廠類可以創建多個具體產品類的實例。

區別:

工廠方法模式只有一個抽象產品類,而抽象工廠模式有多個。

工廠方法模式的具體工廠類只能創建一個具體產品類的實例,而抽象工廠模式可以創建多個。

Singleton單例模式

單例模式只能有一個實例。

單例類必須創建自己的唯一實例。

單例類必須向其他對象提供這一實例。

保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。
技術分享圖片

單例模式(Singleton)是幾個創建模式中最對立的一個,它的主要特點不是根據用戶程序調用生成一個新的實例,而是控制某個類型的實例唯一性,通過上圖我們知道它包含的角色只有一個,就是Singleton,它擁有一個私有構造函數,這確保用戶無法通過new直接實例它。除此之外,該模式中包含一個靜態私有成員變量instance與靜態公有方法Instance()。Instance()方法負責檢驗並實例化自己,然後存儲在靜態成員變量中,以確保只有一個實例被創建。

使用Singleton模式有一個必要條件:在一個系統要求一個類只有一個實例時才應當使用單例模式。反之,如果一個類可以有幾個實例共存,就不要使用單例模式。

不要使用單例模式存取全局變量。這違背了單例模式的用意,最好放到對應類的靜態成員中。

不要將數據庫連接做成單例,因為一個系統可能會與數據庫有多個連接,並且在有連接池的情況下,應當盡可能及時釋放連接。Singleton模式由於使用靜態成員存儲類實例,所以可能會造成資源無法及時釋放,帶來問題。

Delegate委派模式
委派模式(Delegate)是面向對象設計模式中常用的一種模式。這種模式的原理為類B和類A是兩個互相沒有任何關系的類,B具有和A一模一樣的方法和屬性;並且調用B中的方法,屬性就是調用A中同名的方法和屬性。B好像就是一個受A授權委托的中介。第三方的代碼不需要知道A的存在,也不需要和A發生直接的聯系,通過B就可以直接使用A的功能,這樣既能夠使用到A的各種公能,又能夠很好的將A保護起來了。

委派模式的優點:

單一一個類無法表現復雜的設計

設計拆分

方便重用

相對獨立

功能定義清晰,行為界面分離

松散耦合,容易擴展

strategy策略模式

定義一系列的算法,把每一個算法封裝起來, 並且使它們可相互替換。本模式使得算法可獨立於使用它的客戶而變化。也稱為政策模式(Policy)。(Definea family of algorithms,encapsulate each one, andmake them interchangeable. Strategy lets the algorithmvary independently from clients that use it. )

策略模式把對象本身和運算規則區分開來,其功能非常強大,因為這個設計模式本身的核心思想就是面向對象編程的多形性的思想。
技術分享圖片

當存在以下情況時使用Strategy模式

? 許多相關的類僅僅是行為有異。 “策略”提供了一種用多個行為中的一個行為來配置一個類的方法。即一個系統需要動態地在幾種算法中選擇一種。

? 需要使用一個算法的不同變體。例如,你可能會定義一些反映不同的空間 /時間權衡的算法。當這些變體實現為一個算法的類層次時 ,可以使用策略模式。

? 算法使用客戶不應該知道的數據。可使用策略模式以避免暴露復雜的、與算法相關的數據結構。

? 一個類定義了多種行為 , 並且這些行為在這個類的操作中以多個條件語句的形式出現。將相關的條件分支移入它們各自的Strategy類中以代替這些條件語句。

Prototype原型模式

原型模式的主要思想是基於現有的對象克隆一個新的對象出來,一般是有對象的內部提供克隆的方法,通過該方法返回一個對象的副本,這種創建對象的方式,相比我們之前說的幾類創建型模式還是有區別的,之前的講述的工廠模式與抽象工廠都是通過工廠封裝具體的new操作的過程,返回一個新的對象,有的時候我們通過這樣的創建工廠創建對象不值得,特別是以下的幾個場景的時候,可能使用原型模式更簡單也效率更高。

? 當一個系統應該獨立於它的產品創建、構成和表示時,要使用 Prototype模式

? 當要實例化的類是在運行時刻指定時,例如,通過動態裝載;

? 為了避免創建一個與產品類層次平行的工廠類層次時

? 當一個類的實例只能有幾個不同狀態組合中的一種時。建立相應數目的原型並克隆它們可能比每次用合適的狀態手工實例化該類更方便一些。(也就是當我們在處理一些對象比較簡單,並且對象之間的區別很小,可能只是很固定的幾個屬性不同的時候,可能我們使用原型模式更合適)。
技術分享圖片

Template模板模式

模板方法模式是一種類的行為型模式,在它的結構圖中只有類之間的繼承關系,沒有對象關聯關系。

板方法模式是基於繼承的代碼復用基本技術,模板方法模式的結構和用法也是面向對象設計的核心之一。在模板方法模式中,可以將相同的代碼放在父類中,而將不同的方法實現放在不同的子類中。

在模板方法模式中,我們需要準備一個抽象類,將部分邏輯以具體方法以及具體構造函數的形式實現,然後聲明一些抽象方法來讓子類實現剩余的邏輯。不同的子類可以以不同的方式實現這些抽象方法,從而對剩余的邏輯有不同的實現,這就是模板方法模式的用意。模板方法模式體現了面向對象的諸多重要思想,是一種使用頻率較高的模式。

模板方法應用於下列情況:

一次性實現一個算法的不變的部分,並將可變的行為留給子類來實現。

各子類中公共的行為應被提取出來並集中到一個公共父類中以避免代碼重復。首先識別現有代碼中的不同之處,並且將不同之處分離為新的操作。最後,用一個調用這些新的操作的模板方法來替換這些不同的代碼。

控制子類擴展。模板方法只在特定點調用“ hook”操作 ,這樣就只允許在這些點進行擴展。
技術分享圖片

針對這些設計模式的源碼並不是靠幾句話能講清楚的,所以我創建了一個Java架構技術交流群:688583154裏面有Java工程化、分布式、高性能、性能調優、Spring,MyBatis,Netty源碼設計模式分析等知識點講解與IT技術、IT職場、在線課程、學習資源分享等,特別註意:我們是免費分享學習資源,阿裏架構師分享知識,多年工作經驗的梳理和總結,帶著大家全面、科學地建立自己的技術體系和技術認知。進群免費獲取:
技術分享圖片

面向對象:

工作1-5年需要突破技術瓶頸;

對java工作機制,常用設計思想,常用java開發框架掌握熟練的;

十年Java”老兵“淺談源碼的七大設計模式