第二节:装饰者模式—定义与应用

一、装饰者模式(Decorator)

  1、装饰者模式定义

    (1)装饰者模式:动态的将新功能附加到对象上。在对象功能扩展方面,它比继承更有弹性,装饰者模式也体现了开闭原则(OCP);

    (2)这里提到的动态的将新功能附加到对象 OCP 原则,下面使用代码的方式学习。

  2、装饰者模式原理

    (1)装饰者模式就像打包一个快递;

        •  主体:比如:陶瓷,衣服 //被修饰者;
        •  包装:比如:报纸填充、塑料泡沫、纸板、木板  //装饰者 Decorator

    (2)Component 主体:比如类似前面的 Drink

    (3)ConcreteComponent 和 Decorator

        ① ConcreteComponent:具体的主体;比如前面的各个单品咖啡;

        ② Decorator:装饰者,比如各种调料;

    (4)在如图的 Component 与 ConcreteComponent 之间,如果 ConcreteComponent 类很多,还可以设计一个缓冲层,将共有的部分提取出来,抽象层一个类。

      

二、装饰者模式解决星巴克咖啡订单分析

   说明:

    1、Drink 类就是前面说的抽象类,Component;

    2、ShortBlack 就是单品咖啡;

    3、Decorator 是一个装饰类,喊有一个被装饰的对象(Drink obj);

    4、Decorator 的 cost 方法进行一个费用的叠加计算,递归的计算价格;

三、用装饰者模式解决咖啡订单需求

  1、装饰者模式下的订单:2分巧克力 + 1份牛奶的 LongBlack

     

     说明:

    (1)Milk 包含了 LongBlack;

    (2)一份 Chocolate 包含了(Milk + LongBlack)

    (3)一份 Chocolate 包含了 (Chocolate + Milk + LongBlack)

    (4)这样不管是什么形式的单品咖啡 +  调料组合,通过递归方式可以方便的组合和维护;

  2、装饰者模式咖啡订单项目应用实例

    抽象类:Drink

 1 public abstract class Drink {
 2 
 3     public String des; //描述
 4     private float price = 0.0f;
 5 
 6     public String getDes() {
 7         return des;
 8     }
 9 
10     public void setDes(String des) {
11         this.des = des;
12     }
13 
14     public float getPrice() {
15         return price;
16     }
17 
18     public void setPrice(float price) {
19         this.price = price;
20     }
21 
22     /**
23      * 计算费用的抽象方法,子类来实现
24      * @return
25      */
26     public abstract float cost();
27 }

   主体类:Coffee 及其下面多种类型的实现

 1 public class Coffee extends Drink{
 2 
 3     @Override
 4     public float cost() {
 5         return super.getPrice();
 6     }
 7 }
 8 
 9 --------------------------------------
10 public class ShortBlack extends Coffee {
11 
12     public ShortBlack() {
13         setDes("ShortBlack");
14         setPrice(4.0f);
15     }
16 }
17 
18 --------------------------------------
19 public class LongBlack extends Coffee {
20 
21     public LongBlack() {
22         setDes("LongBlack");
23         setPrice(5.0f);
24     }
25 }
26 --------------------------------------
27 public class Espresso extends Coffee {
28 
29     public Espresso() {
30         setDes("意大利咖啡");
31         setPrice(6.0f);
32     }
33 
34 }
35 --------------------------------------
36 public class DeCaf extends Coffee {
37 
38     public DeCaf() {
39         setDes("无因咖啡");
40         setPrice(1.0f);
41     }
42 }

    装饰类:Decorator 及其下面多种调料

 1 public class Decorator extends Drink {
 2 
 3     private Drink obj;
 4 
 5     /**组合进去**/
 6     public Decorator(Drink obj) {
 7         this.obj = obj;
 8     }
 9 
10     @Override
11     public float cost() {
12         // getPrice() 自己价格
13         return super.getPrice() + obj.cost();
14     }
15 
16     @Override
17     public String getDes() {
18         // obj 被装饰者的信息
19         return super.des + " " + super.getPrice() + "&&" + obj.getDes();
20     }
21 }
22 ----------------------------------------------
23 public class Milk extends Decorator {
24     /**
25      * 组合进去
26      *
27      * @param obj
28      **/
29     public Milk(Drink obj) {
30         super(obj);
31         setDes("牛奶");
32         setPrice(2.0f);
33     }
34 }
35 ----------------------------------------------
36 public class Chocolate extends Decorator {
37     /**
38      * 组合进去
39      *
40      * @param obj
41      **/
42     public Chocolate(Drink obj) {
43         super(obj);
44         setDes("巧克力");
45         setPrice(3.0f);
46     }
47 }
48 ----------------------------------------------
49 public class Soy extends Decorator {
50     /**
51      * 组合进去
52      *
53      * @param obj
54      **/
55     public Soy(Drink obj) {
56         super(obj);
57         setDes("豆浆");
58         setPrice(1.5f);
59     }
60 }
61 ----------------------------------------------

  咖啡店测试类:

 1 public class CoffeeBar {
 2     public static void main(String[] args) {
 3         //装饰者模式的订单:2份巧克力 + 一份牛奶的 LongBlack
 4 
 5         //1.点一份 LongBlack
 6         Drink order = new LongBlack();
 7         System.out.println("单品费用1=" + order.getPrice() + "  描述信息=" + order.getDes());
 8 
 9         //2.加入一份牛奶
10         order = new Milk(order);
11         System.out.println("order 加入牛奶费用2=" + order.getPrice() + "  描述信息=" + order.getDes());
12 
13         //3.加入一份巧克力
14         order = new Chocolate(order);
15         System.out.println("order 又加入巧克力费用3=" + order.getPrice() + "  描述信息=" + order.getDes());
16 
17         //4.再加入一份巧克力
18         order = new Chocolate(order);
19         System.out.println("order 两份巧克力,一份牛奶费用4=" + order.getPrice() + "  描述信息=" + order.getDes());
20     }
21 }

  运行结果:

单品费用1=5.0  描述信息=LongBlack
order 加入牛奶费用2=2.0  描述信息=牛奶 2.0&&LongBlack
order 又加入巧克力费用3=3.0  描述信息=巧克力 3.0&&牛奶 2.0&&LongBlack
order 两份巧克力,一份牛奶费用4=3.0  描述信息=巧克力 3.0&&巧克力 3.0&&牛奶 2.0&&LongBlack
原文地址:https://www.cnblogs.com/niujifei/p/14318621.html