装饰者模式:动态地将责任附加到对象上。若要扩展对象,装饰者提供了比继承更有弹性的替代方案。

    举例:有一家咖啡厅,主要饮料有咖啡,牛奶等。配料有糖,椰果等。每一款饮料都可以加入不限配料,但只有一款主饮。

    此时,针对饮料有一个抽象类

 


  
  1. package com.zlh.decoretor; 
  2.  
  3. public abstract class Beverage { 
  4.      String description; 
  5.  
  6.     abstract double cost(); 
  7.  
  8.     String getDescription() { 
  9.         return description; 
  10.     } 

咖啡,牛奶的实现如下:

 


  
  1. package com.zlh.decoretor;  
  2.   
  3. public class Milk extends Beverage{  
  4.   
  5.     public Milk() {  
  6.         this.description = "milk";  
  7.     }  
  8.   
  9.     public double cost() {  
  10.         return 1;  
  11.     }  
  12.   
  13.     public String getDescription() {  
  14.         return description;  
  15.     }  
  16.   
  17. }  
  18.   
  19. package com.zlh.decoretor;  
  20.   
  21. public class Coffee extends Beverage {  
  22.   
  23.     public Coffee() {  
  24.         this.description = "milk";  
  25.     }  
  26.   
  27.     public double cost() {  
  28.         return 2;  
  29.     }  
  30.   
  31.     public String getDescription() {  
  32.         return this.description;  
  33.     }  
  34.   
  35. }  

为了实现装饰模式,每一款配料都有一个基本抽象类,此抽象类继承自beverage,但重写了getDescription方法,用于输出整个装饰中所有的主料和配料名称。

 


  
  1. package com.zlh.decoretor; 
  2.  
  3. public abstract class CondimentDecorator extends Beverage{ 
  4.  
  5.     @Override 
  6.     abstract String getDescription(); 
  7.  

在具体装饰类中,聚合了被装饰的饮料。如下:

 


  
  1. package com.zlh.decoretor; 
  2.  
  3. public class SugarMilk extends CondimentDecorator{ 
  4.     private Beverage beverage; 
  5.  
  6.     public SugarMilk(Beverage beverage) { 
  7.         this.description = "suger "
  8.         this.beverage = beverage; 
  9.     } 
  10.  
  11.     public double cost() { 
  12.         return 0.5 + beverage.cost(); 
  13.     } 
  14.  
  15.     public String getDescription() { 
  16.         return this.description + beverage.description; 
  17.     } 

同样,更深层次的包装也可以这么实现:

 


  
  1. package com.zlh.decoretor; 
  2.  
  3. public class CoconutSugarMilk extends CondimentDecorator{ 
  4.     private Beverage beverage; 
  5.  
  6.     public CoconutSugarMilk(Beverage beverage) { 
  7.         this.description = "coconut "
  8.         this.beverage = beverage; 
  9.     } 
  10.  
  11.     public double cost() { 
  12.         return 0.3 + beverage.cost(); 
  13.     } 
  14.  
  15.     public String getDescription() { 
  16.         return "cconut"+beverage.getDescription(); 
  17.     } 

可以看出,无论装饰多少层,所有的实现,其实都是一样的。

以下是测试代码:

 


  
  1. package com.zlh.decoretor; 
  2.  
  3. public class TestDriver { 
  4.     public static void main(String[] args) { 
  5.         Beverage sugarMilk = new SugarMilk(new Milk()); 
  6.         System.out.println(sugarMilk.getDescription()); 
  7.         System.out.println(sugarMilk.cost()); 
  8.          
  9.         Beverage coconutSugarMilk = new CoconutSugarMilk(sugarMilk); 
  10.         System.out.println(coconutSugarMilk.getDescription()); 
  11.         System.out.println(coconutSugarMilk.cost()); 
  12.     } 

以上就是全部源码,装饰类的典型应用就是I/O中streamBuffer等。