装饰者模式:动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。(星巴兹咖啡)
设计原则:类应该对扩展开放,对修改关闭。
我们的目标是允许类容易扩展,在不修改现有代码的情况下,就可以搭配新的行为。如能实现这样的目标,有什么好处呢?这样的设计具有弹性可以应对改变,可以接受新的功能来应对改变的需求。
工程名称:Decorator(eclipse) 下载目录: ,Decorator.zip
1 package com.jyu.abstractclass; 2 3 /** 4 * 饮料(组件) 5 * @author JRSmith 6 * 7 */ 8 public abstract class Beverage { 9 10 protected String description = "Unknown Beverage";11 12 /**getDescription()已经在此实现了,但是cost()必须在子类中实现*/13 public String getDescription(){14 return description;15 }16 17 public abstract double cost();18 }
1 package com.jyu.abstractclass; 2 3 /** 4 * 调料 5 * @author JRSmith 6 * 7 */ 8 public abstract class Condiment extends Beverage { 9 10 @Override11 public abstract String getDescription();12 }
View Code
1 package com.jyu.extendsbeverage; 2 3 import com.jyu.abstractclass.Beverage; 4 5 /** 6 * 低咖啡因 7 * @author JRSmith 8 * 9 */10 public class Decat extends Beverage {11 12 public Decat() {13 description = "Decat Coffee";14 }15 16 @Override17 public double cost() {18 return 1.05;19 }20 21 }
View Code
1 package com.jyu.extendsbeverage; 2 3 import com.jyu.abstractclass.Beverage; 4 5 /** 6 * 深焙 7 * @author JRSmith 8 * 9 */10 public class DarkRoast extends Beverage {11 12 public DarkRoast() {13 description = "DarkRoast Coffee";14 }15 16 @Override17 public double cost() {18 return .99;19 }20 21 }
View Code
1 package com.jyu.extendsbeverage; 2 3 import com.jyu.abstractclass.Beverage; 4 5 /** 6 * 浓缩咖啡 7 * @author JRSmith 8 * 9 */10 public class Espresso extends Beverage {11 12 public Espresso(){13 description = "Espresso Coffee";14 }15 16 @Override17 public double cost() {18 return 1.99;19 }20 21 }
View Code
1 package com.jyu.extendsbeverage; 2 3 import com.jyu.abstractclass.Beverage; 4 5 /** 6 * 综合咖啡 7 * @author JRSmith 8 * 9 */10 public class HouseBlend extends Beverage {11 12 public HouseBlend() {13 description = "House Blend Coffee";14 }15 16 @Override17 public double cost() {18 return .89;19 }20 21 }
View Code
1 package com.jyu.extendscondiment; 2 3 import com.jyu.abstractclass.Beverage; 4 import com.jyu.abstractclass.Condiment; 5 6 /** 7 * 摩卡 8 * @author JRSmith 9 *10 */11 public class Mocha extends Condiment {12 13 protected Beverage beverage;14 15 public Mocha(Beverage beverage) {16 this.beverage = beverage;17 }18 19 @Override20 public String getDescription() {21 return this.beverage.getDescription() + " , Mocha";22 }23 24 @Override25 public double cost(){26 return 0.20 + this.beverage.cost();27 }28 29 }
View Code
1 package com.jyu.extendscondiment; 2 3 import com.jyu.abstractclass.Beverage; 4 import com.jyu.abstractclass.Condiment; 5 6 /** 7 * 豆浆 8 * @author JRSmith 9 *10 */11 public class Soy extends Condiment {12 13 protected Beverage beverage;14 15 public Soy(Beverage beverage) {16 this.beverage = beverage;17 }18 19 @Override20 public String getDescription() {21 return this.beverage.getDescription() + " , Soy";22 }23 24 @Override25 public double cost() {26 return 0.15 + this.beverage.cost();27 }28 29 }
View Code
1 package com.jyu.extendscondiment; 2 3 import com.jyu.abstractclass.Beverage; 4 import com.jyu.abstractclass.Condiment; 5 6 /** 7 * 奶泡 8 * @author JRSmith 9 *10 */11 public class Whip extends Condiment {12 13 protected Beverage beverage;14 15 public Whip(Beverage beverage) {16 this.beverage = beverage;17 }18 19 @Override20 public String getDescription() {21 return this.beverage.getDescription() + " , Whip";22 }23 24 @Override25 public double cost() {26 return 0.10 + this.beverage.cost();27 }28 29 }
1 package com.jyu.test; 2 3 import com.jyu.abstractclass.Beverage; 4 import com.jyu.extendsbeverage.DarkRoast; 5 import com.jyu.extendsbeverage.Espresso; 6 import com.jyu.extendsbeverage.HouseBlend; 7 import com.jyu.extendscondiment.Mocha; 8 import com.jyu.extendscondiment.Soy; 9 import com.jyu.extendscondiment.Whip;10 11 public class StarbuzzCoffee {12 13 /**14 * @param args15 */16 public static void main(String[] args) {17 18 /**订一杯Espresso,不需要调料,打印出它的描述与价钱*/19 Beverage beverage = new Espresso();20 System.out.println(beverage.getDescription() + " $" + beverage.cost());21 22 /**制造出一个DarkRoast对象。用Mocha装饰它,用第二个Mocha装饰它,用Whip装饰它*/23 Beverage beverage2 = new DarkRoast();24 beverage2 = new Mocha(beverage2);25 beverage2 = new Mocha(beverage2);26 System.out.println(beverage2.getDescription() + " $" + beverage2.cost());27 28 /**最后,再来一杯调料为豆浆、摩卡、奶泡的HouseBlend咖啡*/29 Beverage beverage3 = new HouseBlend();30 beverage3 = new Soy(beverage3);31 beverage3 = new Mocha(beverage3);32 beverage3 = new Whip(beverage3);33 System.out.println(beverage3.getDescription() + " $" + beverage3.cost());34 35 36 }37 38 }