設計模式學習筆記之三:裝飾者模式

公司門口有一個小攤賣手抓餅和肉夾饃的,有時候中午不想吃飯就會去光顧一下那個小攤,點了手抓餅以後每每還能夠在這個基礎之上增長一些配料,例如煎蛋,火腿片等等,每一個配料的價格都不同,無論你怎麼配配料,最終價格是手抓餅基礎價加上每一種所選配料價格的總和。小攤的價格單以下:java

如何使用一種設計模式來處理價格計算的問題呢,或許咱們能夠試試裝飾者模式,由於在這裏,主體是手抓餅和肉夾饃,而配料則是裝飾者,我先用UML類圖來描述一下類之間的協做關係。設計模式

再來看看具體java代碼是怎麼實現的:ide

 1 public abstract class Pancake {
 2     
 3     public String desc = "我不是一個具體的煎餅";
 4 
 5     public String getDesc() {
 6         return desc;
 7     }
 8     
 9     public abstract double price();
10 
11 }
public class TornCake extends Pancake {

    public TornCake() {
        desc = "手抓餅";
    }

    @Override
    public double price() {
        return 4;
    }

}
public class Roujiamo extends Pancake {

    public Roujiamo() {
        desc = "肉夾饃";
    }

    @Override
    public double price() {
        return 6;
    }

}
public abstract class Condiment extends Pancake {

    public abstract String getDesc();

}
public class FiredEgg extends Condiment {
    private Pancake pancake;
    
    public FiredEgg(Pancake pancake) {
        this.pancake = pancake;
    }

    @Override
    public String getDesc() {
        return pancake.getDesc() + ", 煎蛋";
    }

    @Override
    public double price() {
        return pancake.price() + 2;
    }

}
public class Ham extends Condiment {
    private Pancake pancake;
    
    public Ham(Pancake pancake) {
        this.pancake = pancake;
    }

    @Override
    public String getDesc() {
        return pancake.getDesc() + ", 火腿片";
    }

    @Override
    public double price() {
        return pancake.price() + 1.5;
    }

}

MeatFloss類和Cucumber類跟FiredEgg很類似,我就不一一列出來了,最後看看測試類:測試

public class MyTest {
    
    @Test
    public void test() {
        Pancake tornCake = new TornCake();
        //手抓餅基礎價
        System.out.println(String.format("%s ¥%s", tornCake.getDesc(), tornCake.price()));
        
        Pancake roujiamo = new Roujiamo();
        roujiamo = new FiredEgg(roujiamo);
        roujiamo = new FiredEgg(roujiamo);
        roujiamo = new Ham(roujiamo);
        roujiamo = new MeatFloss(roujiamo);
        roujiamo = new Cucumber(roujiamo);
        //我好餓
        System.out.println(String.format("%s ¥%s", roujiamo.getDesc(), roujiamo.price()));
    }

}

在Java源碼中典型的裝飾者模式就是java I/O, 其實裝飾者模式也有其缺點,就是產生了太多的裝飾者小類,有類爆炸的趨勢。this

我是剛學設計模式的小白,歡迎各位拍磚:)spa

相關文章
相關標籤/搜索