裝飾者模式: java
動態地將責任附加到對象上, 若要擴展功能, 裝飾者提供了比繼承更有彈性地替代方案ide
關鍵: 裝飾者和被裝飾者都繼承同一個對象, 裝飾者繼承並非爲了得到父類地行爲, 而是達到類型匹配地目的this
一般裝飾者模式採用抽象類spa
java中的裝飾類: I/O 3d
Component--->InputStreamcode
ConcreteComponent---->FileInputStream, StringBufferInputStream, ByteArrayInputStream..orm
Decorator----> FilterInputStream;對象
Concrete--->BufferedInputStream...是否是以爲一會兒恍然大悟了, 以前一直用輸入流的時候套管道--.--;blog
Example: 想象一下, 一家咖啡店, 咖啡裏面能夠加各類不一樣地調料, 你要去計算每一種不一樣搭配的飲料的價格, 怎麼辦繼承
1. 簡單的繼承想法: 先建立一個抽象的Bevarage(飲料)基類, 把計算價格的方法都定義成抽象的, 全部具體的咖啡都繼承這個父類, 而後實現本身的幾個計算
若是這麼作,咱們來考慮幾個問題, 1) 首先調料之間就有很是多的組合, 難道你要每一種組合都去實現它的具體類嗎, 2) 就算你毅力驚人實現了全部類, 那麼要 價格變了, 打折了, 新添加了一種調料, 難道又要重寫嗎, 顯然繼承有點難覺得繼
因此咱們想, 你的咖啡里加了什麼調料, 咱們能夠動態地把價格加上去多好
下面就是一個簡單利用裝飾模式, 實現動態地計算咖啡價格地例子:
1) 一個抽象Beverage基類, 含有一個計算cost的抽象方法;
public abstract class Bevarage { String description; public String getDescription() { return description; } abstract double cost(); }
2) 普通coffe類和抽象Condiments類都繼承Bevarage類, 同時裝飾者中含有一個Bevarage對象---->實現裝飾模式的關鍵;
public class Coffe extends Bevarage { public Coffe() { this.description = "Normal Coffe"; } @Override double cost() { return 5.1; } } /*不知道這個beverage放在者仍是子類裏比較好*/ public abstract class CodimentsDecorator extends Bevarage { Bevarage bevarage; } public class Milk extends CodimentsDecorator { public Milk(Bevarage b) { this.bevarage = b; } public String getDescription() { return bevarage.getDescription() + ", Milk"; } @Override double cost() { return 0.5 + bevarage.cost(); } } public class Mocha extends CodimentsDecorator { public Mocha(Bevarage b) { this.bevarage = b; } @Override public String getDescription() { return bevarage.getDescription() + ", Mocha"; } @Override double cost() { return 1.2 + bevarage.cost(); } } public class Test { public static void main(String[] args) { /*點一杯基本的咖啡, 而後加進去各類調料*/ Bevarage b = new Coffe(); Bevarage milk = new Milk(b); Bevarage mocha = new Mocha(milk); double cost = mocha.cost(); System.out.println(mocha.getDescription() + "\ncost " + cost); } } 輸出: Normal Coffe, Milk, Mocha cost 6.8