zoukankan      html  css  js  c++  java
  • 第三式 装饰者模式

    装饰者模式

    一 卡旺卡扩张带来的问题

      卡旺卡在很短的时间内快速扩张,这让他们的系统维护起来越来越力不从心。之前的设计类图如下

      

      购买饮料时,如果要求在里面加糖、加冰、加奶泡等。材料的部分单独收费时,我们需要根据不同的调料和奶茶进行组合,然后再算出费用。

      这就需要有多少种组合就得维护出多少种饮料类出来,简直就是类爆炸。如果某种调料价格调整,如果新增了一个新的调料,这时将掉入一个

      维护的深渊中,是维护的噩梦。这样的设计违反了开放-关闭原则。

      设计原则:开放-关闭原则,简称开闭原则,即类应该对扩展开放,对修改关闭。

    二 认识装饰者模式

      顾客点了一份红豆奶茶,加糖,加冰;装饰者模式走的流程图是,先去找加冰cost,再到加糖的cost,然后再是红豆奶茶本体的cost,全部累加完毕之后,

      返回的结果是整体的花费。

      

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

      装饰者类图如下

      

    三 代码实现

      1.饮料抽象类

    public abstract class Drink {
    String description;

    public String getDescription(){
    return description;
    }
    public abstract double cost();
    }
    2.创建具体的奶茶对象
    public class MilkTea extends Drink {

    public MilkTea(){
    description = "Milk Tea";
    }

    public double cost() {
    return 10;
    }
    }
    3.创建装饰者抽象类,将饮料类中的描述方法也抽象化
    public abstract class Decorator extends Drink{
    public abstract String getDescription();
    }
    4.创建加冰,加糖,加奶 三个装饰者类
    public class AddIce extends Decorator {
    Drink drink;

    public AddIce(Drink drink){
    this.drink = drink;
    }

    public String getDescription() {
    return "加冰,"+drink.getDescription();
    }

    public double cost() {
    return 5+drink.cost();
    }
    }
    public class AddSugar extends Decorator {
    Drink drink;

    public AddSugar(Drink drink){
    this.drink = drink;
    }

    public String getDescription() {
    return "加糖,"+drink.getDescription();
    }

    public double cost() {
    return 6+drink.cost();
    }
    }
    public class AddMilk extends Decorator {
    Drink drink;

    public AddMilk(Drink drink){
    this.drink = drink;
    }

    public String getDescription() {
    return "加奶,"+drink.getDescription();
    }

    public double cost() {
    return 7+drink.cost();
    }
    }
    5.测试
    public class Test {
    public static void main(String[] args){
    Drink d = new MilkTea();
    d = new AddIce(d);
    d = new AddMilk(d);
    d = new AddSugar(d);

    System.out.println(d.getDescription()+"$"+d.cost());
    }
    }
    结果如下:

      

      当客户有新的需求,需要提供不同容量大小的奶茶是,如小杯,中杯,大杯。我们可以在Drink类中加上size,然后在各自的调料装饰者类中,根据size的不同

     收取不同的费用。

    四 jdk中的装饰者模式

      java.io包中类超级多,里面基本上都是装饰者类,例如读取文件数据的类。

      

    
    
  • 相关阅读:
    表达式执行工具方法
    Mysql表创建外键报错
    JVM打印加载类的详情信息
    Shell脚本查询进程存活信息
    旋转数组的最小数字
    斐波那契数列(水题)
    用两个栈实现队列
    变态跳台阶
    跳台阶
    9*9乘法表(5种输出格式)
  • 原文地址:https://www.cnblogs.com/bwyhhx2018/p/10661303.html
Copyright © 2011-2022 走看看