設計模式之八 --- 裝飾模式(Decorator)
阿新 • • 發佈:2019-01-01
【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
3.3 建立裝飾類 Decorator 實現 Component 介面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.4 分別建立具體的裝飾類:Jeans.java , Pelisse.java, Sandal.java ...等等,分別繼承 Decorator.java 類: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(); } } }
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 客戶端測試類:
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】測試顯示輸出的結果如下:
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模式進行系統設計往往會產生許多看上去類似的小物件,這些物件僅僅在他們相互連線的方式上有所不同。
注:本文為Andy.Chen原創,歡迎大家轉載,轉載請大家註明出處,謝謝!