1. 程式人生 > >設計模式之八 --- 裝飾模式(Decorator)

設計模式之八 --- 裝飾模式(Decorator)

【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 介面
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 類:
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原創,歡迎大家轉載,轉載請大家註明出處,謝謝!