巧妙的煎餅

changlong2022發表於2024-08-16

問題提出:上班族大部分都吃過煎餅,煎餅一般5塊錢,可以額外加碼比如雞蛋+1元,香腸+2元。 編寫一個程式 可以 快速計算出 煎餅 多少錢。
大部分人寫的程式碼:
首先建個煎餅類,最基礎的類:

public class Battercake {
    protected String getMsg(){
        return "煎餅";
    }
    public int getPrice(){
        return 5;
    }
}

再建個雞蛋煎餅類,繼承煎餅類然後修改價格

public class BattercakeWithEgg extends Battercake{
    protected String getMsg(){
        return super.getMsg() + "+1個雞蛋";
    }
    public int getPrice(){
        return super.getPrice() + 1;
    }
}

再在雞蛋煎餅的基礎上加個香腸

public class BattercakeWithEggAndSauage extends BattercakeWithEgg{、
    protected String getMsg(){
        return super.getMsg() + "+1根香腸";
    }
    public int getPrice(){
        return super.getPrice() + 2;
    }
}

測試一下:

public static void main(String[] args) {
        Battercake battercake = new Battercake();
        System.out.println(battercake.getMsg() + ",總價:" + battercake.getPrice());

        BattercakeWithEgg battercakeWithEgg = new BattercakeWithEgg();
        System.out.println(battercakeWithEgg.getMsg() + ",總價:" + battercakeWithEgg.getPrice());

        BattercakeWithEggAndSauage battercakeWithEggAndSauage = new BattercakeWithEggAndSauage();
        System.out.println(battercakeWithEggAndSauage.getMsg() + ",總價:" + battercakeWithEggAndSauage.getPrice());
    }

執行結果:

"D:\Program Files\Java\jdk1.8.0_181\bin\java.exe" 
煎餅,總價:5
煎餅+1個雞蛋蛋,總價:6
煎餅+1個雞蛋蛋+1根香腸,總價:8

程式碼寫到這兒,感覺很easy,沒毛病。但是如果 我想加兩個雞蛋 怎麼辦呢,難道再寫一個類?我不想加蛋,只要個香腸又怎麼辦呢。這個需求完全沒問題,程式碼如何靈活變化呢。
我們來看一位老師給出的程式碼:
首先建立一個抽象類:

public abstract class Battercake {
    protected abstract String getMsg();
    protected abstract int getPrice();
}

再建立一個煎餅類:

public class BaseBattercake extends Battercake {
    protected String getMsg() {
        return "煎餅";
    }
    protected int getPrice() {
        return 5;
    }
 }

重點來了,建立一個抽象擴充套件類,仔細看下面的程式碼

public abstract class BattercakeDecorator extends Battercake {

    //用了抽象類當一個屬性
    private Battercake battercake;

    public BattercakeDecorator(Battercake battercake) {
        this.battercake = battercake;
    }

    public abstract void doSomething();

    protected String getMsg() {
        return this.battercake.getMsg();
    }

    protected int getPrice() {
        return this.battercake.getPrice();
    }
}

最後建立雞蛋類的擴充套件:

public class EggDecorator extends BattercakeDecorator {
    public EggDecorator(Battercake battercake) {
        super(battercake);
    }

    public void doSomething() {

    }

    @Override
    protected String getMsg() {
        return super.getMsg() + "1個雞蛋";
    }

    @Override
    protected int getPrice() {
        return super.getPrice() + 1;
    }
}

香腸類的擴充套件:

public class SausageDecorator extends BattercakeDecorator {
    public SausageDecorator(Battercake battercake) {
        super(battercake);
    }

    public void doSomething() {

    }

    @Override
    protected String getMsg() {
        return super.getMsg() + "1根香腸";
    }

    @Override
    protected int getPrice() {
        return super.getPrice() + 2;
    }
}


測下程式碼:

public static void main(String[] args) {

        Battercake battercake;

        battercake = new BaseBattercake();

        //加個蛋
        battercake = new EggDecorator(battercake);

		//加個腸
        battercake = new EggDecorator(battercake);

 		//加個蛋
        battercake = new SausageDecorator(battercake);

        System.out.println(battercake.getMsg() + ",總價:" + battercake.getPrice());
"D:\Program Files\Java\jdk1.8.0_181\bin\java.exe"
煎餅1個雞蛋1個雞蛋1根香腸,總價:9

有沒有覺得的很神奇,透過抽象類,繼承,建構函式里傳入介面物件,完成了自由擴充套件特性。想加幾個蛋就加幾個,不必再去修改計算邏輯。

這部分程式碼實際來自 Tom的書《設計模式就該這樣學》, 這種處理方式叫 裝飾器模式,之前學習設計模式總覺得很枯燥, 直到遇到這個例子才激發學習樂趣,這種接地氣的程式碼印象深刻值得反覆思考

相關文章