文章目录

  • 23种设计模式——装饰者模式
    • 1、装饰者模式概述
    • 2、装饰者模式的结构
    • 3、装饰者模式的实现
    • 4、装饰者模式的应用场景

23种设计模式——装饰者模式

1、装饰者模式概述

背景

有些人为了早上多睡一会,就会用方便的方式解决早餐问题。有些人早餐可能会吃煎饼,煎饼中可以加鸡蛋,也可以加香肠,但是不管怎么“加码”,都还是一个煎饼。在现实生活中,常常需要对现有产品增加新的功能或美化其外观,如房子装修、相片加相框、咖啡加调料等,都是装饰器模式。

装饰者模式的定义

装饰者(Decorator)模式的定义:指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式。

装饰者模式属于对象结构型模式,也体现了开闭原则(ocp)。

装饰者模式的优缺点

优点

  • 装饰器是继承的有力补充,比继承灵活,在不改变原有对象的情况下,动态的给一个对象扩展功能,即插即用
  • 通过使用不用装饰类及这些装饰类的排列组合,可以实现不同效果
  • 装饰器模式完全遵守开闭原则

缺点:装饰器模式会增加许多子类,过度使用会增加程序得复杂性。

2、装饰者模式的结构

装饰者模式的结构

装饰器模式主要包含以下角色。

  1. 抽象构件(Component)角色:定义一个抽象接口以规范准备接收附加责任的对象。
  2. 具体构件(ConcreteComponent)角色:实现抽象构件,通过装饰角色为其添加一些职责。
  3. 抽象装饰(Decorator)角色:继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。
  4. 具体装饰(ConcreteDecorator)角色:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。

装饰者模式的结构图

3、装饰者模式的实现

实现星巴克咖啡+调味品的下单,并计算费用

定义抽象构件(Component)角色:定义一个抽象接口以规范准备接收附加责任的对象。

public abstract class Drink {public String dsc; //描述private float price = 0.0f; //价格public String getDsc() {return dsc;}public void setDsc(String dsc) {this.dsc = dsc;}public float getPrice() {return price;}public void setPrice(float price) {this.price = price;}//计算费用的抽象方法,由子类实现public abstract float cost();}

定义具体构件(ConcreteComponent)角色:实现抽象构件,通过装饰角色为其添加一些职责。

public class Coffee extends Drink{@Overridepublic float cost() {return super.getPrice();}
}

具体构件(ConcreteComponent)角色1:Espresso 意大利咖啡

public class Espresso extends Coffee{public Espresso(){setDsc("意大利咖啡");setPrice(10.0f);}
}

具体构件(ConcreteComponent)角色2:LongBlack 美式咖啡1

public class LongBlack extends Coffee{public LongBlack(){setDsc("美式咖啡1");setPrice(9.0f);}
}

具体构件(ConcreteComponent)角色3:LongBlack 美式咖啡2

public class ShortBlack extends Coffee{public ShortBlack(){setDsc("美式咖啡2");setPrice(8.0f);}
}

定义抽象装饰(Decorator)角色:继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。

public class Decorator extends Drink{//装饰者组合了抽象构件(被装饰者)private Drink obj;public Decorator(Drink obj){this.obj = obj;}@Overridepublic float cost() {//计算费用:父类的费用 + 自己的费用return getPrice() + obj.getPrice();}@Overridepublic String getDsc() {//输出描述:父类的描述 + 自己的描述return dsc + " " + getPrice() + " " +obj.getDsc();}
}

定义具体装饰(ConcreteDecorator)角色:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。

具体装饰(ConcreteDecorator)角色1:巧克力 Chocolate

public class Chocolate extends Decorator{public Chocolate(Drink obj) {super(obj);setDsc("巧克力");setPrice(3.0f);}
}

具体装饰(ConcreteDecorator)角色2:牛奶 Milk

public class Milk extends Decorator{public Milk(Drink obj) {super(obj);setDsc("牛奶");setPrice(2.0f);}
}

具体装饰(ConcreteDecorator)角色3:豆浆 Soy

public class Soy extends Decorator{public Soy(Drink obj) {super(obj);setDsc("豆浆");setPrice(1.5f);}
}

编写测试类下咖啡订单,测试装饰者模式:

public class coffeeBar {public static void main(String[] args) {//一杯美式Drink order1 = new LongBlack();System.out.println("订单描述:" + order1.getDsc());System.out.println("订单费用= " + order1.cost());//一杯美式 + 一份牛奶order1 = new Milk(order1);System.out.println("订单描述:" + order1.getDsc());System.out.println("订单费用= " + order1.cost());//一杯美式 + 2份牛奶order1 = new Milk(order1);System.out.println("订单描述:" + order1.getDsc());System.out.println("订单费用= " + order1.cost());//一杯美式 + 2份牛奶 + 巧克力order1 = new Chocolate(order1);System.out.println("订单描述:" + order1.getDsc());System.out.println("订单费用= " + order1.cost());}
}

4、装饰者模式的应用场景

装饰者模式的应用场景

  • 当需要给一个现有类添加附加职责,而又不能采用生成子类的方法进行扩充时。例如,该类被隐藏或者该类是终极类或者采用继承方式会产生大量的子类。
  • 当需要通过对现有的一组基本功能进行排列组合而产生非常多的功能时,采用继承关系很难实现,而采用装饰器模式却很好实现。
  • 当对象的功能要求可以动态地添加,也可以再动态地撤销时。

装饰器模式在 Java 中的体现

装饰器模式在 Java语言中的最著名的应用莫过于 Java I/O 标准库的设计了。例如,InputStream 的子类 FilterInputStream,OutputStream 的子类 FilterOutputStream,Reader 的子类 BufferedReader 以及 FilterReader,还有 Writer 的子类 BufferedWriter、FilterWriter 以及 PrintWriter 等,它们都是抽象装饰类。

23种设计模式——装饰者模式相关推荐

  1. 实践GoF的23种设计模式:建造者模式

    本文分享自华为云社区<[Go实现]实践GoF的23种设计模式:建造者模式>,作者: 元闰子. 简述 在程序设计中,我们会经常遇到一些复杂的对象,其中有很多成员属性,甚至嵌套着多个复杂的对象 ...

  2. 【Go实现】实践GoF的23种设计模式:命令模式

    上一篇:[Go实现]实践GoF的23种设计模式:代理模式 简单的分布式应用系统(示例代码工程):https://github.com/ruanrunxue/Practice-Design-Patter ...

  3. 23种设计模式7_代理模式之一静态代理

    23种设计模式7_代理模式之一静态代理 1 基本介绍 代理模式:为其他对象提供一种代理以控制对这个对象的访问 代理模式也叫委托模式,它是一项基本设计技巧.许多其他的模式,如状态模式.策略模式.访问者模 ...

  4. 23种设计模式之命令模式和策略模式的区别

    文章目录 概述 命令模式 策略模式 相同点 总结 概述 命令模式和策略模式确实很相似,只是命令模式多了一个接收者(Receiver)角色.它们虽然同为行为类模式,但是两者的区别还是很明显的.策略模式的 ...

  5. 23种设计模式之代理模式

    文章目录 代理模式的定义与特点 代理模式的结构与实现 模式的结构 模式的实现 代理模式的应用场景 代理模式的应用实例 代理模式的扩展 代理模式分类 静态代理 动态代理 在有些情况下,一个客户不能或者不 ...

  6. 23种设计模式----中介者模式----行为型模式

    中介者模式 1.什么是中介者模式 2.中介者模式的角色 3.例子 3.1 项目结构 3.2 共同实体 3.3 抽象的中介者 3.4 抽象的被中介者 3.5 具体的中介者 3.6 具体的被中介者 3.7 ...

  7. 2.5万字详解23种设计模式—创建型模式(简单工厂、工厂方法、抽象工厂、单例-多线程安全详解、建造者、原型)的详细解读、UML类图

    本文简述了各大设计模式,并通过UML和代码详细说明.本文大约共 2.5W 字,建议收藏.下方是本文的目录: 一.设计模式的认识 二.设计模式的分类 根据其目的 根据范围 三.设计模式的优点 四.设计模 ...

  8. 23种设计模式-行为型模式-访问者模式

    在患者就医时,医生会根据病情开具处方单,很多医院都会存在以下这个流程:划价人员拿到处方单之后根据药品名称和数量计算总价,而药房工作人员根据药品名称和数量准备药品,如下图所示. 在软件开发中,有时候也需 ...

  9. 23种设计模式-行为型模式-观察者模式

    概述 它用于建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应作出反应.在观察者模式中,发生改变的对象称为观察目标,而被通知的对象称为观察者,一个观察目标可以对应多 ...

最新文章

  1. CTFshow 命令执行 web35
  2. C++ Primer 5th笔记(chap 14 重载运算和类型转换)递增和递减运算符
  3. 如何将SP1集成到Office 2007安装包
  4. 区块链软件公司:区块链使用程序如何成为战胜商场应战的垫脚石
  5. JavaScript高级程序设计阅读笔记
  6. jlink怎么调试linux程序_纯Linux下的 ARM裸机调试环境搭建(GDB + JLink)
  7. 小学奥数 7654 等差数列末项计算 python
  8. 腾讯首投AI芯片,领投燧原科技Pre-A轮3.4亿元融资
  9. AttributeError: 'NoneType' object has no attribute 'append'
  10. H3C题库HCNE的 最新
  11. 【python与数据分析】Python与数据分析概述
  12. php wx.downloadimage,大神,wx.downloadImage 图片过期问题
  13. java学习(类和对象)
  14. 留学目的地选择之亚利桑那州
  15. 耳机断线了怎么修 耳机头部断线了如何修4线修复的方法
  16. 程序员如何从技术岗转为技术管理层?
  17. [整站源码]thinkphp美肤微形美容仪器网站模板+前后端源码
  18. VBA关于数组Dim,ReDim Preserve运行速度对比思考
  19. HashSet子类依靠()方法区分重复元素
  20. 05.视频播放器内核切换封装

热门文章

  1. Python数字拆分
  2. Ubuntu系统镜像盘ISO:各版本大全、国内网速下载地址(阿里云)
  3. 从零搭建WebApi接口开发框架-接口规范
  4. 对于offsetWidth,offsetHeight,offsetLeft,offsetTop的理解
  5. java 的 MD5 算法介绍 总结 使用
  6. 使用浏览器传感器工具测试手机陀螺仪效果
  7. python 频数表_python里计算每个数字出现的频数
  8. 惠普笔记本重装系统后没有声音如何解决
  9. form的onsubmit验证
  10. 「自控原理」5.1 频率特性及其图示