设计模式 |03 装饰者模式

本贴最后更新于 1935 天前,其中的信息可能已经时移世改

开头说几句

博主的博客地址:https://www.jeffcc.top/
推荐入门学习设计模式 java 版本的数据 Head First 《设计模式》

什么是装饰者模式

专业定义:装饰者模式可以动态得讲责任附加到对象上,若要拓展功能,装饰者模式提供了比继承更加有弹性的替代方案。
个人见解:装饰者模式重点在于装饰者,我们可以不修改对象的前提下,对对象进行功能的拓展,不通过继承来实现行为的拓展,而是通过组合和委托来实现!以免出现继承泛滥以及一些其他的业务修改对象代码而带来的 bug。

设计原则

  1. 类应该对拓展开放,对修改关闭。我们的目标是允许类容易拓展,再不修改代码的情况下,就可以搭配新的行为。
  2. 并不是要求对类的所有部分都设计成开放-关闭原则,应该把注意力放在设计中最有可能改变的地方,然后应用开放-关闭的原则,过多的设计会造成浪费,同时也会造成代码变得负责而难以理解,并无太多益处。

设计方法

  1. 装饰者和被装饰者具有相同的超类型;这里用到了继承的方式来实现同类型,但是并没有使用到继承来拓展行为,所以这不违背多使用组合而少使用继承的原则;
  2. 可以使用一个或者多个装饰者来装饰一个对象;
  3. 既然装饰者和被装饰者都有相同的超类型,所以可以在任何需要原始数据类型的地方使用装饰对象代替;
  4. 装饰者可以在所委托被装饰的行为之前或者之后,加上自己的行为,以达到某种特定的目的;
  5. 对象可以在任何时候被装饰;

模式实例

实例背景

一家咖啡店需要设计一个订单系统,其中的订单价格和订单描述这一方面需要设计出一种优秀的模式,
每款饮料都继承自 Beverage,饮料配有配料以及本身的价格以及杯的大小的价格不同而有不同的定价。

代码实现

项目结构

image.png

项目类图

image.png

饮料抽象类
调料抽象类
饮料 1 Espresso
饮料 2 HouseBlend
调料 1 Mocha
调料 2 Whip
咖啡店测试
输出结果

image.png

分析

关键在于:装饰者 CondimentDecorator 一定要注意继承被装饰者的抽象类 Beverage,这样才能够实现不断得进行装饰。

现实中的装饰者 java I/O

Java 世界中有太多的装饰者模式的设计了,java.io 包中就有许多这样的装饰者;
FileInputStream 就是一个被装饰的组件,提供最基本的 io 功能;
而 BufferedInputStream 是一个具体的装饰者,它加入两种行为:利用缓冲输入来改善性能,用一个 readLine 方法来增强了接口;
LineNumberInputStream 也是一个具体的装饰者,它加上了计算行数的功能。

挖掘源码我们也可以发现: 这些 io 的装饰者都继承自同一个超类,这样使得 io 的装饰起来便捷了很多

装饰者模式的一个小缺点

利用装饰者模式造成的设计中有大量的小类,数量十分多,可能会造成使用此 API 的程序员的困扰。但是我们理解了装饰者模式的工作原理了,就能够在以后的工作中容易的辨识出类是如何组织的,也就能高效的进行开发了!


END
2019 年 9 月 3 日 13:11:51

  • 设计模式

    设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。

    200 引用 • 120 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...