1. 程式人生 > >Decorator 裝飾器模式

Decorator 裝飾器模式

作用:動態的給物件增加額外的功能。這比通過生成子類的方式更為靈活。因為:1)有的時候,我們希望給某個物件而不是一個類增加功能。2)雖然繼承機制也是增加功能的一種有效途徑。但這種方式是靜態的,無法控制增加的方式和時機。

別名:也叫包裝器(Wrapper)。

解釋:裝飾器,顧名思義就是在某個物件的外面新增一些裝飾的東西。我們把被裝飾的物件稱為元件,將該元件嵌入到另一個物件中,由這個物件新增功能。我們稱這個嵌入的物件為裝飾。

結構圖
這裡寫圖片描述
Component:定義了物件的介面,我們要給這些物件動態的新增功能。
ConcreteComponent:具體的物件類。
Decorators:裝飾器的父類。如果你確定只有一個裝飾器類,也可以不採用這種繼承模式。該類需要維持一個Component物件。並且需要與Component介面一致。
Decorator1/Decorator2:具體的裝飾器類。每個類中都有增加的功能。

程式碼例項

Component類

public abstract class Component {
    public abstract void draw();
}

ConcreteComponent類

public class ConcreteComponent extends Component{
    public void draw(){
        System.out.println("This is a round");
    }
}

Decorators類

public class Decorators extends Component{
    private
Component component; public Decorators(Component c){ this.component=c; } public void draw(){ component.draw(); } }

Decorator1類-BorderDecorator

public class BorderDecorator extends Decorators{
    public BorderDecorator(Component c) {
        super(c);
    }
    public
void draw(){ super.draw(); System.out.println("Draw: the border of round will be red color"); } }

Decorator2類-InnerDecorator

public class InnerDecorator extends Decorators{
    public InnerDecorator(Component c) {
        super(c);
    }
    public void  draw(){
        super.draw();
        System.out.println("Draw: the inner of round will be bule color");
    }
}

測試類

public class Test {
    public static void main(String args[]){
        Component c1=new ConcreteComponent();
        System.out.print("1: ");
        c1.draw();
        Component c2=new ConcreteComponent();
        System.out.print("2: ");
        c2.draw();
        BorderDecorator d1=new BorderDecorator(c1);
        System.out.print("3: ");
        c1.draw();
        System.out.print("4: ");
        d1.draw();
        InnerDecorator d2=new InnerDecorator(c2);
        System.out.print("5: ");
        d2.draw();
        InnerDecorator d3=new InnerDecorator(d1);
        System.out.print("6: ");
        d3.draw();
        Component cbig=new ConcreteComponent();
        Component dbig=new InnerDecorator(new BorderDecorator(cbig));
        System.out.print("7: ");
        dbig.draw();    
    }
}
/*
Output:
1: This is a round
2: This is a round
3: This is a round
4: This is a round
Draw: the border of round will be red color
5: This is a round
Draw: the inner of round will be bule color
6: This is a round
Draw: the border of round will be red color
Draw: the inner of round will be bule color
7: This is a round
Draw: the border of round will be red color
Draw: the inner of round will be bule color
*/

說明:
1 比靜態繼承更為靈活。可以在執行的時候增加功能(也可以刪除某些功能)。並且,可以為一個特定的Component類提供多個不同的Decorator類,可以對功能進行混合。
2 避免在層次結構高層的類有太多特徵。裝飾器模式提供了一種“即用即付”的方式來增加功能。它不試圖建立一個擁有所有可預見的特徵的複雜的類。而是可以建立一個簡單的類,逐漸的增加功能。
3 有許多小物件。在裝飾器的過程中,會建立許多裝飾器物件。每個裝飾器類也會有許多物件,但這並不是它們的類或者它們的屬性值有所不同。

實現注意點:
1 介面一致性。裝飾物件的結構必須與它所裝飾的Component的介面一致。
2 保持Component類的簡單性。該類應該集中於定義介面而不是儲存資料。
3 改變的是物件的外殼。我們可以將裝飾器看作是物件的外殼,最終的效果是可以改變物件的行為。改變物件的行為還可以通過改變物件核心的方式,但那不是裝飾器模式。