因为所有咖啡都有共性, 所有开发人员,把它们的共性上提到一个父类中: Beverage
步骤
先定义一个抽象Beverage(饮料)类定义一个String类型的description(描述)把费用定义成抽象方法,因为每个咖啡的价格都是不一样的 abstract class Beverage { private String description; //描述 public Beverage(String description) { this.description = description; } //花费 public abstract double cost(); public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } } class Decaf extends Beverage { public Decaf() { super("无咖啡因咖啡"); } @Override public double cost() { return 1; } } class Espresso extends Beverage { public Espresso() { super("浓缩咖啡"); } @Override public double cost() { return 2; } } class DarkRoast extends Beverage { public DarkRoast() { super("焦炒咖啡"); } @Override public double cost() { return 1.5; } } class HouseBlend extends Beverage { public HouseBlend() { super("混合咖啡"); } @Override public double cost() { return 3; } } //=======================时空线============================= //=========上面为服务端(提供服务,作者),下面为客户端(使用服务)===== public class AppTest { public static void main(String[] args) { Beverage b = new Decaf(); Beverage b2 = new Espresso(); Beverage b3 = new DarkRoast(); Beverage b4 = new HouseBlend(); System.out.println(b.getDescription()+ ":" + b.cost()); System.out.println(b2.getDescription()+ ":" + b2.cost()); System.out.println(b3.getDescription()+ ":" + b3.cost()); System.out.println(b4.getDescription()+ ":" + b4.cost()); } } 目前这段代码,看起来是没有问题的.问题是: 变化来了 星巴克的老板为了提高自身的竞争力,想出来一个新的业务,调料也就是说可以给咖啡放调料: 牛奶、豆浆、摩卡、泡沫(只是为了好玩)所有不能这样设计类
续
abstract class Condiment extends Beverage { //让调料类关联饮料类 protected Beverage beverage; public Condiment(Beverage beverage) { super("调料"); this.beverage = beverage; } } class Decaf extends Beverage { public Decaf() { super("无咖啡因咖啡"); } @Override public double cost() { //咖啡本身价格 return 1; } } class Espresso extends Beverage { public Espresso() { super("浓缩咖啡"); } @Override public double cost() { return 2; } } class DarkRoast extends Beverage { public DarkRoast() { super("焦炒咖啡"); } @Override public double cost() { return 1.5; } } class HouseBlend extends Beverage { public HouseBlend() { super("混合咖啡"); } @Override public double cost() { return 3; } } class Milk extends Condiment { public Milk(Beverage beverage) { super(beverage); } @Override public double cost() { return beverage.cost() + 0.2; } @Override public String getDescription() { return beverage.getDescription() + " 牛奶"; } } class Soy extends Condiment { public Soy(Beverage beverage) { super(beverage); } @Override public double cost() { return beverage.cost() + 0.3; } @Override public String getDescription() { return beverage.getDescription() + " 豆浆"; } } class Mocha extends Condiment { public Mocha(Beverage beverage) { super(beverage); } @Override public double cost() { return beverage.cost() + 0.4; } @Override public String getDescription() { return beverage.getDescription() + " 摩卡"; } } class Bubble extends Condiment { public Bubble(Beverage beverage) { super(beverage); } @Override public double cost() { return beverage.cost() + 0.1; } @Override public String getDescription() { return beverage.getDescription() + " 泡沫"; } } //=======================时空线============================= //=========上面为服务端(提供服务,作者),下面为客户端(使用服务)===== public class AppTest { public static void main(String[] args) { Beverage b = new Tea(); Beverage b2 = new Milk(b); System.out.println(b2.getDescription()+ ":" + b2.cost()); } }其实装饰器模式就是要继承和关联同一个类,并且每一个套一个(类似套娃)
优点:
加一个新的饮料,不会违反开闭原则加一个新的调料.也不会违反开闭原则 //添加一个茶的饮料 class Tea extends Beverage { public Tea() { super("茶"); } @Override public double cost() { return 2; } } //添加一个枸杞的调料 class GouQi extends Condiment { public GouQi(Beverage beverage) { super(beverage); } @Override public double cost() { return beverage.cost() + 1; } @Override public String getDescription() { return beverage.getDescription() + " 枸杞"; } } 缺点: 类还是有点多,但是我们已经尽力了!!