【1】基本概念
裝飾模式(Decorator),動态地給一個對象添加一些額外的職責,就增加功能來說,裝飾模式比生成子類更為靈活。
【2】簡單分析
我們先來看下該設計模式的UML結構圖
上圖是Decorator 模式的結構圖,讓我們可以進行更友善的描述:
Component是定義一個對象接口,可以給這些對象動态地添加職責。
ConcreteComponent是定義了一個具體的對象,也可以給這個對象添加一些職責。
Decorator是裝飾抽象類,繼承了Component,從外類來擴充Component類的功能,但對于Component來說,是無需知道Decorator存在的。
ConcreteDecorator就是具體的裝飾對象,起到給Component添加職責的功能。
【3】如何用Java語音來實作該設計模式
假設情景:某人裝扮自己形象,穿衣服,褲子,鞋子,戴帽子等來把自己給包裝起來,需要把所需的功能按正确的順序串聯起來進行控制,我們應該如何設計才能做到呢?如下,先看下代碼結構圖:
3.1 先建立一個接口類:Component.java
package com.andyidea.patterns.component;
public interface Component {
void show();
}
3.2 建立一個具體的 ConcreteComponent 來實作 Component 接口:Person.java
package com.andyidea.patterns.concretecomponent;
import com.andyidea.patterns.component.Component;
public class Person implements Component{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Person(String name){
this.name = name;
}
@Override
public void show() {
System.out.println("裝扮的" + name);
}
}
3.3 建立裝飾類 Decorator 實作 Component 接口
[html] view plaincopy
package com.andyidea.patterns.decorator;
import com.andyidea.patterns.component.Component;
public class Decorator implements Component{
private Component mComponent;
public void decoratorObj(Component component){
mComponent = component;
}
@Override
public void show() {
if(mComponent != null){
mComponent.show();
}
}
}
3.4 分别建立具體的裝飾類:Jeans.java , Pelisse.java, Sandal.java ...等等,分别繼承 Decorator.java 類:
[html] view plaincopy
package com.andyidea.patterns.concretedecorator;
import com.andyidea.patterns.decorator.Decorator;
/** 牛仔褲 */
public class Jeans extends Decorator {
@Override
public void show(){
System.out.println("穿牛仔褲");
super.show();
}
}
其餘類類似,在這裡就省略了。
3.5 用戶端測試類:
[html] view plaincopy
package com.andyidea.patterns;
import com.andyidea.patterns.concretecomponent.Person;
import com.andyidea.patterns.concretedecorator.Jeans;
import com.andyidea.patterns.concretedecorator.Sandal;
import com.andyidea.patterns.concretedecorator.TShirt;
/**
* 裝飾模式測試用戶端
* @author Andy.Chen
*
*/
public class DecoratorClient {
public static void main(String[] args) {
System.out.println("Welcome to Andy.Chen Blog!" +"\n"
+"Decorator Patterns." +"\n");
Person mPerson = new Person("Andy");
Sandal mSandal = new Sandal();
Jeans mJeans = new Jeans();
TShirt mShirt = new TShirt();
mShirt.decoratorObj(mPerson);
mJeans.decoratorObj(mShirt);
mSandal.decoratorObj(mJeans);
mSandal.show();
}
}
【4】測試顯示輸出的結果如下:
[html] view plaincopy
Welcome to Andy.Chen Blog!
Decorator Patterns.
穿涼鞋
穿牛仔褲
穿T-Shirt
裝扮的Andy
【5】總結: Decorator模式有以下的優缺點:
1. 比靜态繼承更靈活 與對象的靜态繼承相比, Decorator 模式提供了更加靈活的向對象添加職責的方式,可以使用添加和分離的方法,用裝飾在運作時刻增加和删除職責。使用繼承機制增加職責需要建立一個新的子類,如果需要為原來所有的子類都添加功能的話,每個子類都需要重寫,增加系統的複雜度,此外可以為一個特定的 Component 類提供多個 Decorator ,這種混合比對是适用繼承很難做到的。 2. 避免在層次結構高層的類有太多的特征, Decorator 模式提供了一種“即用即付”的方法來添加職責,他并不試圖在一個複雜的可訂制的類中支援所有可預見的特征,相反可以定義一個簡單的類,并且用 Decorator 類給他逐漸的添加功能,可以從簡單的部件組合出複雜的功能。 3. Decorator 與它的 Component 不一樣 Decorator 是一個透明的包裝,如果我們從對象辨別的觀點出發,一個被裝飾了的元件與這個元件是有差别的,是以使用裝飾時不應該以來對象辨別。 4. 産生許多小對象,采用 Decorator 模式進行系統設計往往會産生許多看上去類似的小對象,這些對象僅僅在他們互相連接配接的方式上有所不同。