java常用設計模式 原

設計模式:面向接口和抽象類編程,依賴接口或抽象類而不依賴具體實現

一、創建型

1、工廠方法(Factory Method

a、普通工廠:根據不同參數返回創建的不同對象。
b、工廠方法:根據不同方法返回創建的不同對象。
c、靜態工廠:將方法改爲static類型。

場景:Spring容器

Spring容器是最大的工廠,不僅提供了創建bean的功能,還管理bean的生命週期和bean之間的依賴關係。

ApplicationContext ctx = new FileSystemXmlApplicationContext("bean.xml");  
Person p = (Person)ctx.getBean("chinese");  

2、抽象工廠(Abstract Factory)

對不同工廠的一個抽象,先創建工廠再創建對象。

3、單例(Singleton)

1、懶漢式:在使用時進行初始化。
2、餓漢式:類加載時就初始化。

最常用:雙檢鎖/雙重校驗鎖(DCL,即 double-checked locking)

public class Singleton {  
    private volatile static Singleton singleton;  
    private Singleton (){}  
    public static Singleton getSingleton() {  
    if (singleton == null) {  
        synchronized (Singleton.class) {  
           if (singleton == null) {  
               singleton = new Singleton();  
           }  
        }  
    }  
    return singleton;  
    }  
}

場景:Spring中的bean默認都是單例的(id一樣的只有一個實例),降低了bean創建和銷燬時的開銷。

二、結構型

4、適配器(Adapter):適配器模式就是把一個類的接口變換成客戶端所能接受的另一種接口,從而使兩個接口不匹配而無法在一起工作的兩個類能夠在一起工作。

a、類的適配器:適配器繼承已有的類,實現想要的目標接口。
b、對象適配器:適配器引用已有的對象,實現想要的目標接口。
c、接口適配器:適配器作爲一個抽象類實現已有接口的方法,子類繼承此抽象類重寫自己需要的方法即可。

場景:Java I/O中的InputStreamReader,實現了Reader接口並且持有InputStream的引用,其作用是將InputStream適配到Reader。源角色就是InputStream代表的實例對象,目標角色就是Reader類

5、裝飾器模式(Decorator):一般我們爲了擴展一個類經常使用繼承方式實現,但隨着擴展功能的增多子類會很膨脹。在不想增加很多子類的情況下可以使用裝飾器模式,它相比生成子類更爲靈活(裝飾類和被裝飾類可以獨立發展,不會相互耦合,裝飾模式是繼承的一個替代模式)。

場景:BufferedInputStream extends FilterInputStream,FilterInputStream爲裝飾類(實現了InputStream並持有InputStream對象的引用),BufferedInputStream爲裝修類的具體實現者

6、代理模式(Proxy):創建對象的代理類以實現對這個對象的訪問控制。

場景:SpringAOP功能,使用Advice(通知)來增強被代理類的功能(1、JDK動態代理,2、CGLib字節碼生成技術代理),生成代理類,並在代理類的方法前設置攔截器,通過執行攔截器中的內容增強了代理方法的功能,實現面向切面編程。

7、橋接模式(Bridge):把抽象化與實現化解耦,使得二者可以獨立變化。

場景:1、JDBC橋DriverManager,JDBC進行連接數據庫的時候,在各個數據庫之間進行切換,基本不需要動太多的代碼,甚至絲毫不用動,原因就是JDBC提供統一接口,每個數據庫提供各自的實現,用一個叫做數據庫驅動的程序來橋接就行了。

2、slf4j-log4j12.jar橋接器:是slf4jlog4j的橋接器(日誌門面接口-->橋接器-->日誌框架,jcl-over-slf4j.jar橋接器:其它日誌框架API轉調回slf4j
直接使用具體日誌框架API喪失了更換日誌框架的靈活性。日誌門面接口提供了一套獨立於具體日誌框架實現的API,應用程序通過使用這些獨立的API就能夠實現與具體日誌框架的解耦。日誌門面接口本身通常並沒有實際的日誌輸出能力,它底層還是需要去調用具體的日誌框架API的,也就是實際上它需要跟具體的日誌框架結合使用。由於具體日誌框架比較多,而且互相也大都不兼容,日誌門面接口要想實現與任意日誌框架結合可能需要對應的橋接器,就好像JDBC與各種不同的數據庫之間的結合需要對應的JDBC驅動一樣。

三、行爲型

8、策略模式(strategy):定義一系列的算法,把它們一個個封裝起來, 並且使它們可相互替換。

場景:Spring中的策略模式使用多如牛毛,Spring的事務管理機制就是典型的策略模式,Spring事務策略是通過PlatformTransactionManager接口實現的,它是整個Spring事務的核心。它是對事務策略的一個高度抽象,不依賴於任何具體的事務策略,而對於底層的具體的事務策略它相應的有不同的實現類。而對於不同的事務策略的切換通常由Spring容器來負責管理,應用程序既無須與具體的事務API耦合,也無須與特定的實現類耦合而將應用和持久化技術,事務API徹底分離開來。

9、模板方法(Template Method):用一個抽象類定義執行它的方法的方式/模板,子類可以按需要重寫方法實現,但調用將以抽象類中定義的方式進行,爲防止惡意操作,一般模板方法都加上 final 關鍵詞。

場景:
a、繼承抽象類:AQS
b、作爲一個參數(回調函數)傳給父類。Template Method模式一般是需要繼承的。這裏想要探討另一種對Template Method的理解。spring中的JdbcTemplate,在用這個類時並不想去繼承這個類,因爲這個類的方法太多,但是我們還是想用到JdbcTemplate已有的穩定的、公用的數據庫連接,那麼我們怎麼辦呢?我們可以把變化的東西抽出來作爲一個參數傳入JdbcTemplate的方法中。但是變化的東西是一段代碼,而且這段代碼會用到JdbcTemplate中的變量。怎麼辦?那我們就用回調對象吧。在這個回調對象中定義一個操縱JdbcTemplate中變量的方法,我們去實現這個方法,就把變化的東西集中到這裏了。然後我們再傳入這個回調對象到JdbcTemplate,從而完成了調用。這可能是Template Method不需要繼承的另一種實現方式吧。

 

Ref:

https://blog.csdn.net/xiaokang123456kao/article/details/76268527

http://www.runoob.com/design-pattern/design-pattern-tutorial.html

https://blog.csdn.net/shizhan84/article/details/80093917

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章