Java設計模式之裝飾者模式

要實現裝飾者模式,注意一下幾點內容:

1.裝飾者類要實現真實類同樣的接口

2.裝飾者類內有一個真實對象的引用(可以通過裝飾者類的構造器傳入)

3.裝飾類對象在主類中接受請求,將請求發送給真實的對象(相當於已經將引用傳遞到了裝飾類的真實對象)

4.裝飾者可以在傳入真實對象後,增加一些附加功能(因爲裝飾對象和真實對象都有同樣的方法,裝飾對象可以添加一定操作在調用真實對象的方法,或者先調用真實對象的方法,再添加自己的方法)

5.不用繼承,

 先用實例說話,最後再具體裝飾者模式

假設要製造添加甜蜜素和着色劑的饅頭:

1.需要生產一個正常饅頭

2.爲節省成本(不使用玉米麪),使用染色劑加入到正常饅頭中

3.和麪,最後生產出染色饅頭

 

一..先實現做麪包的接口

    IBread接口包括準備材料,和麪,蒸饅頭,加工饅頭(即調用前面三個步驟)

package com.Geeksun.Decoration;

public interface IBread {

    public void prepare();

    public void kneadFlour();

    public void steamed();

    public void process();

}

二.製作正常饅頭

package com.Geeksun.Decoration;

public class NormalBread implements IBread {
    @Override
    public void prepare() {
        System.out.println("準備麪粉,水以及發酵粉...");
    }

    @Override
    public void kneadFlour() {
        System.out.println("和麪...");
    }

    @Override
    public void steamed() {
        System.out.println("蒸饅頭...香噴噴的饅頭出爐了");
    }

    @Override
    public void process() {
        prepare();
        kneadFlour();
        steamed();
    }
}

三.定義出製作麪包的抽象類

    抽象類實現了IBread這個製作麪包的接口,同時包含IBread接口的實例

    對應上述的第2個注意點:裝飾者類內有一個真實對象的引用

package com.Geeksun.Decoration;

public abstract class AbstractBread implements IBread {
    protected IBread bread;

    public AbstractBread(IBread bread){
        this.bread = bread;
    }

    @Override
    public void prepare() {
        bread.prepare();
    }

    @Override
    public void kneadFlour() {
        bread.kneadFlour();
    }

    @Override
    public void steamed() {
        bread.steamed();
    }

    @Override
    public void process() {
        prepare();
        kneadFlour();
        steamed();
    }
}

四.生產有着色劑的"玉米饅頭"

    繼承AbstarctBread類,所以可以有選擇的覆蓋正常生產饅頭的方法,並添加原有方法原來的信息,同時也可以添加自己的方法

    裝飾者模式中這裏最關鍵,

     對應上述的第1個注意點:裝飾者類要實現真實類同樣的接口

package com.Geeksun.Decoration;

public class CornDecorator extends AbstractBread {

    public CornDecorator(IBread bread) {
        super(bread);
    }

    public void paint(){
        System.out.println("添加檸檬黃的着色劑");
    }

    @Override
    public void kneadFlour() {
        this.paint();
        super.kneadFlour();
    }
}

五.生產有甜蜜素的"甜饅頭"

    實現與第四部一樣

package com.Geeksun.Decoration;

public class SweetDecorator extends AbstractBread {

    public SweetDecorator(IBread bread) {
        super(bread);
    }

    public void paint(){
        System.out.println("增加甜味劑");
    }

    @Override
    public void kneadFlour() {
        this.paint();
        super.kneadFlour();
    }
}

六.開始製作添加甜蜜素和着色劑的饅頭

package com.Geeksun.Decoration;

public class Client {

    public static void main(String[] args) {
        System.out.println("=======開始裝飾饅頭");
        IBread normalBread = new NormalBread();
        normalBread = new SweetDecorator(normalBread);
        normalBread = new CornDecorator(normalBread);
        normalBread.process();
        System.out.println("=======裝飾饅頭結束");
    }

}

七.輸出

=======開始裝飾饅頭
準備麪粉,水以及發酵粉...
添加檸檬黃的着色劑
增加甜味劑
和麪...
蒸饅頭...香噴噴的饅頭出爐了
=======裝飾饅頭結束

裝飾者模式中的4個角色

(1)被裝飾者抽象Component:是一個接口或者抽象類,定義最核心的對象,這個類是裝飾者的基類,例如IBread接口

(2)被裝飾者具體實現ConcreteComponent:這是Component接口或抽象類的實現,例如本例中的NormalBread

(3)裝飾者Decorator:一般是抽象類,實現Component,它裏面必然有一個指向Component的引用,例如本例中AbstractBread

(4)裝飾者實現ConcreteDecorator1和ConcreteDecorator2:用來裝飾最基本的類,如本例中的CornDecorator,

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章