若是增長新功能,能夠在上面進行擴展,而不是修改原來已經編寫的部分。ide
動態的將責任附加到對象中。若要擴展功能,裝飾者提供比繼承更有彈性的替代方案。函數
理解:this
一、 裝飾者A和B能夠實現對ConcreateComponent的動態擴展,只需保存一個超類的引用即Component的引用,這樣能夠實現對原方法methodA()和methodB()的從新擴展。 由於每一個裝飾者對象都有一個超類的引用,也就是被裝飾者的引用,那麼天然能夠經過它調用原方法,如ConcreateComponent的methodA()或B ;spa
擴展methodA()的辦法是全部裝飾者有一個共同的抽象接口,也就是Decorator,裏面聲明methodA(),那麼其子類就必須重寫,也就實現了擴展。設計
二、對比直接繼承,即若是ConcreateDecorator直接繼承自ConcreateComponent相比,結構更清晰、並且能夠動態擴展code
三、裝飾者具備超類或者說是被裝飾對象特徵的辦法是將其做爲裝飾者的構造函數參數。對象
四、要擴展方法必定要在裝飾者接口中從新聲明以便子類重寫進行覆蓋。blog
五、裝飾者接口的做用就是,繼承Component以便具備其類型,以及限定擴展的方法繼承
思考:接口
因爲裝飾者的子類必須具備Component的引用,這個引用在Decorator中聲明以及構造函數實現 對比 在每一個子類分別聲明實現有什麼不一樣嗎,爲何headfirst使用後面的辦法。
package com.decorator; public abstract class Beverage { String description = "Unkonow Description"; protected String getDescription() { return description; } public void setDescription(String description) { this.description = description; } protected abstract double cost(); }
package com.decorator; public abstract class CondimentDecorator extends Beverage{ Beverage beverage; public CondimentDecorator(Beverage beverage){ this.beverage = beverage; } protected abstract String getDescription(); }
package com.decorator; public class Espresso extends Beverage{ public Espresso(){ this.description = "Espresso"; } @Override protected double cost() { // TODO Auto-generated method stub return 0.1; } }
package com.decorator; public class HouseBlend extends Beverage{ public HouseBlend(){ this.description = "HouseBlend"; } @Override protected double cost() { // TODO Auto-generated method stub return 0; } }
package com.decorator; public class Mocha extends CondimentDecorator{ // Beverage beverage; // public Mocha(Beverage beverage){ // this.beverage = beverage; // } public Mocha(Beverage beverage) { super(beverage); // TODO Auto-generated constructor stub } @Override protected String getDescription() { // TODO Auto-generated method stub return beverage.getDescription() + ",Mocha"; } @Override protected double cost() { // TODO Auto-generated method stub return beverage.cost() + 0.9; } }
package com.decorator; public class Sop extends CondimentDecorator{ // Beverage beverage; // public Sop(Beverage beverage){ // this.beverage = beverage; // } public Sop(Beverage beverage) { super(beverage); // TODO Auto-generated constructor stub } @Override protected String getDescription() { // TODO Auto-generated method stub return this.beverage.getDescription() + ",Sop"; } @Override protected double cost() { // TODO Auto-generated method stub return 0.888 + beverage.cost(); } }
package com.decorator; public class DecoratorTest { public static void main(String args[]){ Beverage beverage = new Espresso(); System.out.println(beverage.getDescription()); beverage = new Sop(beverage); System.out.println(beverage.getDescription()); beverage = new Mocha(beverage); System.out.println(beverage.getDescription()); } }
思考: