裝飾者模式:動態地將責任附加到對象上。想要擴展功能,裝飾者提供有別於繼承的另外一種選擇。ide
如今,咱們有一個場景,咖啡店出售各類不一樣的咖啡,而不一樣的咖啡中能夠加入各類不一樣的調料,根據咖啡種類和加入的調料來計算價格。下面咱們就用代碼來簡單實現下這個場景,也就是裝飾者模式,其中咖啡爲主體,調料是用來裝飾咖啡的,好比想要一杯摩卡和奶泡的深焙咖啡,那麼要作的是:測試
1:拿一個深焙咖啡DarkRoast對象this
2:以摩卡Mocha對象來進行裝飾spa
3:以奶泡Whip對象進行裝飾code
4:調用cost方法,並依賴委託將調料價格加上去。對象
好了,直接上代碼理解裝飾者模式吧。blog
第一步:先建立一個基類,全部咖啡和調料都是擴展自這個類的。這就說明裝飾者和被裝飾者對象都有相同的超類型。繼承
//基類 public abstract class Coffer { String descirption = "Unknown Coffer"; public String getDescription(){ return descirption; } //全部子類必須實現這個方法來計算價格 public abstract double cost(); }
第二步:建立一個調料的抽象類,也就是裝飾者類,具體的裝飾者類實現此類。ip
//抽象的裝飾者,調料類,擴展自Coffer public abstract class Condiment extends Coffer{ public abstract String getDescription(); }
第三步:建立具體的咖啡類。ci
//具體的咖啡種類——濃縮咖啡類 public class Espresso extends Coffer{ public Espresso(){ descirption = "Espresso"; } @Override public double cost() { return 1.99; } }
//具體的咖啡種類——深焙咖啡類 public class DarkRoast extends Coffer{ public DarkRoast(){ descirption = "DarkRoast"; } @Override public double cost() { return 0.88; } }
第四步:建立具體的調料類
//具體的裝飾者,摩卡調料 public class Mocha extends Condiment { //用於記錄被裝飾者,這裏是在構造方法中將參數記錄到咖啡的實例變量中,你也能夠使用get/set方法 Coffer coffer; public Mocha(Coffer coffer){ this.coffer = coffer; } @Override public String getDescription() { return coffer.getDescription() + ", Mocha"; } @Override public double cost() { return 0.2 + coffer.cost(); } }
//具體的裝飾者,奶泡調料 public class Whip extends Condiment{ Coffer coffer; public Whip(Coffer coffer){ this.coffer = coffer; } @Override public String getDescription() { return coffer.getDescription() + ", Whip"; } @Override public double cost() { return 0.15 + coffer.cost(); } }
第五步:測試
public class Test { public static void main(String[] args) { //來一杯Espresso咖啡 Coffer coffer = new Espresso(); System.out.println(coffer.getDescription() + ",價格:" + coffer.cost()); //來一杯深焙咖啡,加入2分摩卡和1分奶泡 Coffer coffer2 = new DarkRoast(); coffer2 = new Mocha(coffer2); coffer2 = new Mocha(coffer2); coffer2 = new Whip(coffer2); System.out.println(coffer2.getDescription() + ",價格:" + coffer2.cost()); } }
運行結果:
好了,這就是一個簡單的裝飾者模式了。在Java的API中,你能夠發現,有關IO類就是採用裝飾者模式的,如:
LineNumberInputStream inputStream = new LineNumberInputStream(new BufferedInputStream(new FileInputStream(fileName)));
頂層類都是InputStream,具體這裏不講解了。
下一節:工廠模式