問題提出:上班族大部分都吃過煎餅,煎餅一般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的書《設計模式就該這樣學》, 這種處理方式叫 裝飾器模式,之前學習設計模式總覺得很枯燥, 直到遇到這個例子才激發學習樂趣,這種接地氣的程式碼印象深刻值得反覆思考