1.概述

装饰者模式是一种结构性设计模式,它能够动态地将新功能附加到对象上,却又不改变对象,在对象功能扩展方面,比继承更富有弹性,且符合开闭原则。这种模式创建了一个类,用来包装原有的类,在保证原来类的功能前提下,增加了额外的功能。本文将分析装饰者模式的概念及使用。

2.概念及使用

2.1 类图

装饰者类图如下:

上述类图包含了装饰着四个核心的部分:抽象组件(Component)、被装饰者(ConcreteComponent)、装饰者组件(Decorator)、具体装饰类(ConcreteDecorator),具体解释如下:

(1)抽象组件(Component):抽象出一个接口,规范需要准备接受附加责任的对象;
(2)被装饰者(ConcreteComponent):需要装饰的具体对象;
(3)装饰者组件(Decorator):装饰者基类,用于持有组件对象的实例引用,装饰具体的组件对象;
(4)具体装饰(ConcreteDecorator):负责给构件对象装饰附加的功能。

2.2 案例

顾客在奶茶店里点奶茶,奶茶有不同的品种:原味奶茶、黑糖珍珠奶茶、芒果耶奶奶茶等,店员也可以根据客户需要制作不同的奶茶。这里就可以用装饰者模式来对奶茶对象进行加工,生成顾客最终需要的奶茶。


编码如下:

//定义抽象组件(奶茶)
public interface MilkyTea {String makeTea();Double calCost();
}//定义被装饰者(这里以原味奶茶为基础)
public class PureMilkyTea implements MilkyTea {private Double cost;public Double getCost() {return cost;}public void setCost(Double cost) {this.cost = cost;}public String makeTea() {System.out.println("原味奶茶基础材料");return "pureMilkyTea";}public Double calCost() {System.out.println("原味奶茶基础价格为10元");setCost(10.0);return this.cost;}
}//定义装饰者组件
public abstract class Decorator implements MilkyTea{public MilkyTea milkyTea;public Decorator(MilkyTea milkyTea) {this.milkyTea = milkyTea;}abstract void addMilk();abstract void addMongo();abstract void addPearl();}//定义具体装饰类:芒果椰奶奶茶装饰类(MongoCocoTea)和黑糖珍珠奶茶装饰类(PearlyTea)
public class MongoCocoTea extends Decorator {public MongoCocoTea(MilkyTea milkyTea) {super(milkyTea);}@Overridevoid addMilk() {System.out.println("添加椰奶。。。");}@Overridevoid addMongo() {System.out.println("添加芒果。。。");}@Overridevoid addPearl() {System.out.println("添加珍珠。。。");}@Overridepublic String makeTea() {System.out.println("制作芒果椰奶奶茶。。。");milkyTea.makeTea();addMilk();addMongo();System.out.println("芒果椰奶奶茶制作完成");return "MongoCocoTea";}@Overridepublic Double calCost() {//原味奶茶价格Double price = milkyTea.calCost();//加椰奶价格price += 10;//加芒果价格price += 5;return price;}
}public class PearlyTea extends Decorator {public PearlyTea(MilkyTea milkyTea) {super(milkyTea);}@Overridevoid addMilk() {System.out.println("添加牛奶。。。");}@Overridevoid addMongo() {System.out.println("添加芒果。。。");}@Overridevoid addPearl() {System.out.println("添加黑糖珍珠。。。");}@Overridepublic String makeTea() {System.out.println("制作黑糖珍珠奶奶茶。。。");milkyTea.makeTea();addMilk();addPearl();System.out.println("黑糖珍珠奶茶制作完成");return "PearlyTea";}@Overridepublic Double calCost() {//原味奶茶价格Double price = milkyTea.calCost();//加牛奶价格price += 5;//加黑糖珍珠价格price += 8;return price;}
}//测试代码如下
public class Test {public static void main(String[] args) {PureMilkyTea pureMilkyTea = new PureMilkyTea();PearlyTea pearlyTea = new PearlyTea(pureMilkyTea);pearlyTea.makeTea();System.out.println("黑糖珍珠奶茶价格为" + pearlyTea.calCost());System.out.println("-------------------------------");MongoCocoTea mongoCocoTea = new MongoCocoTea(pureMilkyTea);mongoCocoTea.makeTea();System.out.println("芒果耶耶奶茶价格为:" + mongoCocoTea.calCost());}
}

运行结果如下:

2.3 装饰者模式在jdk源码中的应用

在JAVA的IO类中,体现了装饰者模式的应用,具体类图如下:

public abstract class InputStream implements Closeable{}是一个抽象组件(Component);
public class FilterInputStream extends InputStream {}是一个装饰者类;
protected volatile InputStream in;这是具体的被装饰对象
public class DataInputStream extends FilterInputStream implements DataInput {} 是FilterInputStream的一个子类,也继承了被装饰对象InputStream。

2.4 装饰者优缺点

2.4.1 优点

1.装饰者模式提供了比继承更加符合开闭原则,具有更好的灵活性;因为继承是在静态期间确立关系,而装饰者是在运行时动态添加对象的功能;
2.解耦,通过增加子类方式来修改对象创建行为,这种通过增加而不是修改类的方式,是面向对象设计所推崇的。

2.4.2 缺点

1.会在系统中产生较多的类,造成系统臃肿;
2.使用难度较高,对设计人员抽象能力要求较高。

3.小结

1.装饰者模式一种结构性模式,它的作用是避免使用继承的方式来扩展对象的功能,而是通过动态添加的方式来增加功能;
2.装饰模式在使用时,需要根据场景进行抽象,选出关键的Component、ConcreteComponent、Decorator、ConcreteDecorator。

4.参考文献

1.《设计模式-可复用面向对象软件的基础》-Erich Gamma、Richard Helm、Ralph Johnson、John Vlissides
2.《可复用物联网Web3D框架的设计与实现》-程亮(知网)
3.https://www.bilibili.com/video/BV1G4411c7N4-尚硅谷设计模式
4.《大话设计模式》-程杰著

小侃设计模式(八)-装饰者模式相关推荐

  1. php设计模式八-----装饰器模式

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

  2. Java设计模式(装饰者模式-组合模式-外观模式-享元模式)

    Java设计模式Ⅳ 1.装饰者模式 1.1 装饰者模式概述 1.2 代码理解 2.组合模式 2.1 组合模式概述 2.2 代码理解 3.外观模式 3.1 外观模式概述 3.2 代码理解 4.享元模式 ...

  3. 【白话设计模式八】命令模式(Command)

    为什么80%的码农都做不了架构师?>>>    #0 系列目录# 白话设计模式 工厂模式 单例模式 [白话设计模式一]简单工厂模式(Simple Factory) [白话设计模式二] ...

  4. C#设计模式(9)——装饰者模式(Decorator Pattern)

    一.引言 在软件开发中,我们经常想要对一类对象添加不同的功能,例如要给手机添加贴膜,手机挂件,手机外壳等,如果此时利用继承来实现的话,就需要定义无数的类,如StickerPhone(贴膜是手机类).A ...

  5. python中的装饰器、装饰器模式_python 设计模式之装饰器模式 Decorator Pattern

    #写在前面 已经有一个礼拜多没写博客了,因为沉醉在了<妙味>这部小说里,里面讲的是一个厨师苏秒的故事.现实中大部分人不会有她的天分.我喜欢她的性格:总是想着去解决问题,好像从来没有怨天尤人 ...

  6. python 设计模式之装饰器模式 Decorator Pattern

    #写在前面 已经有一个礼拜多没写博客了,因为沉醉在了<妙味>这部小说里,里面讲的是一个厨师苏秒的故事.现实中大部分人不会有她的天分.我喜欢她的性格:总是想着去解决问题,好像从来没有怨天尤人 ...

  7. 设计模式03 - 装饰者模式

    引入: 曾今以为继承能解决一切问题.在程序运行时发现,扩展的威力远大于编译时扩展的威力. 装饰者模式: 好处: 一旦知道装饰的技巧,你将能给你的(或别人的)对象一个新的责任,而不需要对底层class的 ...

  8. 5分钟读懂设计模式(2)---装饰者模式

    每当我们买了新房子之后,相信绝大部分人都会进行装修,给房子增加一些其他新的物品.不过,无论如何装修,这个房子还是这个房子,最本质的东西并没有变,有的只是我们通过装修的方式,给这个房子增加了一些额外的功 ...

  9. javascript设计模式之装饰器模式(结构型模式)

    javascript设计模式之装饰器模式 js的设计模式分为创建型模式,结构型模式和行为模式 结构模式描述了如何组合对象以提供新的功能. 装饰器模式是一种常见的结构型模式,我们可以以一个基础对象为基础 ...

  10. 设计模式之装饰者模式(五)

    设计模式之装饰者模式(五) 前几天把创建型设计模式学习了一下,因为之前了解过,算是复习吧. 接下来进行结构型设计模式,结构型设计模式包括:适配器,桥接,外观,组合,装饰者,享元,代理 今天来学习装饰者 ...

最新文章

  1. 2021年必读的10 个计算机视觉论文总结
  2. python十八:尾调用与递归
  3. 深入浅出 Java 中 JVM 内存管理
  4. 4/100. Maximum Depth of Binary Tree
  5. Web端口复用正向后门研究实现与防御
  6. mysql创建数据库schooldb_mysql创建新用户和数据库
  7. Python实现学生出勤记录
  8. 对WITH和from(select ...)的一点比较
  9. 2的10次方-1的python表达式_第1章 语言处理与Python
  10. linux 路由跟踪命令_云计算网络知识学习-linux网络基础
  11. Typora优化,Typora结合PicGo,让工作更轻松【图文教程】
  12. Linux安全加固手册
  13. 千呼万唤始出来的京东HR面(2023暑期实习)
  14. win7无法自动检测修复计算机,无法启动,启动修复正在检查系统问题
  15. 一文了解上拉电阻和下拉电阻(一)
  16. 现在哪里有卖鸡腿面包的?
  17. SpringBoot事务配置管理
  18. MySQL廖雪峰的官方网站
  19. 数据库那些事--greenDAO增删查改
  20. input输入长度 vue_Vue实现input宽度随文字长度自适应操作

热门文章

  1. 跨境电商B2B是什么?跨境电商B2B模式如何定义?
  2. 日语 假名对应的汉字来源
  3. c语言实现多目标优化,MOPSO 多目标例子群优化算法
  4. 微信小程序开发之——拍照和录像
  5. 2021-2027全球与中国韧带连结植入物市场现状及未来发展趋势
  6. AD19 编译报错:has only one pin 和 floating net label
  7. hanlp自然语言处理包的基本使用--python
  8. 传统相声台词-太平歌词大实话
  9. 操作系统:存储器管理(下)
  10. [渝粤教育] 中国地质大学 人力资源开发与管理 复习题 (2)