星巴克咖啡订单项目(咖啡馆):

  1. 咖啡种类/单品咖啡:Espresso(意大利浓咖啡)、ShortBlack、LongBlack(美式咖啡)、Decaf(无因咖啡)

  2. 调料:Milk、Soy(豆浆)、Chocolate

  3. 要求在扩展新的咖啡种类时,具有良好的扩展性、改动方便、维护方便

  4. 使用OO 的来计算不同种类咖啡的费用: 客户可以点单品咖啡,也可以单品咖啡+调料组合。

方案1-解决星巴克咖啡订单项目

方案1-解决星巴克咖啡订单问题分析

  1. Drink 是一个抽象类,表示饮料

  2. des 就是对咖啡的描述, 比如咖啡的名字

  3. cost() 方法就是计算费用,Drink 类中做成一个抽象方法.

  4. Decaf 就是单品咖啡, 继承Drink, 并实现cost

  5. Espress && Milk 就是单品咖啡+调料, 这个组合很多

  6. 问题:这样设计,会有很多类,当我们增加一个单品咖啡,或者一个新的调料,类的数量就会倍增,就会出现类爆炸

方案2-解决星巴克咖啡订单(好点)

  1. 前面分析到方案1 因为咖啡单品+调料组合会造成类的倍增,因此可以做改进,将调料内置到Drink 类,这样就不会造成类数量过多。从而提高项目的维护性(如图)

方案2-解决星巴克咖啡订单问题分析

  1. 方案2 可以控制类的数量,不至于造成很多的类

  2. 在增加或者删除调料种类时,代码的维护量很大

  3. 考虑到用户可以添加多份调料时,可以将hasMilk 返回一个对应int

  4. 考虑使用装饰者模式

装饰者模式定义

  1. 装饰者模式:动态的将新功能附加到对象上。在对象功能扩展方面,它比继承更有弹性,装饰者模式也体现了开闭原则(ocp)
  2. 这里提到的动态的将新功能附加到对象和ocp 原则,在后面的应用实例上会以代码的形式体现,

装饰者模式原理

  1. 装饰者模式就像打包一个快递
    主体:比如:陶瓷、衣服(Component) // 被装饰者
    包装:比如:报纸填充、塑料泡沫、纸板、木板(Decorator)

  2. Component 主体:比如类似前面的Drink

  3. ConcreteComponent 和Decorator
    ConcreteComponent:具体的主体,
    比如前面的各个单品咖啡

  4. Decorator: 装饰者,比如各调料.
    在如图的Component 与ConcreteComponent之间,如果ConcreteComponent 类很多,还可以设计一个缓冲层,将共有的部分提取出来,抽象层一个类。

装饰者模式解决星巴克咖啡订单

装饰者模式下的订单:2 份巧克力+一份牛奶的LongBlack


说明

  1. Milk包含了LongBlack

  2. 一份Chocolate包含了(Milk+LongBlack)

  3. 一份Chocolate包含了(Chocolate+Milk+LongBlack)

  4. 这样不管是什么形式的单品咖啡+调料组合,通过递归方式可以方便的组合和维护。

源码

装饰者模式在JDK 应用的源码分析

Java 的IO 结构,FilterInputStream 就是一个装饰者

public abstract class InputStream implements Closeable{} //是一个抽象类,即Component
public class FilterInputStream extends InputStream { //是一个装饰者类Decorator
protected volatile InputStream in //被装饰的对象}
class DataInputStream extends FilterInputStream implements DataInput { //FilterInputStream 子类,也继承了被装饰的对象in }

说明

  1. InputStream 是抽象类, 类似我们前面讲的Drink

  2. FileInputStream 是InputStream 子类,类似我们前面的DeCaf, LongBlack

  3. FilterInputStream 是InputStream 子类:类似我们前面的Decorator 修饰者

  4. DataInputStream 是FilterInputStream 子类,具体的修饰者,类似前面的Milk, Soy 等

  5. FilterInputStream 类有protected volatile InputStream in; 即含被装饰者

  6. 分析得出在jdk 的io 体系中,就是使用装饰者模式

桥接模式和装饰者模式的区别

第一种说法
装饰器模式用于动态地添加职责,原本的功能必须执行,对用户而言重要的是添加的职责

桥接模式用于抽象和实现的分离,即从不同维度划分类的属性,以聚合的方式桥接,降低耦合。

第二种说法
1。桥接模式中所说的分离,其实是指将结构与实现分离(当结构和实现有可能发生变化时)或属性与基于属性的行为进行分离;而装饰者只是对基于属性的行为进行封闭成独立的类。

2。桥接中的行为是横向的行为,行为彼此之间无关联;而装饰者模式中的行为具有可叠加性,其表现出来的结果是一个整体,一个各个行为组合后的一个结果

第三种说法

区别:

1.没有装饰者和被装饰者的主次区别,桥接和被桥接者是平等的,不用继承自同一个父类。(即桥接可以互换)

2.桥接模式不用使用同一个接口;装饰模式用同一个接口装饰,接口在父类中定义。

相同点:

1.都可以处理类扩散的情况

总结:

桥接模式:抽象类(抽象接口)
装饰模式 抽象父类(抽象子类)

总结

有抽象的意识:有相同特征的就会被抽象出来
如:上面讲的把他们抽象成饮料类和调味类,
再根据适合的设计模式

抽象父类 Drink
抽象子类 Decorator

上面的装饰者模式其实就是:
抽象子类(抽象父类)

装饰者模式(通俗易懂)相关推荐

  1. 这是我见过最通俗易懂的 装饰者模式 讲解了!

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者:lewis0077 cnblogs.com/lewis007 ...

  2. 装饰器模式(通俗易懂)

    文章目录 装饰器模式 反例 #1 反例 #2 反例 #3 装饰器模式 执行示意图 UML类图 JDK源码中的装饰器模式展现 装饰java.io类UML类图 装饰器模式的简单实用 反例都是为了和装饰器模 ...

  3. 【实例学模式】一针见血装饰器模式

    目录 什么是装饰器模式 开发案例[奶茶店自助下单系统] 设计方案 对装饰器模式的思考 什么是装饰器模式 通常给对象添加功能,要么直接修改对象添加相应的功能,要么派生对应的子类来扩展,抑或是使用对象组合 ...

  4. 图解Java设计模式学习笔记——结构型模式(适配器模式、桥接模式、装饰者模式、组合模式、外观模式、享元模式、代理模式)

    一.适配器模式(类适配器.对象适配器.接口适配器) 1.现实生活中的例子 泰国插座用的是两孔的(欧标),可以买个多功能转换插头(适配器),这样就可以使用了国内的电器了. 2.基本介绍 适配器模式(Ad ...

  5. 手抓饼加生菜加鸡蛋的装饰器模式

    装饰器模式 装饰器模式(Decorator Patter),也称为包装模式(Wrapper Pattern)是指在不改变原有对象的基础之上,将功能附加在对象上,提供了比继承更有弹性的替代方案(扩展原有 ...

  6. 设计模式之装饰者模式--钢铁侠的形成

    前言 本文主要讲述java常见设计模式之装饰者模式,文中使用通俗易懂的案例,使你更好的学习本章知识点并理解原理,做到有道无术. 一.什么是装饰者模式 装饰者模式是23种设计模式中结构型模式的一种,它的 ...

  7. java设计模式----装饰器模式

    Decorator装饰器,顾名思义,就是动态地给一个对象添加一些额外的职责,就好比为房子进行装修一样.因此,装饰器模式具有如下的特征: 它必须具有一个装饰的对象. 它必须拥有与被装饰对象相同的接口. ...

  8. Android 设计模式:(三)装饰者模式 —— 装饰对象

    *利用组合(composition)和委托(delegation)可以在运行时实现继承行为的效果,动态地给对象加上新的行为. *利用继承扩展子类的行为,是在编译时静态决定的:利用组合的做法,可以在运行 ...

  9. java I/O之装饰者模式

    装饰者: Decorator模式(别名Wrapper):动态将职责附加到对象上,若要扩展功能,装饰者提供了比继承更具弹性的代替方案. 装饰者模式意图: 动态的给一个对象添加额外的职责.Decorato ...

最新文章

  1. caffe中在某一层获得迭代次数的方法以及caffe编译时报错 error: ‘to_string‘ is not a member of ‘std‘解决方法
  2. python掌握程度怎么判断-想要学习人工智能需要掌握Python到什么程度
  3. window编程_消息分类
  4. 运维如何逆袭?月薪30K的牛逼运维需要的知识,全在这里了
  5. mysql随机显示记录_MySQL随机读取表中记录
  6. mysql数据通讯方式_c# 与 Mysql 的通讯方式总结
  7. WebApi的调用-3.Basic验证
  8. ionic 组件之二维码扫描
  9. python调用metasploit自动攻击_Python脚本与Metasploit交互进行自动永恒之蓝攻击-Go语言中文社区...
  10. Android开发实践:线程与异步任务
  11. Flutter videoplayer
  12. python3爬取微博评论教程_python3爬取微博评论并存为xlsx
  13. 用户DSN、系统DSN、文件DSN的区别
  14. “安全删除硬件”图标 隐藏
  15. 如何识别手写汉字?跟着步骤就能完成
  16. 06-CSS盒模型详解
  17. 【赚钱应跟Apple,做大不忘Google】移动开发时代的开发者选择
  18. 在jupyter中使用python绘制线条椭球
  19. python公开课乐博学院_Python 变量
  20. LoadLibrary()动态调用dll失败,GetLastError()返回126

热门文章

  1. Adobe 软件安装出现 183 错误
  2. 查询江苏丹阳高考成绩2021,2021年镇江高考状元是谁分数多少分,历年镇江高考状元名单...
  3. 深度学习之遥感图像标注(二)
  4. 【JY】曹博士的土木工程有限元学习历程
  5. 微信实验二、配置微信公众号
  6. 华为Mate Xs 2发布,持续引领折叠屏手机创新
  7. 点云 3D 目标检测 - SECOND(Sensors 2018)
  8. 一文搞懂两表关联时left join 、 on 以及where条件不同写法对结果的影响--文末有结论
  9. 一拍二吹三扯皮?一份“靠谱”的年度经营计划
  10. 1-编程常用日语单词积累