設計模式之裝飾者模式


裝飾者模式  Decorator

什么是裝飾者模式:動態將職責附加到對象上,若要擴展功能,裝飾者提供了比繼承更具彈性的代替方案。

適用性:當采用類繼承的方式會造成類爆炸的情況。如本文的例子中,基本飲料(被裝飾者)可能有茶、水、牛奶等等、可以添加的(裝飾者)有糖、果肉、珍珠等。

    如果通過繼承的方式,為每一種類型的奶茶設計一種類會造成類爆炸,同時也不利於后期的擴展(如又添加一種基本飲料豆漿的情況),此時通過裝飾者模式可以很好的解決問題。

    裝飾者模式本質是一種組合的思想(不同於繼承的思想),多組合少繼承。利用繼承設計子類的行為,是在編譯時靜態決定的,而且所有的子類都會繼承到相同的行為。然而,如果能夠利用組合的做法擴展對象的行為,就可以在運行時動態地進行擴展。

裝飾者模式的主要組成部分:抽象被裝飾者、具體被裝飾者、抽象裝飾者、具體裝飾者。(當只有一個具體被裝飾者、一個具體裝飾者,其對應的抽象類可以省略)。

裝飾者模式類圖:

裝飾者模式要點:

1 多種具體被裝飾者(主體類)抽象出一個抽象被裝飾類,后面通過多態,動態傳遞具體對象。

2 抽象裝飾類繼承抽象被裝飾者(保持接口);要求傳入被裝飾者(使用父類應用、protected修飾);

3 多種具體裝飾者抽象出一個抽象裝飾類。

4 具體裝飾者中,可以添加新方法,可以重寫方法;需要使用被裝飾者方法的地方用傳入的被裝飾者引用。

裝飾者模式的基本代碼:

/**
 * 被裝飾抽象類——基本飲料
 *
 * 作用:當具體的被裝飾類有多種時,抽象提出該抽象類,用於后面實現多態。
 */
public abstract class BaseDrink {
    public abstract int calculate();
    public abstract void display();
}
/**
 * 具體的被裝飾者類—— Water類
 * 繼承抽象的被裝飾者類,並實現其中的抽象方法。
 */

public class Water extends BaseDrink{
    @Override
    public int calculate() {
        return 3;
    }

    @Override
    public void display() {
        System.out.println("water");
    }
}
/**
 * 具體的被裝飾者類—— Tea類
 * 繼承抽象的被裝飾者類,並實現其中的抽象方法。
 */

public class Tea extends BaseDrink{
    @Override
    public int calculate() {
        return 5;
    }

    @Override
    public void display() {
        System.out.println("Tea");
    }
}
/**
 * 抽象裝飾者類——Decorator
 * 要點:1.抽象裝飾者類中繼承該抽象類以保持接口規范
 *      2.包含該抽象類的引用以通過多態的方式對多種被裝飾者類進行裝飾。
 */

public abstract class Decorator extends BaseDrink{  //繼承,保持接口
    protected BaseDrink bd;  //引用,多態

    public Decorator(BaseDrink bd) { this.bd = bd; }

    @Override
    public int calculate() {
        return bd.calculate();
    }

    @Override
    public void display() {
        bd.display();
    }
}
/**
 * 裝飾者類  果肉
 */
public class FleshDecorator extends Decorator{
    public FleshDecorator(BaseDrink bd) {
        super(bd);
    }

    @Override
    public int calculate() {
        return super.calculate() + 2;
    }

    @Override
    public void display() {
        super.display();
        System.out.println("+ flesh");
    }
}


/**
* 裝飾者類 糖
*/
public class SugarDecorator extends Decorator{
public SugarDecorator(BaseDrink bd) {
super(bd);
}

@Override
public int calculate() {
return super.calculate()+1;
}

@Override
public void display() {
bd.display();
System.out.println("+ sugar");
}

public void addMoreSugar(){
System.out.println("add more sugar");
}
}
 
/**
 * 測試用例
 */
public class TestCase {
    public static void main(String[] args) {
        BaseDrink water = new Water();
        SugarDecorator sugarWater = new SugarDecorator(water);
        sugarWater.addMoreSugar();
        sugarWater.display();
        System.out.println(sugarWater.calculate());
        System.out.println("=========================");
        BaseDrink tea = new Tea();
        FleshDecorator fleshTea = new FleshDecorator(tea);
        fleshTea.display();
        System.out.println(fleshTea.calculate());
    }
}
//結果

F:\deaIC-2019.1.3-jbr11.win\jre64\bin\java.exe -javaagent:F:\deaIC-2019.1.3-jbr11.win\lib\idea_rt.jar=7425:F:\deaIC-2019.1.3-jbr11.win\bin -Dfile.encoding=UTF-8 -classpath E:\eclipse-workspace\decoratorDemo\out\production\decoratorDemo TestCase
add more sugar
water
+ sugar
4
=========================
Tea
+ flesh
7

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM