裝飾模式(Decorator)

1.簡介

裝飾模式指的是在不必改變原類文件和使用繼承的情況下,動態地擴展一個對象的功能。它是通過創建一個包裝對象,也就是裝飾來包裹真實的對象。

2.特點

(1) 裝飾對象和真實對象有相同的接口。這樣客戶端對象就能以和真實對象相同的方式和裝飾對象交互。

(2) 裝飾對象包含一個真實對象的引用(reference)

(3) 裝飾對象接受所有來自客戶端的請求。它把這些請求轉發給真實的對象。

(4) 裝飾對象可以在轉發這些請求以前或以後增加一些附加功能。這樣就確保了在運行時,不用修改給定對象的結構就可以在外部增加附加的功能。在面向對象的設計中,通常是通過繼承來實現對給定類的功能擴展。

3.適用場景

1. 需要擴展一個類的功能,或給一個類添加附加職責。

2. 需要動態的給一個對象添加功能,這些功能可以再動態的撤銷。

3. 需要增加由一些基本功能的排列組合而產生的非常大量的功能,從而使繼承關係變的不現實。

4. 當不能採用生成子類的方法進行擴充時。一種情況是,可能有大量獨立的擴展,爲支持每一種組合將產生大量的子類,使得子類數目呈爆炸性增長。另一種情況可能是因爲類定義被隱藏,或類定義不能用於生成子類。

4.UML類圖

角色構成:

抽象組件角色(Component):定義一個對象接口,以規範準備接受附加責任的對象,即可以給這些對象動態地添加職責。

具體組件角色(ConcreteComponent) :被裝飾者,定義一個將要被裝飾增加功能的類。可以給這個類的對象添加一些職責。

抽象裝飾器(Decorator):維持一個指向構件Component對象的實例,並定義一個與抽象組件角色Component接口一致的接口。

具體裝飾器角色(ConcreteDecorator):向組件添加職責。

5.實例代碼
 


//抽象構建角色
interface Component{
	public void Operation();
}

//具體的構建角色
class ConcreteComponent implements Component{
  //我做了一份水煮肉片
	public void Operation() {
		//完成相關的業務代碼
		System.out.println("我做了一份水煮肉片");
	}
}

//抽象裝飾器
class Decorator implements Component{
	private Component component;
	public Decorator(Component component) {
		this.component=component;
	}
	public void Operation() {
		//委託給構建
		component.Operation();
	}
}

//具體的裝飾角色A
class ConcreteDecoratorA extends Decorator{
	public ConcreteDecoratorA(Component component) {
		super(component);
	}
	public void Operation() {
		super.Operation();
		//添加你需要的職責,例如給水煮肉片撒上一些香菜
		System.out.println("給水煮肉片撒上一些香菜");
	}
	
}

//具體的裝飾角色B
class ConcreteDecoratorB extends Decorator{
	public ConcreteDecoratorB(Component component) {
		super(component);
	}
	public void Operation() {
		super.Operation();
		//添加你需要的職責,例如給水煮肉片撒上一些辣椒粉
		System.out.println("給水煮肉片撒上一些辣椒粉");
	}
	
}

public class Client{
	public static void main(String[] args) {
		Component component = new ConcreteComponent();
		Decorator decorator;
		decorator=new ConcreteDecoratorA(component);
		decorator.Operation();
		decorator=new ConcreteDecoratorB(component);
		decorator.Operation();
	}
}

6.優點

  • 裝飾模式與繼承關係的目的都是要拓展對象的功能,但是裝飾模式可以提供比繼承更多的靈活性。裝飾模式允許系統動態決定“貼上”一個需要的“裝飾”,或者“除掉”一個不需要的“裝飾”。繼承關係則不同,繼承關係是靜態的,它在系統運行前就決定了。
  • 通過不同的具體裝飾類以及這些裝飾類的排列組合,設計師可以創造出更多不同行爲的組合。

7.缺點

由於使用裝飾模式,可以比使用繼承關係需要較少數目的類。使用較少的類,當然使設計比較易於進行。但是,在另外一方面,使用裝飾模式會產生比使用繼承關係所產生的更多的對象。而更多的對象會使得查找錯誤更爲困難,特別是這些對象在看上去極爲相似的時候。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章