装饰者模式

作者: imyyq_star | 来源:发表于2018-01-05 09:18 被阅读30次

需求

咖啡店,客户可能会叫一种饮料,并且指定某些调料加入进去,比如深焙咖啡,用摩卡,奶泡,牛奶作为调料,计算出总价

饮料类,被装饰者

/**
 * 饮料父类
 */
public abstract class Beverage
{
    /**
     * 描述饮料的字段
     */
    protected String description = "Unknown Berverage";

    public String getDescription()
    {
        return description;
    }

    /**
     * 计算价钱的方法,必须在子类中实现
     */
    public abstract double cost();
}

/**
 * 暗烤咖啡
 */
public class DarkRoast extends Beverage
{
    public DarkRoast()
    {
        description = "暗烤咖啡 DarkRoast"; // 描述此饮料
    }

    /**
     * 返回此饮料的价钱
     */
    @Override
    public double cost()
    {
        return .99;
    }
}

调料类,装饰者

/**
 * 调料类,也就是装饰者
 * 
 * 为了让 装饰者 能够替代 被装饰者 ,因此 装饰者 继承 被装饰者
 */
public abstract class Condiment extends Beverage
{
    /**
     * 所有的装饰者类,都必须重新实现此方法,因为必须有不同的名称
     */
    @Override
    public abstract String getDescription();
}

/**
 * 摩卡调料
 */
public class Mocha extends Condiment
{
    private Beverage beverage; // 用来记住 被装饰者 ,也就是此调料要加在哪个饮料上

    /**
     * 想办法把被装饰者记录在变量中
     */
    public Mocha(Beverage beverage)
    {
        this.beverage = beverage;
    }

    /**
     * 把被装饰者和装饰者的名称组合起来,比如:混合咖啡,摩卡
     */
    @Override
    public String getDescription()
    {
        return beverage.getDescription() + ", 摩卡调料 Mocha";
    }

    /**
     * Mocha自身的价钱+饮料的价钱
     */
    @Override
    public double cost()
    {
        return 0.20 + beverage.cost();
    }
}

/**
 * 豆奶调料
 */
public class Soy extends Condiment
{
    private Beverage beverage;

    public Soy(Beverage beverage)
    {
        this.beverage = beverage;
    }

    @Override
    public String getDescription()
    {
        return beverage.getDescription() + ", 豆奶调料 Soy";
    }

    @Override
    public double cost()
    {
        return .15 + beverage.cost();
    }
}

测试

// 点一杯饮料
Beverage beverage2 = new DarkRoast();
// 用调料去装饰饮料
beverage2 = new Mocha(beverage2);
beverage2 = new Whip(beverage2);
// 算出总价钱
System.out.println(beverage2.getDescription() + " $" + beverage2.cost());

疑问

  • 以上全用了继承,这里是利用继承达到类型匹配的目的,并不是获得行为。方便更有弹性的混合匹配
  • 每当需要新的调料,甚至是新的饮料,都可以新增并方便的加入
  • 并非一定要用接口,如果抽象类用的好好的,并且已经满足需求,就不用再去修改他
  • 会导致有很多的小类

Java 中应用到装饰者模式的地方

Java I/O

设计原则 5

类应该对扩展开放,对修改关闭,在不修改现有代码的情况下,就搭配新的行为

装饰者模式定义:

动态的将责任附加到对象上,对于扩展的话,比继承更有弹性。

相关文章

  • 如何利用装饰者模式在不改变原有对象的基础上扩展功能

    目录 什么是装饰者模式 普通示例 装饰者模式示例 类图关系 装饰者模式使用场景 装饰者模式优点 装饰者模式缺点 什...

  • 装饰者模式

    装饰者模式 装饰者模式和适配器模式对比 装饰者模式 是一种特别的适配器模式 装饰者与被装饰者都要实现同一个接口,主...

  • java IO 的知识总结

    装饰者模式 因为java的IO是基于装饰者模式设计的,所以要了解掌握IO 必须要先清楚什么事装饰者模式(装饰者模式...

  • 设计模式-装饰者模式

    装饰者模式概念: 装饰者模式又名包装(Wrapper)模式。装饰者模式以对客户端透明的方式扩展对象的功能,是继承关...

  • java - 装饰者模式

    装饰者模式 装饰者模式:动态将责任添加到对象上。如果需要扩展功能,装饰者提供了比继承更有弹性的解决方案。装饰者模式...

  • 设计模式之装饰者模式(Decorator Pattern)

    What: 装饰者模式又名包装(Wrapper)模式。装饰者模式动态地将责任附加到对象身上。若要扩展功能,装饰者提...

  • 装饰者(Decorator)模式

    装饰者(Decorator)模式装饰模式又名包装(Wrapper)模式。装饰模式是继承关系的一个替代方案。装饰模式...

  • 2、装饰者模式

    装饰者模式 一、基本概念 二、结构 三、案例1、装饰者模式案例2、JavaIO中使用装饰者模式 四、总结 一、基本...

  • PHP的设计模式-装饰者模式

    装饰者模式 装饰者模式 装饰者模式类似蛋糕,有草莓味、奶酪等种类,但是它们的核心都是蛋糕。 不断地将对象添加装饰的...

  • 设计模式 | 装饰者模式及典型应用

    前言 本文的主要内容: 介绍装饰者模式 示例 源码分析装饰者模式的典型应用Java I/O 中的装饰者模式spri...

网友评论

    本文标题:装饰者模式

    本文链接:https://www.haomeiwen.com/subject/xljjnxtx.html