裝飾模式(Decorator)就是使用被裝飾的一個子類的實例,在客戶端將這個子類的實例委托給裝飾類。裝飾模式是結成關系的一個替代方案。
簡單的裝飾模式是原理圖入下:

裝飾模式以對客服端透明的方式增添了對象的功能,其在與動態的給對象添加了責任,當然這里的繼承便是靜態的。
其中重要的地方時裝飾對象和真是對象有相同的接口,這樣客戶端就可以和真是對象一樣的交互方式和裝飾對象交互,然后裝飾對象把所有從客戶端接收過來的請求全部轉發給真是對象,然后在返還給客戶端,這樣裝飾對象就可以再轉發前或者以后添加一些附加功能而不影響對真是對象的操作,這樣在不改變原有類的基礎想,可以實現對于原有類的這種額外功能的實現,增強了程序的復用性。
同時裝飾模式比繼承好的地方就是,裝飾模式可以動態的對已經存在的類進行任意的組合,實現想要的功能,而繼承是靜態的實現,不能改變原有類的實現,如果要添加更多的功能,只有添加更多的派生類來實現,這個簡潔在下面的例子里對于最后一次打印輸出就有很明顯的效果,定義好了兩個裝飾類以后,不用再定義第三個就可以實現兩個裝飾類排列組合的效果。下面就簡單的做了一個通過對于手機接電話的一個擴展,接聽電話之前有一個彩鈴,接受電話之后會回撥一段廣告,這樣就出來了下面的例子:

~~~
package com.designpattern.decorator;
public interface Phone {
public void recevieCall(String name);
}
~~~
~~~
package com.designpattern.decorator;
public class ChinaMobile implements Phone {
@Override
public void recevieCall(String name) {
System.out.println("step recevie " + name + " call");
}
}
~~~
~~~
package com.designpattern.decorator;
public abstract class Decorator implements Phone {
private Phone phone;
public Decorator(Phone phone) {
this.phone = phone;
}
@Override
public void recevieCall(String name) {
this.phone.recevieCall(name);
}
}
~~~
~~~
package com.designpattern.decorator;
public class RingBeforeChinaMobileDecorator extends Decorator {
public RingBeforeChinaMobileDecorator(Phone phone) {
super(phone);
}
@Override
public void recevieCall(String name) {
System.out.println("step ring before recevie " + name + "call");
super.recevieCall(name);
}
}
~~~
~~~
package com.designpattern.decorator;
public class AdAfterChinaMobileDecorator extends Decorator {
public AdAfterChinaMobileDecorator(Phone phone) {
super(phone);
}
@Override
public void recevieCall(String name) {
super.recevieCall(name);
System.out.println("step ad after recevie " + name + " call");
}
}
~~~
~~~
package com.designpattern.decorator;
public class Client {
public static void main(String[] args) {
Phone phone = new ChinaMobile();
Decorator decorator = new RingBeforeChinaMobileDecorator(phone);
decorator.recevieCall("andimuise");
System.out
.println("**************************");
decorator = new AdAfterChinaMobileDecorator(phone);
decorator.recevieCall("halberd");
System.out
.println("**************************");
decorator = new RingBeforeChinaMobileDecorator(
new AdAfterChinaMobileDecorator(phone));
decorator.recevieCall("teacher");
System.out
.println("**************************");
}
}
~~~
最終輸出結果為,很明顯在第三次輸出的時候我想同時實現兩種效果,就把另一個裝飾類為為了其中一個裝飾類的屬性,因為無論是裝飾類還是真實類他們是實現的共同的接口,這樣就對實現提供了很好的效果
~~~
step ring before recevie andimuisecall
step recevie andimuise call
**************************
step recevie halberd call
step ad after recevie halberd call
**************************
step ring before recevie teachercall
step recevie teacher call
step ad after recevie teacher call
**************************
~~~
- 前言
- 前言(目錄、源碼、資料)
- (一)簡單工廠模式(SimpleFatory)
- (二)工廠方法模式(FactoryMethod)
- (三)抽象工廠模式(AbstractFactory)
- (四)創建者模式(Builder)
- (五)原型模式(Prototype)
- (六)單例模式(Singleton)
- (七)外觀模式(Facade)
- (八)適配器模式(Adapter)
- (九)代理模式(Proxy)
- (十)裝飾模式(Decorator)
- (十一)橋模式(birdge)
- (十二)組合模式(Composite)
- (十三)享元模式(Flyweight)
- (十四)模板方法模式(Template)
- (十五)觀察者模式(Observer)
- (十六)狀態模式(State)