博客
关于我
设计模式-装饰者模式
阅读量:805 次
发布时间:2019-03-23

本文共 1604 字,大约阅读时间需要 5 分钟。

装饰者模式是面向对象编程中常用的一种高级设计模式。它允许我们对一对象的行为和属性进行动态的扩展,而无需修改现有的类结构。这与传统的继承方式相比,具有更高的灵活性和可扩展性。在本文中,我们将逐步阐述装饰者模式的设计思想、实现原理及其在实际项目中的应用实例。

装饰者模式分析

星巴克咖啡订单项目中,我们需要处理多种咖啡单品及其调料组合。选择传统的继承方式会导致大量waitlist类的生成,当需要新增单品咖啡或调料时,类的数量会呈指数级增长,导致维护成本高昂。为了解决这一问题,装饰者模式提供了一种更加灵活的解决方案。

装饰者模式在咖啡订单中的应用

  • 基类设计

    • Drink abstract类,代表所有咖啡饮品。
    • 每个咖啡单品都继承自Drink类,如ShortBlackEspresso等。
    • Coffee concrete类继承自Drink类,用于具体实现咖啡的价格和描述。
  • 装饰者类设计

    • Decorator类,作为基装饰者,持有一个Drink对象。
    • 具体的装饰者如MilkSoy等继承自Decorator类,它会在CoffeeDrink的基础上增加调料的描述和价格。
  • 动态组合

    • 使用装饰者可以实现任意的组合方式,例如:一份LongBlack加上一份Milk和两份Chocolate,可以通过多次调用Decorator构造相应的饮品。
  • 装饰者模式的核心原理

    装饰者模式的核心思想是动态地对一个对象的行为进行扩展。与传统的继承方式相比,其优点:

  • 避免类爆炸:通过动态组合而非硬编码,减少新增类的需求。
  • 提高维护性:当需要修改或新建调料时,只需添加新的装饰者类,不会影响现有类结构。
  • 灵活性高:可以根据实际需求自由组合不同的装饰者,满足多样化的订单需求。
  • 实例解析

    以咖啡订单项目为例:

    // 点一份长黑咖啡Drink order = new LongBlack();// 加入牛奶order = new Milk(order);// 加入一道巧克力order = new Chocolate(order);// 再加一道巧克力,可以叠加多个装饰者order = new Chocolate(order);// 最终价格:LongBlack的价格 + 牛奶的价格 + 两次巧克力的价格System.out.println("总费用:" + order.cost());

    每个Decorator类通过持有原始饮品对象和在cost()getDes()等方法中递归调用原始对象的方法,动态构建最终的饮品描述和价格。

    JDK中的装饰者模式

    在Java标准库中,装饰者模式广泛用于文件读取和数据加工流程。例如,FilterInputStream类就是一个典型的装饰者类,它包裹了原始的InputStream对象,并对其输入流程进行扩展。例如:

    public abstract class InputStream implements Closeable {    // 基本输入流操作方法    ...}public class FilterInputStream extends InputStream {    protected volatile InputStream in;    public FilterInputStream(InputStream input) {        this.in = input;    }    // 具体实现输入流操作,如读取数据时进行过滤    public int read(byte[] b, int off, int len) {        return in.read(b, off, len);    }    ...}

    这个设计模式的优点显而易见:无论是向现有的类添加新功能,还是修改现有行为,仅需创建新的装饰者类即可,而无需修改原始类结构。

    转载地址:http://tctzk.baihongyu.com/

    你可能感兴趣的文章
    No module named 'crispy_forms'等使用pycharm开发
    查看>>
    No module named cv2
    查看>>
    No module named tensorboard.main在安装tensorboardX的时候遇到的问题
    查看>>
    No module named ‘MySQLdb‘错误解决No module named ‘MySQLdb‘错误解决
    查看>>
    No new migrations found. Your system is up-to-date.
    查看>>
    No qualifying bean of type XXX found for dependency XXX.
    查看>>
    No resource identifier found for attribute 'srcCompat' in package的解决办法
    查看>>
    no session found for current thread
    查看>>
    No toolchains found in the NDK toolchains folder for ABI with prefix: mips64el-linux-android
    查看>>
    NO.23 ZenTaoPHP目录结构
    查看>>
    NO32 网络层次及OSI7层模型--TCP三次握手四次断开--子网划分
    查看>>
    NoClassDefFoundError: org/springframework/boot/context/properties/ConfigurationBeanFactoryMetadata
    查看>>
    Node JS: < 一> 初识Node JS
    查看>>
    Node-RED中使用JSON数据建立web网站
    查看>>
    Node-RED中使用json节点解析JSON数据
    查看>>
    Node-RED中使用node-random节点来实现随机数在折线图中显示
    查看>>
    Node-RED中使用node-red-browser-utils节点实现选择Windows操作系统中的文件并实现图片预览
    查看>>
    Node-RED中使用Notification元件显示警告讯息框(温度过高提示)
    查看>>
    Node-RED中实现HTML表单提交和获取提交的内容
    查看>>
    Node.js 8 中的 util.promisify的详解
    查看>>