装饰者模式 

1、顾名思义,装饰者的意思是修饰、辅助的意思, 即在原来东西的基础之上附加上一些内容。犹如很多公司的增值业务一样, 比如中国移动提供的来电显示、天气预报等。 总之一句话, 就是对之前的功能进行一些添加或修补, 便于各种情况的使用。采用装饰者设计模式可以减少不必要的类, 使增值业务不再需要从基类中去继承;这本来也是不合理的,因为增值业务不是原来的业务,它只是对原来的修饰而已。 就像咖啡中加的奶一样,毕竟奶不是咖啡。细心的同学恐怕早就注意到了,JDK中的Stream中大量使用了装饰者设计模式, 经过装饰之后的流,具备的更强大的功能, 比如提供缓冲等。

   设计模式中如何来做到的呢? 通过装饰者实现基类(或继承)且包含基类来实现。GOF中的原话是这样的:装饰者模式是动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。

装饰者模式

具体代码如下:

基础接口:Coffee.java

  1. public interface Coffee { 
  2.     double getPrice(); 
  3.     String getInfomation(); 

 

装饰者:DecoratorCoffee.java

  1. /** 
  2.  * 咖啡的装饰者 
  3.  * @author keju.wangkj 
  4.  * 
  5.  */ 
  6. public class DecoratorCoffee implements Coffee { 
  7.      
  8.     private Coffee coffee; 
  9.  
  10.     public DecoratorCoffee(Coffee coffee) { 
  11.         this.coffee = coffee; 
  12.     } 
  13.  
  14.     public String getInfomation() { 
  15.         return coffee.getInfomation(); 
  16.     } 
  17.  
  18.     public double getPrice() { 
  19.         return coffee.getPrice(); 
  20.     } 

 

南山咖啡:BlueMountain.java

  1. public class BlueMountain implements Coffee{ 
  2.  
  3.     public String getInfomation() { 
  4.         // TODO Auto-generated method stub 
  5.         return "Blue Mountain coffee"
  6.     } 
  7.  
  8.     public double getPrice() { 
  9.         // TODO Auto-generated method stub 
  10.         return 10.0
  11.     } 
  12.  

 

星巴克咖啡:StarBucks.java

  1. public class StarBucks implements Coffee{ 
  2.  
  3.     public String getInfomation() { 
  4.         // TODO Auto-generated method stub 
  5.         return "star bucks coffee"
  6.     } 
  7.  
  8.     public double getPrice() { 
  9.         // TODO Auto-generated method stub 
  10.         return 15.0
  11.     } 
  12.  

 

加奶的咖啡:MilkCoffee .java

加奶的咖啡需求:加3元,咖啡的信息中说明已经加奶 

  1. public class Milk extends DecoratorCoffee{ 
  2.  
  3.     public Milk(Coffee coffee) { 
  4.         super(coffee); 
  5.     } 
  6.  
  7.     public String getInfomation() { 
  8.         return "milk-added " + super.getInfomation(); 
  9.     } 
  10.  
  11.     public double getPrice() { 
  12.         return super.getPrice() + 3
  13.     } 

 

大杯的咖啡:LargeSize.java

需求:价格是原来的1.5倍,且需要为客户说明是大杯的咖啡

  1. public class LargeSize  extends DecoratorCoffee{ 
  2.  
  3.     public LargeSize(Coffee coffee) { 
  4.         super(coffee); 
  5.     } 
  6.  
  7.     @Override 
  8.     public String getInfomation() { 
  9.         return "Large-Size " + super.getInfomation(); 
  10.     } 
  11.  
  12.     @Override 
  13.     public double getPrice() { 
  14.         return super.getPrice() * 1.5
  15.     } 
  16.  

 

测试类:MilkCoffeeTest.java

  1. public class MilkLargeCoffeeTest { 
  2.      
  3.     DecoratorCoffee milkCoffee = new Milk(new LargeSize(new StarBucks())); 
  4.     //DecoratorCoffee milkCoffee = new LargeSize(new Milk(new StarBucks())); 
  5.      
  6.     @Test 
  7.     public void testGetInfomation() { 
  8.         System.out.println(milkCoffee.getInfomation()); 
  9.     } 
  10.  
  11.     @Test 
  12.     public void testGetPrice() { 
  13.         System.out.println(milkCoffee.getPrice()); 
  14.     } 

测试结果: 

 

milk-added Large-Size star bucks coffee

25.5