装饰器模式

一、装饰器模式
  1. 装饰器模式的概念:

装饰器模式 (Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。装饰者可以在所委托被装饰者的行为之前或之后加上自己的行为,以达到特定的目的。

 

 

  1. 模式的结构

  • 抽象组件(Component):需要被装饰的抽象对象
  • 具体组件(ConcreteComponent),是被装饰类,他本身是个具有一些功能的完整的类。
  • 抽象装饰类(Decorator),实现了Component接口的同时还在内部维护了一个ConcreteComponent的实例,并可以通过构造函数初始化。而Decorator本身,通常采用默认实现,他的存在仅仅是一个声明:我要生产出一些用于装饰的子类了。而其子类才是赋有具体装饰效果的装饰产品类。
  • 具体装饰类(ConcreteDecorator):每一种装饰产品都具有特定的装饰效果。可以通过构造器声明装饰哪种类型的ConcreteComponent,从而对其进行装饰。

     

     

3.模式的适用场景:

扩展一个类的功能。

动态增加功能,动态撤销。

4.模式的特点:

4.1优点:

装饰类和被装饰类可以独立发展,不会相互耦合

动态的将责任附加到对象身上。在对象功能扩展方面,它比继承更有弹性。

4.2缺点:

多层装饰比较复杂。

 

 

 

二、范例

相信大家都去星巴克喝过咖啡,或者奶茶,我们在买coffe的时候,首先选择一个基本的coffe类型,比如卡布奇洛,然后添加各种佐料:摩卡,豆浆,蒸奶等。基本类型是基础价,佐料又要宁外算钱

 

一般的设计方案就是如上图所示那样,但是采用这种设计方案的话,如果有100多种饮料的话,代码的重用率会很低,代码会显得冗长复杂,。

 

这种设计方案我们把所有的佐料的放到公共父类中,让所有子类都拥有所有的佐料,只是在类中判断到底加没加。但是也有很大的问题,我们把所有的佐料的放到公共父类中,让所有子类都拥有所有的佐料,只是在类中判断到底加没加。当遇到多份问题,和增加调料种类的时候就会显得复杂。在设计模式原则中有一个非常重要的原则,就是开闭原则:对扩展开放,对修改关闭。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  1.    //创建抽象组件Drink
  2. public abstract class Drink {
  3.    public String description="";
  4.    private float price=0f;;
  5.  
  6.  
  7.    public void setDescription(String description)
  8.    {
  9.       this.description=description;
  10.    }
  11.  
  12.    public String getDescription()
  13.    {
  14.       return description+"-"+this.getPrice();
  15.    }
  16.    public float getPrice()
  17.    {
  18.       return price;
  19.    }
  20.    public void setPrice(float price)
  21.    {
  22.       this.price=price;
  23.    }
  24.    public abstract float cost();
  25.  
  26. }

 

 

 

 

  1. //创建具体组件(ConcreteComponent)
  2. public class Coffee extends Drink {
  3.  
  4.    @Override
  5.    public float cost() {
  6.       // TODO Auto-generated method stub
  7.       return super.getPrice();
  8.    }
  9. }
  10. //创建具体组件(ConcreteComponent)Decaf
  11. public class Decaf extends Coffee {
  12.    public Decaf()
  13.    {
  14.       super.setDescription("Decaf");
  15.       super.setPrice(3.0f);
  16.    }
  17. }
  18. //创建抽象装饰类(Decorator)
  19. public class Decorator extends Drink {
  20.    private Drink Obj;
  21.  
  22.    public Decorator(Drink Obj){
  23.       this.Obj=Obj;
  24.    };
  25.  
  26.  
  27.    @Override
  28.    public float cost() {
  29.       // TODO Auto-generated method stub
  30.  
  31.       return super.getPrice()+Obj.cost();
  32.    }
  33.  
  34.    @Override
  35.    public String getDescription()
  36.    {
  37.       return super.description+"-"+super.getPrice()+"&&"+Obj.getDescription();
  38.    }
  39.  
  40.    }
  41. //创建具体装饰类(ConcreteDecorator)
  42. public class Milk extends Decorator {
  43.  
  44.    public Milk(Drink Obj) {
  45.       super(Obj);
  46.       // TODO Auto-generated constructor stub
  47.       super.setDescription("Milk");
  48.       super.setPrice(2.0f);
  49.    }
  50.  
  51. }
  52. //创建具体装饰类(ConcreteDecorator)
  53. public class Chocolate extends Decorator {
  54.  
  55.    public Chocolate(Drink Obj) {
  56.       super(Obj);
  57.       // TODO Auto-generated constructor stub
  58.       super.setDescription("Chocolate");
  59.       super.setPrice(3.0f);
  60.    }
  61.  
  62. }
  63. //主函数
  64. public class CoffeeBar {
  65.  
  66.  
  67.    public static void main(String[] args) {
  68.  
  69.       Drink order;
  70.       order=new Decaf();
  71.       System.out.println("order1 price:"+order.cost());
  72.       System.out.println("order1 desc:"+order.getDescription());
  73.  
  74.       System.out.println("****************");
  75.       order=new LongBlack();
  76.       order=new Milk(order);
  77.       order=new Chocolate(order);
  78.       order=new Chocolate(order);
  79.       System.out.println("order2 price:"+order.cost());
  80.       System.out.println("order2 desc:"+order.getDescription());
  81.  
  82.    }
  83. }
posted on 2018-03-28 13:06  朽木藏虫  阅读(123)  评论(0)    收藏  举报