目錄java
裝飾模式能夠在不改變一個對象自己功能的基礎上給對象增長額外的新行爲。git
裝飾模式是一種用於替代繼承的技術,它經過一種無須定義子類的方式來給對象動態增長職責,使用對象之間的關聯關係取代類之間的繼承關係。在裝飾模式中引入了裝飾類,在裝飾類中既能夠調用待裝飾的原有類的方法,還能夠增長新的方法,以擴充原有類的功能。編程
裝飾模式(Decorator Pattern):動態地給一個對象增長一些額外的職責,就增長對象功能來講,裝飾模式比生成子類實現更爲靈活。裝飾模式是一種對象結構型模式。設計模式
在裝飾模式中,爲了讓系統具備更好的靈活性和可擴展性,咱們一般會定義一個抽象裝飾類,而將具體的裝飾類做爲它的子類,裝飾模式結構如圖所示:ide
原本Car只有駕駛功能,爲了動態地給Car加一些其餘的功能,好比加上一個電視,或者放幾瓶水,使用裝飾模式實現以下:性能
抽象構件類Icarthis
public interface ICar { void drive(); }
具體構建類1加密
public class Jeep implements ICar { @Override public void drive() { System.out.println("駕駛吉普車啦"); } }
具體構建類2設計
public class Lorry implements ICar { @Override public void drive() { System.out.println("開貨車啦"); } }
抽象裝飾類調試
public abstract class CarDecorator implements ICar { private ICar car; public CarDecorator(ICar car) { this.car = car; } @Override public void drive() { car.drive(); } }
具體裝飾類1
public class TvCarDecorator extends CarDecorator { public TvCarDecorator(ICar car) { super(car); } @Override public void drive() { addTv(); super.drive(); } public void addTv(){ System.out.println("爲這部車安裝了電視咯"); } }
具體裝飾類2
public class WaterCarDecorator extends CarDecorator { public WaterCarDecorator(ICar car) { super(car); } @Override public void drive() { addWater(); super.drive(); } public void addWater(){ System.out.println("爲車子放了幾瓶水"); } }
客戶端
public class Client { public static void main(String[] args) { ICar jeepCar,lorryCar,tvCar,waterCar1,waterCar2; jeepCar=new Jeep(); lorryCar=new Lorry(); tvCar=new TvCarDecorator(jeepCar); waterCar1=new WaterCarDecorator(tvCar); waterCar1.drive(); System.out.println("------------"); waterCar2=new WaterCarDecorator(lorryCar); waterCar2.drive(); } } //爲車子放了幾瓶水 //爲這部車安裝了電視咯 //駕駛吉普車啦 //------------ //爲車子放了幾瓶水 //開貨車啦
能夠將裝飾了一次以後的tvCar對象注入另外一個裝飾類WaterCarDecorator中實現第二次裝飾,獲得一個通過兩次裝飾的對象waterCar1,再調用waterCar1的drive()方法便可獲得一個既有電視機又有放了水的吉普車。
在透明裝飾模式中,要求客戶端徹底針對抽象編程,裝飾模式的透明性要求客戶端程序不該該將對象聲明爲具體構件類型或具體裝飾類型,而應該所有聲明爲抽象構件類型。對於客戶端而言,具體構件對象和具體裝飾對象沒有任何區別。
沒法單獨調用新增的行爲,好比
tvCar.addTv();
透明裝飾模式可讓客戶端透明地使用裝飾以前的對象和裝飾以後的對象,無須關心它們的區別,此外,還能夠對一個已裝飾過的對象進行屢次裝飾,獲得更爲複雜、功能更爲強大的對象。在實現透明裝飾模式時,要求具體裝飾類的operation()方法覆蓋抽象裝飾類的operation()方法,除了調用原有對象的operation()外還須要調用新增的addedBehavior()方法來增長新行爲。
爲了可以調用到新增方法,咱們不得不用具體裝飾類型來定義裝飾以後的對象,而具體構件類型仍是可使用抽象構件類型來定義,這種裝飾模式即爲半透明裝飾模式,也就是說,對於客戶端而言,具體構件類型無須關心,是透明的;可是具體裝飾類型必須指定,這是不透明的。
ICar jeepCar=new Jeep(); TvCarDecorator tvCar=new TvCarDecorator(jeepCar); tvCar.addTv();
半透明裝飾模式能夠給系統帶來更多的靈活性,設計相對簡單,使用起來也很是方便;可是其最大的缺點在於不能實現對同一個對象的屢次裝飾(由於該對象新增的方法後面加入裝飾類的時候仍是沒法調用,因此是不完全的裝飾),並且客戶端須要有區別地對待裝飾以前的對象和裝飾以後的對象。
裝飾模式下降了系統的耦合度,能夠動態增長或刪除對象的職責,並使得須要裝飾的具體構件類和具體裝飾類能夠獨立變化,以便增長新的具體構件類和具體裝飾類。在JavaIO中的輸入流和輸出流的設計、javax.swing包中一些圖形界面構件功能的加強,多重加密的設計能夠運用裝飾模式。