2010年3月26日 星期五

Design Pattern : 12 Decorator


把裝飾物件與主要內容物件當成相同的物件,也就是給予相同的API
可以在程式內用相同的方式操作,就可以用來組合出有彈性並複雜的結果
這就是Decorator

把裝飾與實際內容物當作相同的方式處裡
範例,要讓輸出字串可以彈性的增加外觀修飾的裝飾
把輸出物拆解成主要內容與裝飾內容,裝飾內容可能也多種的變化


參與者
1.Display (abstract)
提供一個主要內容與裝飾物都要依循的標準操作方法(API)


public abstract class Display {
    public abstract int getColumns();
    public abstract int getRows();
    public abstract String getRowText(int row);
    public final void show(){
        for(...){
            System.out.println(getRowText(i));
        }
    }
}


2.StringDisplay 主內容顯示類別
真正的主要內容顯示class,在實作抽象method時,具體的執行工作內容


public class StringDisplay extends Display {
    private String string;
    public StringDisplay(String string){
        this.string=string;
    }
    public int getColumns() { 
        return string.getBytes().length;
    }
    public int getRows() { 
        return 1;
    }
    public String getRowText(int row) { 
        if(row==0){
            return string;
        }else{
            return null;
        } 
    }
}


3.Border(abstract)
修飾抽象類別,還是繼承了主要Display類別,但是導入了一個display物件
來作為內部method委讓操作使用


public abstract class Border extends Display {
    protected Display display;  
    public Border(Display display){
        this.display=display;
    }
}


4.SlideBorder
在實作抽象method內,利用委讓操作display物件取得主要內容
再添加上裝飾的內容後,將最後結果輸出


public class SlideBorder extends Border {
    private char borderChar;
    public SlideBorder(Display display,char borderChar){
        super(display);
        this.borderChar=borderChar;
    }
    public int getColumns() {
        return 1+display.getColumns()+1;
    }
    public int getRows() {
        return display.getRows();
    }
    public String getRowText(int row) {
        return borderChar+display.getRowText(row)+borderChar;
    }
}


5.Main外部程式
可任意包裝產生所要的結果


Display b1=new StringDisplay("hello ozzy");
b1.show();
Display b2=new SlideBorder(new StringDisplay("hello sun"),'*');
b2.show();



沒有留言: