設(shè)計(jì)模式之裝飾者模式

模擬需求

更新一個(gè)訂單系統(tǒng),以滿足飲料供應(yīng)要求。
原先的設(shè)計(jì)是這樣的

圖片.png

每種飲料都需要實(shí)現(xiàn)cost抽象方法,來(lái)返回飲料的價(jià)錢。購(gòu)買咖啡時(shí)也可以要求在其中加入各種調(diào)料,商家會(huì)根據(jù)不同的調(diào)料收取不同的費(fèi)用。
如果這樣設(shè)計(jì):

圖片.png

這簡(jiǎn)直是“類爆炸”,基類中加入了新的功能并不適用于所有的子類,給維護(hù)造成了很大的困難,而且也不能應(yīng)對(duì)需求的變化。繼承是一種強(qiáng)耦合,在編譯時(shí)就動(dòng)態(tài)決定的,如果能夠利用組合的做法擴(kuò)展對(duì)象的行為,就可以在運(yùn)行時(shí)動(dòng)態(tài)地進(jìn)行擴(kuò)展。

類應(yīng)該對(duì)擴(kuò)展開放,對(duì)修改關(guān)閉。

定義裝飾者模式

裝飾者模式動(dòng)態(tài)地將責(zé)任附加到對(duì)象上,若要擴(kuò)展功能,裝飾者提供了比繼承更有彈性的替代方案。

圖片.png

裝飾飲料

圖片.png

不難發(fā)現(xiàn),裝飾者和被裝飾者都繼承了同一個(gè)抽象類。當(dāng)我們將裝飾者與組件組合時(shí),就是在加入新的行為,所得到的行為不是繼承于超類,而是由組合對(duì)象得來(lái)的。裝飾類繼承于抽象類,是為了有正確的類型,而不是繼承它的行為。

代碼實(shí)現(xiàn)

public abstract class Beverage{
  String description = "Unknow Beverage';
  public String getDescription(){
    return description;
  }
  public abstract double cost();
}
//Condiment(調(diào)料)裝飾抽象類
public abstract class CondimentDecorator extends Beverage{
  //所有的調(diào)料必須重新實(shí)現(xiàn)getDescription方法
  public abstract String getDescription();
}
//被裝飾者
public class Espresso extends Beverage{
  public Espresso(){
    description = "Espresso";
  }
  public double cost(){
    return 1.99;
  }
}
//具體裝飾類
public class Mocha extends CondimentDecorator{
  Beverage beverage;
  public Mocha(Beverage beverage){
    this.beverage = beverage;
  }
  public String getDescription(){
    return beveragge.getDescription() + ",Mocha";
  }
  pubic double cost(){
    //要計(jì)算帶Mocha飲料的價(jià)錢,首先把調(diào)用方法委托給被裝飾對(duì)象計(jì)算,再加上Mocha的價(jià)錢
    return 20 + beverage.cost;
  }
}
//產(chǎn)生訂單
public static void main (String[] args){
  //制造一個(gè)飲料
  Beverage beverage = new darkRoast();
  //用Mocha裝飾對(duì)象
  beverage = new Mocha(beverage);
  //用whip裝飾對(duì)象
  beverage = new Whip(beverage);
  system.out.println(beverage.getDescription()+"$"+beverage.cost());
}

jdk中的裝飾類:java/Io

圖片.png

BufferedInputStream和LineNumberInputStream都擴(kuò)展自FilterInputStream,而FileInputStream是一個(gè)抽象的裝飾類

圖片.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容