裝飾模式的UML圖和代碼示例

一、裝飾模式

1.1、定義

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

1.2、特點

(1) 裝飾對象和真實對象有相同的接口。這樣客戶端對象就能以和真實對象相同的方式和裝飾對象交互。
(2) 裝飾對象包含一個真實對象的引用(reference)
(3) 裝飾對象接受所有來自客戶端的請求。它把這些請求轉發給真實的對象。
(4) 裝飾對象可以在轉發這些請求以前或以後增加一些附加功能。這樣就確保了在運行時,不用修改給定對象的結構就可以在外部增加附加的功能。在面向對象的設計中,通常是通過繼承來實現對給定類的功能擴展。

1.3、適用條件

以下情況使用 裝飾模式:

(1)需要擴展一個類的功能,或給一個類添加附加職責。
(2) 需要動態的給一個對象添加功能,這些功能可以再動態的撤銷。
(3)需要增加由一些基本功能的排列組合而產生的非常大量的功能,從而使繼承關係變的不現實。
(4)當不能採用生成子類的方法進行擴充時。一種情況是,可能有大量獨立的擴展,爲支持每一種組合將產生大量的子類,使得子類數目呈爆炸性增長。另一種情況可能是因爲類定義被隱藏,或類定義不能用於生成子類。

1.4、優點

  • 採用裝飾模式擴展對象的功能比採用繼承方式更加靈活。
  • 可以設計出多個不同的具體裝飾類,創造出多個不同行爲的組合。

1.5、缺點

  • 裝飾模式增加了許多子類,
  • 如果過度使用會使程序變得很複雜。

1.6、代碼中的應用

IO流的操作就是典型的裝飾模式

二、裝飾者模式 UML圖

在這裏插入圖片描述

  • Component(組件) :組件接口 或 抽象類 定義了 組件實現類 和 裝飾器實現類 的行爲。

  • ConcreteComponent(組件實現類) :組件實現類 實現了 Component 接口 或 抽象類。通常情況下,具體組件實現類就是被裝飾器裝飾的原始對象,該類提供了 Component 接口中定義的最基本的功能,其他高級功能或後序添加的新功能,都是通過裝飾器的方式添加到該類的對象之上的。

  • Decorator(裝飾器) :裝飾器,它是一個實現了 Component 接口的類,並在其中封裝了一個 Component 對象,也就是 被裝飾 的對象。 而這個被裝飾的對象只要是 Component 類型,就實現 裝飾器的組合和複用 。

  • ConcreteDecorator(裝飾器子類) :該子類要向 被裝飾對象 添加某些功能 。

三、代碼示例

2.1、示例 UML圖

在這裏插入圖片描述

2.2、組件 Drink

public abstract class Drink {

	public String des; // 描述
	private float price = 0.0f;
	
	public void setDes(String des) {
		this.des = des;
	}
	
	public String getDes() {
		return des ;
	}
	
	
	public float getPrice() {
		return price;
	}
	public void setPrice(float price) {
		this.price = price;
	}
	
	//計算費用的抽象方法
	//子類來實現
	public abstract float cost();	
}

2.3、組件實現類 Coffee

public class Coffee  extends Drink {

	@Override
	public float cost() {
		return super.getPrice();
	}
}

2.4、組件子類 Espresso、CoffeeLongBlack

public class CoffeeEspresso extends Coffee {
	
	public CoffeeEspresso() {
		setDes(" 意大利咖啡 ");
		setPrice(6.0f);
	}
}


public class CoffeeLongBlack extends Coffee {
	public CoffeeLongBlack() {
		setDes(" longblack ");
		setPrice(5.0f);
	}
}

2.5、裝飾器 Decorator

public class Decorator extends Drink {
	
	private Drink obj;
	
	public Decorator(Drink obj) { //組合
		this.obj = obj;
	}
	
	@Override
	public float cost() {
		// getPrice 自己價格
		return super.getPrice() + obj.cost();
	}
	
	@Override
	public String getDes() {
		// obj.getDes() 輸出被裝飾者的信息
		return super.getDes()+" +"+obj.getDes();
	}
}

2.6、裝飾器子類 Milk、Chocolate


/**
 * Decorator 的子類, 這裏就是口味
 */
public class DecoratorMilk extends Decorator {

	public DecoratorMilk(Drink obj) {
		super(obj);
		setDes(" 牛奶 ");
		setPrice(2.0f); 
	}
}

public class DecoratorChocolate extends Decorator {

	public DecoratorChocolate(Drink obj) {
		super(obj);
		setDes(" 巧克力 ");
		setPrice(3.0f); // 調味品 的價格
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章