java模式—装饰者模式

在公司上班,经过大半天的忙碌,每到下午三四点,肚子就感觉咕咕叫,嘴巴也挺寂寞的,于是乎就想着点杯奶茶慰劳下自己。喝过奶茶的小伙伴都知道,点奶茶加点配料更爽口,例如燕麦(oats),珍珠(pearl),布丁(pudding)等等,当然了,每种配料的价格都是不一样的,那么我们今天要做的就是,不管你是点奶茶,还是咖啡,还是鲜果茶;不管你在茶里面加布丁、还是珍珠,最终需要展示价格是奶茶基础价加上每一种所选配料价格的总和。例如:奶茶加燕麦,加珍珠,加布丁,销售价格:12.0

规格表如下:

1、下面我们先看代码,再总结:

/**
 * Created by sww_6 on 2019/4/25.
 * 被装饰对象的基类
 */
public abstract class Tea {

  public abstract String desc();

  public abstract double price();
}
/**
 * Created by sww_6 on 2019/4/25.
 * 具体被装饰对象,奶茶基类。
 */
public class MilkTea extends Tea {

  public String desc() {
    return "奶茶";
  }

  public double price() {
    return 8;
  }
}
/**
 * Created by sww_6 on 2019/4/25.
 * 具体被装饰对象,咖啡基类。
 */
public class Coffee extends Tea {

  public String desc() {
    return "拿铁";
  }

  public double price() {
    return 10;
  }
}
/**
 * Created by sww_6 on 2019/4/25.
 * 配料装饰者
 */
public class DosingDecorator extends Tea {

  private Tea tea;

  public DosingDecorator(Tea tea) {
    this.tea = tea;
  }

  public String desc() {
    return tea.desc();
  }

  public double price() {
    return tea.price();
  }
}
/**
 * Created by sww_6 on 2019/4/25.
 * 配料具体装饰者,燕麦。
 */
public class Oats extends DosingDecorator {

  public Oats(Tea tea) {
    super(tea);
  }

  @Override
  public String desc() {
    return super.desc() + "加燕麦,";
  }

  @Override
  public double price() {
    return super.price() + 1;
  }
}
/**
 * Created by sww_6 on 2019/4/25.
 * 配料具体装饰者,珍珠。
 */
public class Pearl extends DosingDecorator {

  public Pearl(Tea tea) {
    super(tea);
  }

  @Override
  public String desc() {
    return super.desc() + "加珍珠,";
  }

  @Override
  public double price() {
    return super.price() + 1;
  }
}
/**
 * Created by sww_6 on 2019/4/25.
 * 配料具体装饰者,布丁。
 */
public class Pudding extends DosingDecorator {

  public Pudding(Tea tea) {
    super(tea);
  }

  @Override
  public String desc() {
    return super.desc() + "加布丁,";
  }

  @Override
  public double price() {
    return super.price() + 2;
  }
}

下面就是测试类。

/**
 * Created by sww_6 on 2019/4/25.
 * 测试类,测试奶茶和咖啡。
 */
public class Test {

  public static void main(String[] args) {
    Tea tea;
    tea = new Coffee();
    System.out.println(tea.desc()+"销售价格:"+tea.price());

    tea = new MilkTea();
    tea = new Oats(tea);
    tea = new Pearl(tea);
    tea = new Pudding(tea);
    System.out.println(tea.desc() + "销售价格:"+tea.price());
  }
}

测试结果如下:

拿铁销售价格:10.0
奶茶加燕麦,加珍珠,加布丁,销售价格:12.0

2、类图

 

 大家看,这个类图是不是一目了然呢?

3、参与者

    1.Component(被装饰对象的基类),即tea抽象类

      定义一个对象接口,可以给这些对象动态地添加职责。

    2.ConcreteComponent(具体被装饰对象),即Coffee和MilkTea类

      定义一个对象,可以给这个对象添加一些职责。

    3.Decorator(装饰者抽象类),即DosingDecorator(配料装饰者)类

      维持一个指向Component实例的引用,并定义一个与Component接口一致的接口。

    4.ConcreteDecorator(具体装饰者),即珍珠(Pearl),燕麦(Oats),布丁(Pudding)类

      具体的装饰对象,给内部持有的具体被装饰对象,增加具体的职责。

4、涉及角色

(1)抽象组件:定义一个抽象接口,来规范准备附加功能的类

(2)具体组件:将要被附加功能的类,实现抽象构件角色接口

(3)抽象装饰者:持有对具体构件角色的引用并定义与抽象构件角色一致的接口

(4)具体装饰:实现抽象装饰者角色,负责对具体构件添加额外功能。

5、意图: 

动态地给一个对象添加一些额外的职责。就增加功能来说, Decorator模式相比生成子类更为灵活。该模式以对客 户端透明的方式扩展对象的功能。

 

posted @ 2019-04-25 14:39 左手背右手背 阅读(...) 评论(...) 编辑 收藏