一.装饰者模式特点:
1.装饰者和被装饰者对象有相同的超类
2.可以用一个或多个装饰者包装一个对象
3.由于装饰者和被装饰者具有相同超类,所以任何需要被包装对象的场合,可以用装饰过的对象代替
4.装饰者可以再所委托被装饰者的行为之前或之后,加上自己的行为,以达到特定的目的(重点)
5.对象可以在任何时候被装饰,所以可以在运行时动态的不限量的用你喜欢的装饰者来装饰对象
二.装饰者模式定义:
动态地将责任附加到对象上,若要扩展功能,装饰者提供了比继承更具有弹性的替代方案
三.代码部分
1.咖啡超类
1 package com.pattern.decorate; 2 /* 3 * 咖啡超类 4 */ 5 public abstract class Coffee { 6 7 String des;//对咖啡的描述 8 9 public String getDes() { 10 return des; 11 } 12 13 public void setDes(String des) { 14 this.des = des; 15 } 16 17 public abstract double cost();//不同的咖啡花费不同 18 19 }
2.咖啡实体类一意大利咖啡,被修饰者
1 package com.pattern.decorate; 2 /** 3 * 意大利咖啡,被装饰者 4 * @author Administrator 5 * 6 */ 7 public class ItalianCoffee extends Coffee { 8 9 public ItalianCoffee() { 10 des = "意大利咖啡"; 11 } 12 13 @Override 14 public double cost() { 15 return 10.99; 16 17 } 18 19 }
3.咖啡实体类2被装饰者
1 package com.pattern.decorate; 2 /** 3 * 美式咖啡,被装饰者 4 * @author Administrator 5 * 6 */ 7 public class CafeAmericano extends Coffee { 8 9 public CafeAmericano() { 10 des = "美式咖啡"; 11 } 12 13 @Override 14 public double cost() { 15 // TODO Auto-generated method stub 16 return 8.10; 17 } 18 19 }
4.装饰者超类,调料
1 package com.pattern.decorate; 2 /** 3 * 装饰者的超类,咖啡调料,也是咖啡一部分,所以继承Coffee 4 * @author Administrator 5 * 6 */ 7 public abstract class CoffeeCondiment extends Coffee { 8 9 10 11 @Override 12 public abstract String getDes();//要知道调料加到什么咖啡中 13 @Override 14 public abstract double cost();//不同的调料价格不一样 15 }
5.装饰者实现类1巧克力
1 package com.pattern.decorate; 2 /** 3 * 装饰者实现类,用来修饰Coffee对象 4 * @author Administrator 5 * 6 */ 7 public class Chocolate extends CoffeeCondiment { 8 9 Coffee coffee;//肯定会有这个引用表示调料要加到咖啡中 10 11 public Chocolate(Coffee coffee) { 12 this.coffee = coffee; 13 this.des = "巧克力"; 14 } 15 16 @Override 17 public String getDes() { 18 // TODO Auto-generated method stub 19 return this.des+coffee.getDes(); 20 } 21 22 @Override 23 public double cost() { 24 // TODO Auto-generated method stub 25 return coffee.cost()+5.1;//加一种调料价钱加一点 26 } 27 28 }
6.装饰者实现类2冰块
1 package com.pattern.decorate; 2 /** 3 * 装饰者实现类,用来修饰Coffee对象, 4 * @author Administrator 5 * 6 */ 7 public class Ice extends CoffeeCondiment { 8 9 Coffee coffee;//肯定会有这个引用表示调料要加到咖啡中 10 11 public Ice(Coffee coffee) { 12 this.coffee = coffee; 13 this.des = "冰块"; 14 } 15 16 @Override 17 public String getDes() { 18 // TODO Auto-generated method stub 19 return this.des+coffee.getDes(); 20 } 21 22 @Override 23 public double cost() { 24 // TODO Auto-generated method stub 25 return coffee.cost()+1.5;//加一种调料价钱加一点 26 } 27 28 }
7.装饰者实现类3摩卡
1 package com.pattern.decorate; 2 /** 3 * 装饰者实现类,用来修饰Coffee对象, 4 * @author Administrator 5 * 6 */ 7 public class Mocha extends CoffeeCondiment { 8 9 Coffee coffee;//肯定会有这个引用表示调料要加到咖啡中 10 11 public Mocha(Coffee coffee) { 12 this.coffee = coffee; 13 this.des = "摩卡"; 14 } 15 16 @Override 17 public String getDes() { 18 // TODO Auto-generated method stub 19 return this.des+coffee.getDes(); 20 } 21 22 @Override 23 public double cost() { 24 // TODO Auto-generated method stub 25 return coffee.cost()+8.2;//加一种调料价钱加一点 26 } 27 28 }
8.测试类
1 package com.pattern.decorate; 2 /** 3 * 装饰者模式测试代码 4 * @author Administrator 5 * 6 */ 7 public class Client { 8 9 public static void main(String[] args) { 10 //创建原始对象,意大利咖啡 11 Coffee coffee1 = new ItalianCoffee(); 12 System.out.println("给我来一杯"+coffee1.getDes()+",价格:"+coffee1.cost()); 13 System.out.println("---------------------------------------------"); 14 Coffee coffee2 = new CafeAmericano(); 15 System.out.println("给我来一杯"+coffee2.getDes()+",价格:"+coffee2.cost()); 16 System.out.println("---------------------------------------------"); 17 //创建装饰者 18 Coffee co = new Chocolate(coffee1);//加入巧克力 19 co = new Ice(co);//在加入冰块 20 co = new Mocha(co);//再加入摩卡 21 System.out.println("给我来一杯"+co.getDes()+",价格:"+co.cost()); 22 System.out.println("------------------------------------------------"); 23 Coffee cof = new Ice(coffee2); 24 cof = new Mocha(cof); 25 System.out.println("给我来一杯"+cof.getDes()+",价格:"+cof.cost()); 26 27 28 29 } 30 31 }
9.运行结果
10.装饰者模式要点:
@1继承属于扩展形式之一,但不是达到弹性设计的最佳方案
@2在我们的设计中,应该允许行为可以被扩展,而无需修改现有的代码
@3组合和委托可用于在运行时动态添加新的行为
@4除了继承装饰者模式也可以让我们扩展行为
@5装饰者模式意味着一群装饰者类,这些类用来包装具体的组件
@6装饰这类反映出被装饰者的组件类型,事实上他们都具有相同的类型,都经过接口或者继承实现
@7装饰者可以在被装饰者的行为前面与后面加上自己的行为,甚至被装饰者的整个行为替换掉而达到特定目的
@8可以用许许多多装饰者包装一个组件
@9装饰者一般对组件的客户是透明的,除非客户程序依赖于组建的具体类型
@10装饰者会导致设计中出现许许多多的小对象,如果过度使用,会让程序变得很复杂