文章目录

  • 一、引入
  • 二、装饰器模式
    • 2.1 Intent 意图
    • 2.2 Applicability 适用性
    • 2.3 类图
    • 2.4 优缺点
    • 2.5 应用实例:Java IO 类
    • 2.6 应用实例:咖啡馆订购系统

一、引入

  • 咖啡馆订购系统

  • Initial 初始

    • 4 种咖啡

      • House blend (混合咖啡)
      • Dark Roast (深度烘培)
      • Decaf (低咖啡因咖啡)
      • Espresso (意式浓缩咖啡)

  • 需求变更:客户可以加料(咖啡、牛奶、糖等)

    • steamed milk
    • soy
    • mocha
    • Whip

使用继承:类爆炸 NO

修改父类:Beverage

需求倘若变更:料种类增加、料价格变化,需要修改 Beverage 类

Classes should be open for extension, but closed for modification:开放封闭原则,对修改封闭

No

Decorator…

二、装饰器模式

aka:Wrapper (包装器)

2.1 Intent 意图
  • Attach additional responsibilities to an object dynamically. 可动态地将其他职责附加到对象上.
  • Decorators provide a flexible alternative to subclassing for extending functionality. 装饰器为扩展功能提供了一种替代子类化的灵活替代方案.
    • Dynamically extension
    • Better than inheritance
2.2 Applicability 适用性
  • To add responsibilities to individual objects dynamically without affecting other object.
  • When extension by subclassing is impractical. 当子类化扩展是不切实际的.
    • 如,子类数量爆炸
2.3 类图

  • Component: defines the interface for objects that can have responsibilities added to them dynamically. 为可以动态地添加职责的对象定义接口
  • ConcreteComponent: defines an object to which additional responsibilities can be attached. 定义一个可以附加其他责任的对象.
  • Decorator: maintains a reference to a Component object and defines an interface that conforms to Component’s interface. 维护对 Component 对象的引用,并定义一个符合 Component 接口的接口
  • ConcreteDecorator: adds responsibilities to the component. 向组件添加职责
2.4 优缺点
  • 优点

    • More flexibility than static inheritance. 比静态继承更灵活

      • With Decorators, responsibilities can be added and removed at runtime simply by attaching and detaching them.
    • 避免"类爆炸"
    • 通过排列和组合,可以创建许多行为组合
    • 装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能
  • 缺点
    • Lots of little objects
    • A decorator and its component are not same
    • 多层装饰比较复杂
2.5 应用实例:Java IO 类

InputStream and OutputStream 字节流
Reader and Writer 字符流

FilterInputStream:protected volatile InputStream in;

FilterInputStream 与 InputStream 为组合和被组合关系

与装饰器设计模式类图相符!

public class JavaIO {public static void main(String[] args) throws FileNotFoundException {// Open an InputStream.FileInputStream in = new FileInputStream("test.dat");// Create a buffered InputStream.BufferedInputStream bin = new BufferedInputStream(in);// Create a buffered, data InputStream.DataInputStream dbin = new DataInputStream(bin);// Create an unbuffered, data InputStream.DataInputStream din = new DataInputStream(in);// Create a buffered, pushback, data InputStream.PushbackInputStream pbdbin = new PushbackInputStream(dbin);}
}
2.6 应用实例:咖啡馆订购系统
  • 饮品抽象类:Beverage
public abstract class Beverage {protected String description = "Unknown Beverage";public String getDescription() {return description;}public abstract double cost();
}
  • 咖啡类:继承 Beverage
public class DarkRoast extends Beverage {public DarkRoast() {description = "DarkRoast";}public double cost() {return .99;}
}
public class Espresso extends Beverage {public Espresso() {description = "Espresso";}public double cost() {return 1.99;}
}
public class HouseBlend extends Beverage {public HouseBlend() {description = "House Blend Coffee";}public double cost() {return .89;}
}
  • 装饰器:CondimentDecorator
public abstract class CondimentDecorator extends Beverage {public abstract String getDescription();
}
  • 装饰器子类:ConcreteDecorator
public class Mocha extends CondimentDecorator {Beverage beverage;public Mocha(Beverage beverage) {this.beverage = beverage;}public String getDescription() {return beverage.getDescription() + ", Mocha";}public double cost() {return .20 + beverage.cost();}
}
public class Soy extends CondimentDecorator {Beverage beverage;public Soy(Beverage beverage) {this.beverage = beverage;}public String getDescription() {return beverage.getDescription() + ", Soy";}public double cost() {return .15 + beverage.cost();}
}
public class Whip extends CondimentDecorator {Beverage beverage;public Whip(Beverage beverage) {this.beverage = beverage;}public String getDescription() {return beverage.getDescription() + ", Whip";}public double cost() {return .10 + beverage.cost();}
}
  • 使用与测试:
public class StarbuzzCoffee {public static void main(String[] args) {Beverage beverage = new Espresso();System.out.println(beverage.getDescription() + " $" + beverage.cost());Beverage beverage2 = new DarkRoast();beverage2 = new Mocha(beverage2);beverage2 = new Mocha(beverage2);beverage2 = new Whip(beverage2);System.out.println(beverage2.getDescription() + " $" + beverage2.cost());Beverage beverage3 = new HouseBlend();beverage3 = new Soy(beverage3);beverage3 = new Mocha(beverage3);beverage3 = new Whip(beverage3);System.out.println(beverage3.getDescription() + " $" + beverage3.cost());}
}

面向对象设计模式:结构型模式之装饰器模式相关推荐

  1. java外观设计修改_Java设计模式之外观模式和装饰器模式的设计(精选)

    前言 本篇来学习下结构型模式的外观模式和装饰器模式. 外观模式 简介 外观模式隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口.这种类型的设计模式属于结构型模式,它向现有的系统添加一个接 ...

  2. 设计模式之门面模式与装饰器模式详解和应用

    目录 1 门面模式定义 1.1 门面模式的应用场景 1.2 门面模式的通用写法 1.3 门面模式业务场景实例 1.4 门面模式在源码中的应用 1.5 门面模式的优缺点 2 装饰器模式 2.1 装饰器模 ...

  3. Java设计模式之五 ----- 外观模式和装饰器模式

    前言 在上一篇中我们学习了结构型模式的适配器模式和桥接模式.本篇则来学习下结构型模式的外观模式和装饰器模式. 外观模式 简介 外观模式隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口.这 ...

  4. 设计模式系列:搞懂装饰器模式,增加自身技能

    装饰器模式的定义:指在不改变原有对象的基础上,动态地给该对象增加一些额外的功能的模式,属于对象结构型模式. 装饰器模式的核心在于类的扩展,通过装饰器模式可以透明且动态的扩展类的功能. 装饰器模式的结构 ...

  5. 大聪明教你学Java设计模式 | 第七篇:装饰器模式

    前言 大聪明在写代码的过程中发现设计模式的影子是无处不在,设计模式也是软件开发人员在软件开发过程中面临的一般问题的解决方案.大聪明本着"独乐乐不如众乐乐"的宗旨与大家分享一下设计模 ...

  6. 装饰器模式与代理模式的区别_JS设计模式(三):装饰器模式、代理模式

    Do more 做的更多,比你上级给你安排的任务! 前言 在<不止代码>中提到了几个程序员典型的思维误区: 「 拜大牛为师 」「 业务代码一样很牛逼 」「 上班太忙没时间学习 」 我之前也 ...

  7. java模式之装饰器模式

    定义: 装饰器模式也叫作包装器模式,只在不改变原有对象的基础上,动态的给一个对象添加一些额外的职责.就增加功能来说,装饰器模式相比生成子类更为灵活,属于结构型设计模式 装饰器模式提供了比继承更有弹性的 ...

  8. 代理模式与装饰器模式有何区别?

    本文有一些争议,谈论的是设计模式中的代理模式和装饰器模式的区别,但笔者是非常赞同文章的观点的,有种豁然开朗的感觉. 以下是原文 代理模式与装饰器模式有何区别? 我想有必要对此问题谈一下我的个人理解,若 ...

  9. 面向对象程序设计(OOP设计模式)-结构型模式之装饰器模式的应用与实现

    课程名称:程序设计方法学 实验4:OOP设计模式-结构型模式的应用与实现 时间:2015年11月18日星期三,第3.4节 地点:理1#208 一.实验目的 加深对结构型设计模式的理解以及在开发中的实际 ...

  10. Java设计模式学习总结(11)——结构型模式之装饰器模式

    装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装.这种模式创建了一个装饰类,用来包装原 ...

最新文章

  1. Udacity机器人软件工程师课程笔记(十六)-机械臂仿真控制实例(其一)-Gazebo、RViz和Moveit!
  2. python基础教程学习笔记十二
  3. treeview自动从表中添加标题和列值做目录的方法2
  4. 无意间看到的浏览器记录......
  5. 网络研讨室_即将举行的网络研讨会:调试生产中Java的5种最佳实践
  6. .net core精彩实例分享 -- 基础篇
  7. 探讨一下常见支付系统的对外接口
  8. Eclipse 导入项目到git@osc中
  9. linux sudo输入密码无法获得锁,Linux系统提示无法获得锁/var/lib/dpkg/lock怎么办?
  10. matlab 带通滤波器_这就够了?一阶高通数字滤波器
  11. Tomcat可以在eclipse里启动,可是不能訪问首页的问题
  12. 全球十大机器人运动控制品牌
  13. MapReduce模型、大数据与数据挖掘、云计算的关系
  14. 天蝎项目整机柜服务器解决方案,天蝎2.0整机柜服务器技术规范rev0.5(final).doc
  15. 浏览器屏蔽百度推广广告
  16. html width 100 无效,html css 样式中100%width 仍有白边解决办法
  17. 吉林银行2021年上半年经营成果丰硕 支持实体经济能力显著增强
  18. floor和ceil函数
  19. SpringSecurity - RememberMe
  20. 关于Win10家庭版修改用户名的问题

热门文章

  1. JVM知识体系学习七:了解JVM常用命令行参数、GC日志详解、调优三大方面(JVM规划和预调优、优化JVM环境、JVM运行出现的各种问题)、Arthas
  2. 2023年中国渔业研究报告
  3. CoinDesk前CEO:2018年区块链的3个重大变化
  4. sql常见面试题(2)
  5. 建模助手:Revit中梁注释设置表达相对净高
  6. Python Exceptions Handling
  7. “985毕业,工作3年,不敢辞职”:年轻时最大的坑,是错把隐忍当磨砺
  8. open-falcon hadoop 搭建
  9. 毛书卿:4.30黄金最新行情分析,白银TD晚间操作策略及解套
  10. 比 rm 更安全的删除文件命令:shred