用途
裝飾者模式是一種
結構式模式。
結構
圖-裝飾者模式結構圖
Component : 定義一個對象接口,可以給這些對象動態地添加職責。
interface Component {
public void operation();
}
public void operation();
}
ConcreteComponent : 實現
Component 定義的接口。
class ConcreteComponent
implements Component {
@Override
public void operation() {
System.out.println("初始行為");
}
}
@Override
public void operation() {
System.out.println("初始行為");
}
}
Decorator : 裝飾抽象類,繼承了 Component, 從外類來擴展 Component 類的功能,但對於 Component 來說,是無需知道 Decorator 的存在的。
class Decorator
implements Component {
// 持有一個 Component 對象,和 Component 形成聚合關系
protected Component component;
// 傳入要進一步修飾的對象
public Decorator(Component component) {
this.component = component;
}
@Override
// 調用要修飾對象的原方法
public void operation() {
component.operation();
}
}
// 持有一個 Component 對象,和 Component 形成聚合關系
protected Component component;
// 傳入要進一步修飾的對象
public Decorator(Component component) {
this.component = component;
}
@Override
// 調用要修飾對象的原方法
public void operation() {
component.operation();
}
}
ConcreteDecorator : 具體的裝飾對象,起到給 Component 添加職責的功能。
class ConcreteDecoratorA
extends Decorator {
private String addedState = "新屬性1";
public ConcreteDecoratorA(Component component) {
super(component);
}
public void operation() {
super.operation();
System.out.println("添加屬性: " + addedState);
}
}
class ConcreteDecoratorB extends Decorator {
public ConcreteDecoratorB(Component component) {
super(component);
}
public void operation() {
super.operation();
AddedBehavior();
}
public void AddedBehavior() {
System.out.println("添加行為");
}
}
private String addedState = "新屬性1";
public ConcreteDecoratorA(Component component) {
super(component);
}
public void operation() {
super.operation();
System.out.println("添加屬性: " + addedState);
}
}
class ConcreteDecoratorB extends Decorator {
public ConcreteDecoratorB(Component component) {
super(component);
}
public void operation() {
super.operation();
AddedBehavior();
}
public void AddedBehavior() {
System.out.println("添加行為");
}
}
測試代碼
public
class DecoratorPattern {
public static void main(String[] args) {
Component component = new ConcreteComponent();
component.operation();
System.out.println("======================================");
Decorator decoratorA = new ConcreteDecoratorA(component);
decoratorA.operation();
System.out.println("======================================");
Decorator decoratorB = new ConcreteDecoratorB(decoratorA);
decoratorB.operation();
}
}
public static void main(String[] args) {
Component component = new ConcreteComponent();
component.operation();
System.out.println("======================================");
Decorator decoratorA = new ConcreteDecoratorA(component);
decoratorA.operation();
System.out.println("======================================");
Decorator decoratorB = new ConcreteDecoratorB(decoratorA);
decoratorB.operation();
}
}
運行結果
初始行為
======================================
初始行為
添加屬性: 新屬性1
======================================
初始行為
添加屬性: 新屬性1
添加行為
======================================
初始行為
添加屬性: 新屬性1
======================================
初始行為
添加屬性: 新屬性1
添加行為
應用場景
1、需要動態的、透明的為一個對象添加職責,即不影響其他對象。
2、需要動態的給一個對象添加功能,這些功能可以再動態的撤銷。
3、需要增加由一些基本功能的排列組合而產生的非常大量的功能,從而使繼承關系變的不現實。
4、當不能采用生成子類的方法進行擴充時。一種情況是,可能有大量獨立的擴展,為支持每一種組合將產生大量的子類,使得子類數目呈爆炸性增長。另一種情況可能是因為類定義被隱藏,或類定義不能用於生成子類。
要點
1、裝飾對象和真實對象有相同的接口。這樣客戶端對象就能以和真實對象相同的方式和裝飾對象交互。
2、裝飾對象包含一個真實對象的引用(reference)。
3、裝飾對象接受所有來自客戶端的請求。它把這些請求轉發給真實的對象。
4、裝飾對象可以在轉發這些請求以前或以后增加一些附加功能。這樣就確保了在運行時,不用修改給定對象的結構就可以在外部增加附加的功能。在面向對象的設計中,通常是通過繼承來實現對給定類的功能擴展。