Java設計模式之裝飾者模式

Java設計模式之裝飾者模式

先考慮這樣一個生活場景,煎餅攤前面有三個人餓了要買煎餅,第一個只要煎餅,第二個煎餅加雞蛋,第三個煎餅加雞蛋加香腸。下面看代碼實現。

//新建一個類 煎餅
public class Battercake {
    public String getDesc(){
        return "煎餅";
    }
    public int price(){
        return 5;
    }

}


//新建類 煎餅 加雞蛋
public class BattercakeWithEgg extends Battercake {

    @Override
    public String getDesc() {
        return super.getDesc() +" 加一個雞蛋";
    }

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


//新建類  煎餅 加雞蛋 加香腸
public class BattercakeWithEggSausage extends BattercakeWithEgg {
    @Override
    public String getDesc() {
        return super.getDesc() +" 加一根香腸";
    }

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

//調用
 public static void main(String [] a){
        Battercake battercake=new Battercake();
        System.out.println(battercake.getDesc()+";價格:"+battercake.price());

        Battercake battercake2=new BattercakeWithEgg();
        System.out.println(battercake2.getDesc()+";價格:"+battercake2.price());

        Battercake battercake3=new BattercakeWithEggSausage();
        System.out.println(battercake3.getDesc()+";價格:"+battercake3.price());
    }

//結果
煎餅;價格:5
煎餅 加一個雞蛋;價格:6
煎餅 加一個雞蛋 加一根香腸;價格:8


看一下UML的類圖:

現在如果來了第四個人想買煎餅加2個蛋一根香腸或者煎餅加1個蛋兩根香腸呢?再考慮其他的組合呢?此時代碼的擴展性很差,很容易導致類爆炸。

下面看看裝飾者模式怎麼優雅的應對這種局面。

抽象的實體類,確定的實體類,抽象的裝飾者,確定的裝飾者。被裝飾者是煎餅,裝飾者是雞蛋和香腸。

//抽象的煎餅
public abstract class ABattercake {
    public abstract String getDesc();
    public abstract int price();
}

//實體的煎餅
public class Battercake extends ABattercake{
    @Override
    public String getDesc() {
        return "煎餅";
    }

    @Override
    public int price() {
        return 5;
    }
}

//抽象的裝飾者繼承抽象的煎餅
public class ADecorator extends ABattercake{
    private ABattercake aBattercake;

    //把要被裝飾的抽象類作爲構造的入參
    public ADecorator(ABattercake aBattercake) {
        this.aBattercake = aBattercake;
    }

    @Override
    public String getDesc() {
        return this.aBattercake.getDesc();
    }

    @Override
    public int price() {
        return this.aBattercake.price();
    }
}

//雞蛋 實體裝飾者
public class EggDecorator extends ADecorator{
    public EggDecorator(ABattercake aBattercake) {
        super(aBattercake);
    }

    @Override
    public String getDesc() {
        return super.getDesc()+" 加一個雞蛋";
    }

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

//香腸 實體裝飾者
public class SuasageDecorator extends ADecorator{
    public SuasageDecorator(ABattercake aBattercake) {
        super(aBattercake);
    }

    @Override
    public String getDesc() {
        return super.getDesc()+" 加一根香腸";
    }

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

//調用
public static void main(String [] a){
        ABattercake aBattercake;
        aBattercake=new Battercake();
        aBattercake=new EggDecorator(aBattercake);
        aBattercake=new EggDecorator(aBattercake);
        aBattercake=new SuasageDecorator(aBattercake);
        System.out.println(aBattercake.getDesc()+"; 價格:"+aBattercake.price());

    }

//結果
煎餅 加一個雞蛋 加一個雞蛋 加一根香腸; 價格:9

看看此時UML的類圖:

 

 

 

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