文章目錄
一、裝飾模式
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); // 調味品 的價格
}
}