總體來說設計模式分為三大類:創建型模式、結構型模式和行為型模式。
結構型模式,共有七種:適配器模式、裝飾器模式、代理模式、外觀模式、橋接模式、組合模式、享元模式。
其中適配器模式主要分為三類:類的適配器模式、對象的適配器模式、接口的適配器模式。其中的對象的適配器模式是各種結構型模式的起源。
一、適配器模式
適配器模式主要分為三類:類的適配器模式、對象的適配器模式、接口的適配器模式。
適配器模式將某個類的接口轉換成客戶端期望的另一個接口表示,目的是消除由于接口不匹配所造成的類的兼容性問題。有點抽象,我們來看看詳細的內容。
1.1 類的適配器模式
類的適配器模式核心思想就是:有一個Source類,擁有一個方法,待適配,目標接口是Targetable,通過Adapter類,將Source的功能擴展到Targetable里。
public class Source {public void method1() { System.out.println("this is original method!"); }
}
public interface Targetable {/* 與原類中的方法相同 */public void method1();/* 新類的方法 */public void method2();
}
public class Adapter extends Source implements Targetable {public void method2() {System.out.println("this is the targetable method!");}
}
public class AdapterTest {public static void main(String[] args) {Targetable target = new Adapter();target.method1();target.method2();}
}
運行結果如下:
this is original method!
this is the targetable method!
1.2 對象的適配器模式
對象的適配器模式的基本思路和類的適配器模式相同,只是將Adapter類作修改成Wrapper,這次不繼承Source類,而是持有Source類的實例,以達到解決兼容性的問題。
public class Wrapper implements Targetable {private Source source;public Wrapper(Source source) {super();this.source = source;}@Overridepublic void method2() {System.out.println("this is the targetable method!");}@Overridepublic void method1() {source.method1();}
}
public class AdapterTest {public static void main(String[] args) {Source source = new Source();Targetable target = new Wrapper(source);target.method1();target.method2();}
}
運行結果跟類的適配器模式例子的一樣。
1.3 接口的適配器模式
接口的適配器是這樣的:有時我們寫的一個接口中有多個抽象方法,當我們寫該接口的實現類時,必須實現該接口的所有方法,這明顯有時比較浪費,因為并不是所有的方法都是我們需要的,有時只需要某一些,此處為了解決這個問題,我們引入了接口的適配器模式,借助于一個抽象類,該抽象類實現了該接口,實現了所有的方法,而我們不和原始的接口打交道,只和該抽象類取得聯系,所以我們寫一個類,繼承該抽象類,重寫我們需要的方法就行了。
二、裝飾模式
裝飾模式:在不必改變原類文件和使用繼承的情況下,動態地擴展一個對象的功能。它是通過創建一個包裝對象,也就是裝飾來包裹真實的對象。
裝飾模式的特點:
- 裝飾對象和真實對象有相同的接口。這樣客戶端對象就能以和真實對象相同的方式和裝飾對象交互。
- 裝飾對象包含一個真實對象的引用(reference)
- 裝飾對象接受所有來自客戶端的請求。它把這些請求轉發給真實的對象。
- 裝飾對象可以在轉發這些請求以前或以后增加一些附加功能。這樣就確保了在運行時,不用修改給定對象的結構就可以在外部增加附加的功能。在面向對象的設計中,通常是通過繼承來實現對給定類的功能擴展。繼承不能做到這一點,繼承的功能是靜態的,不能動態增刪。
代碼如下:
public interface Sourceable {public void method();
}
public class Source implements Sourceable {@Overridepublic void method() {System.out.println("the original method!");}
}
public class Decorator implements Sourceable {private Sourceable source;public Decorator(Sourceable source) {super();this.source = source;}@Overridepublic void method() {System.out.println("before decorator!");source.method();System.out.println("after decorator!");}
}
public class DecoratorTest {public static void main(String[] args) {//(1) 裝飾對象和真實對象有相同的接口。這樣客戶端對象就能以和真實對象相同的方式和裝飾對象交互。//(2) 裝飾對象包含一個真實對象的引用(reference)//(3) 裝飾對象接受所有來自客戶端的請求。它把這些請求轉發給真實的對象。//(4) 裝飾對象可以在轉發這些請求以前或以后增加一些附加功能。這樣就確保了在運行時,不用修改給定對象的結構就可以在外部增加附加的功能。// 在面向對象的設計中,通常是通過繼承來實現對給定類的功能擴展。// 繼承不能做到這一點,繼承的功能是靜態的,不能動態增刪。Sourceable source = new Source();Sourceable obj = new Decorator(source);obj.method();}
}
運行結果如下:
before decorator!
the original method!
after decorator!
======以上為創建型模式的兩種設計模式,下面陸續記錄代理等創建型模式。
為什么叫創建型模式呢?
先來看看設計模式的六大原則:http://yyqian.com/post/1456847694817/
- 開閉原則:對擴展開放,對修改關閉
- 里氏替換原則:面向對象設計的基本原則之一。==任何基類可以出現的地方,子類一定可以出現。==LSP是繼承復用的基石,只有當衍生類可以替換掉基類。
- 依賴倒轉原則:針對接口編程,依賴于抽象而不是具體。
- 接口隔離原則:使用多個隔離的接口,比使用單個接口要好。還是一個降低類之間的耦合度的意思。【降低依賴,降低耦合】
- 迪米特法則(最少知道原則):一個實體應當盡量少的與其它實體之間發生相互作用,使得系統功能模塊相對獨立。
- 合成復用原則:意思是盡量使用合成聚合的方式,而不是使用繼承。
回過頭解釋為什么叫創建型設計模式。創建型設計模式就是處理對象創建的設計模式,試圖根據實際情況使用合適的方式創建對象。基本的對象創建方式可能會導致設計上的問題,或增加設計的復雜度。創建型模式通過以某種方式控制對象的創建來解決問題。
創建型模式由兩個主導思想構成。一是將系統使用的具體類封裝起來,二是隱藏這些具體類的實例創建和結合的方式。
創建型模式又分為對象創建型模式和類創建型模式。對象創建型模式處理對象的創建,類創建型模式處理類的創建。詳細地說,對象創建型模式把對象創建的一部分推遲到另一個對象中,而類創建型模式將它對象的創建推遲到子類中。[2]
參考:
- Java經典設計模式(2):七大結構型模式
- CSDN:七大結構型模式
- 圖解設計模式
- 面試總結