【设计模式-9】装饰模式的代码实现及使用场景

 装饰器模式类比生活中房屋装修的场景,可以在毛坯房的基础上加以各种装饰,使得房屋的居住属性增强。装饰器模式能够在运行期间,动态地为原始对象增加一些额外的功能,使其功能更为丰富。

1. 概述

装饰模式 可以动态的为某些对象增加一些额外的职责,在某些程度上,装饰器模式类似于继承,但是比继承更加灵活,可以在不改变一个对象本身功能的基础上额外增加新行为。装饰模式是一种对象结构性的模式。

 在定义中,我们提到了继承,通过继承的方式,子类可以在父类的功能上做增加,但这是在编译期间,需要修改子类来完成的。装饰模式可以在运行期间动态的包装原始对象,实现“装饰”的效果。

 装饰模式的实现需要以下4个角色。

  • 组件接口:组件接口是所有被装饰的类和装饰器抽象类共同要实现的接口标准,接口中会定义装饰的行为方法。
  • 组件实现:这里是指被装饰的组件,只需实现组件接口,并且在接口行为方法中实现未被装饰的原始特性就可以。
  • 装饰器:是装饰器的高层抽象类,同样实现了组件接口,同时会声明一个组件接口类型的被装饰对象,一般是抽象类。
  • 装饰器实现:是装饰器抽象类的子类,可以有多种实现,在被装饰对象的基础上添加新的特性,真正实现功能增强的装饰器组件。

2. 代码实现

 在下面的代码案例中,我们假设装修公司提供给客户两种装修方案,分别是中式装修和欧式装修,对于装饰器模式需要的4个角色,我们实现如下:

  • 组件接口
// 组件接口
public interface Component {// 表示装饰的行为接口方法void fitment();
}
  • 组件实现
// 毛坯房屋 - 被装饰的对象
public class RoughHouse implements Component {// 组件接口的实现方法@Overridepublic void fitment() {System.out.print("【原始的毛坯房屋】");}
}
  • 装饰器
// 抽象的装饰器
public abstract class AbstractDecorator implements Component {// 声明的被装饰的对象属性protected Component component;// 构造方法中注入被装饰对象的属性public AbstractDecorator(Component component) {this.component = component;}// 装修的方法@Overridepublic void fitment() {component.fitment();}
}
  • 装饰器实现
// 具体的装饰实现类 - 中式装修风格
public class ChineseStyle extends AbstractDecorator {// 构造方法的注入public ChineseStyle(Component component) {super(component);}// 功能增强的方法@Overridepublic void fitment() {System.out.print("【中式装修的吊顶");super.fitment();System.out.print("】");}
}// 具体的装饰实现类 - 欧式装修风格
public class EuropeanStyle extends AbstractDecorator {// 构造器 - 装饰对象的注入public EuropeanStyle(Component component) {super(component);}// 具体的装修风格@Overridepublic void fitment() {System.out.print("【欧式装修的家电家具");super.fitment();System.out.print("】");}
}
  • 客户端
// 客户端
public class Client {public static void main(String[] args) {// 只是中式装修Component chineseStyle = new ChineseStyle(new RoughHouse());chineseStyle.fitment();System.out.println("");// 只是欧式装修Component europeanStyle = new EuropeanStyle(new RoughHouse());europeanStyle.fitment();System.out.println("");// 中式装修+欧式装修Component component = new EuropeanStyle(new ChineseStyle(new RoughHouse()));component.fitment();System.out.println("");}
}

3. UML类图

 根据上述房屋装修的代码示例,我们来画一下UML类图,如下所示:
在这里插入图片描述

4. 使用场景

 装饰器模式在某些场景下,如果只有一个具体的被装饰对象,那么抽象的装饰类可以直接作为该具体构件类的子类。

在这里插入图片描述

 在Java类库中,最典型的装饰器模式使用就是Java IO中的输入流和输出流的设计,总体来说,装饰器模式的使用场景还是比较多的。

5. 总结

 最后,我们来总结一下装饰模式的优点:

  1. 相对于继承,装饰器模式更灵活,也不会导致类的数量急剧增加;
  2. 通过装饰实现类的自由组合,可以扩展对象的不同的能力,从而实现不同的行为;
  3. 不同的被装饰类和装饰器实现类,都可以在不改变原有类结构的基础上,直接增加新的类型,符合开闭原则。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/639919.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深入Matplotlib:画布分区与高级图形展示【第33篇—python:Matplotlib】

文章目录 Matplotlib画布分区技术详解引言方法一:plt.subplot()方法二:简略写法方法三:plt.subplots()实例展示添加更多元素 进一步探索Matplotlib画布分区自定义子图布局3D子图结语 Matplotlib画布分区技术详解 引言 Matplotlib是一个强大…

代码随想录27期|Python|Day35|435. 无重叠区间|763.划分字母区间|56. 合并区间

435. 无重叠区间 和昨天的射爆气球是一样的处理方式: 由于不需要进行不重合的时候的计算,只需要对重合进行处理,所以反而更加简单。 1、按照区间左边界从小到大排序; 2、从索引1开始遍历,对于i-1的右边界大于i的左边…

网页无法访问但是有网什么原因

目录 1.运行网络诊断,确认原因 原因A.远程计算机或设备将不接受连接(该设备或资源(Web 代理)未设置为接受端口“7890”上的连接 原因B.DNS服务器未响应 场景A.其他的浏览器可以打开网页,自带的Edge却不行 方法A:关闭代理 Google自带翻译…

用户头像上传

将用户上传的头像存储在腾讯云存储桶里 注册腾讯云 https://cloud.tencent.com/login 创建存储桶 配置跨域 来源 * (任何都可以访问) put get post 请求都可以 点击概览,查看存储桶基本信息 记录保存存储桶名称和地域 找到api密钥管理,新建密钥 ht…

Git学习笔记(第7章):IDEA实现Git操作(VSCode)

目录 7.1 配置忽略文件 7.2 初始化本地库 7.3 添加暂存区、提交本地库 7.4 修改文件 补充:工具栏简介 7.1 配置忽略文件 问题引入 在版本控制系统中,有些文件或目录是不需要纳入版本管理的,比如编译产生的临时文件、日志文件、缓存文件等…

项目篇:基于UDP通信模型的网络聊天室

思维导图 基于UDP通信模型的网络聊天室 消息分类及数据包结构 服务器端 #include <head.h> #define SER_PORT 8888 #define SER_IP "192.168.232.133" typedef struct mb {struct sockaddr_in cin;char name[20];struct mb *next; }*member; //群发消息 int …

【window】Windows11:该文件没有与之关联的应用来执行该操作

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff1a;人工智能 之前win10升级win11后&#xff0c;受不了桌面软件图标的的小箭头&#xff0c;所以弄掉了&#xff0c;但是随之而来产…

9个好习惯教会你设计商业模式的电商干货,真心分享丨运营逻辑

9个好习惯教会你设计商业模式的电商干货&#xff0c;真心分享丨运营逻辑 文丨微三云营销总监胡佳东&#xff0c;点击上方“关注”&#xff0c;为你分享市场商业模式电商干货。 - 最近&#xff0c;有很多新认识的朋友&#xff0c;都在询问我最近市场上&#xff0c;有什么好的…

定类变量的频率分析(SPSS

目录 1.导入数据&#xff1a;2.频率分析&#xff1a;3.结果分析4.表格导出为excel小结&#xff1a; 1.导入数据&#xff1a; 直接把表格拖入spss 然后点确定 下面会有变量视图&#xff0c;查看各个指标的类型和属性&#xff1a; 2.频率分析&#xff1a; 点击频率分析 选择…

json-server的基础使用

本篇文章与另一篇文章有关系axios的基本使用&#xff0c;大家可以看看这篇文章 json-server 是什么? 用来快速搭建模拟的 REST API 的工具包 可以30秒内快速为我们搭建一个假的基于 REST API的服务 我们要如何使用呢&#xff1f; 1.先安装 //全局安装 npm i -g json-server …

伪原创文章生成器软件免费使用的方法

写文章不仅消耗时间&#xff0c;而且还容易出现写不出内容的问题&#xff0c;随着技术的发展&#xff0c;越来越多的人开始不再亲历亲为的去写文章了&#xff0c;而是用起了伪原创文章生成器软件&#xff0c;对于还不了解自动生成文章软件的人&#xff0c;可不要小瞧这个它了&a…

JOSEF约瑟 零序电流继电器 JL-8D/2X122A4(S) 0-30AAC 220VDC

系列型号 JL-8D/3X1定时限电流继电器&#xff1b;JL-8D/3X111A2定时限电流继电器&#xff1b; JL-8D/3X121A2定时限电流继电器&#xff1b;JL-8D/3X211A2定时限电流继电器&#xff1b; JL-8D/3X221A2定时限电流继电器&#xff1b;JL-8D/3X2定时限电流继电器&#xff1b; JL-8D/…

[小程序]Http网络请求

一、数据请求限制 出于安全性(bushi)考虑&#xff0c;小程序请求的数据接口必须具备以下两个条件&#xff1a; ①只能请求Https类型 ②必须将接口域名添加到信任列表中 1.配置request合法域名 配置步骤如下&#xff1a;小程序管理后台->开发->开发设置->服务器域名-&g…

幻兽帕鲁专用服务器

随着幻兽帕鲁这款游戏的热度持续升温&#xff0c;我们遍寻全网&#xff0c;带给各位玩家一个全新的、高品质的游戏体验——莱卡云服务器。有幻兽帕鲁的热衷者们无需再为了服务器的选取困扰&#xff0c;因为我们可以肯定地说&#xff1a;选择莱卡云&#xff0c;你不会失望。 首先…

java SSM政府采购管理系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java SSM政府采购管理系统是一套完善的web设计系统&#xff08;系统采用SSM框架进行设计开发&#xff0c;springspringMVCmybatis&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代 码和数据库&#xff0c;系统主要采…

飞书+ChatGPT+cpolar搭建企业智能AI助手并实现无公网ip远程访问

文章目录 推荐 前言环境列表1.飞书设置2.克隆feishu-chatgpt项目3.配置config.yaml文件4.运行feishu-chatgpt项目5.安装cpolar内网穿透6.固定公网地址7.机器人权限配置8.创建版本9.创建测试企业10. 机器人测试 推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂…

C语言第五弹---分支语句(上)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 分支语句 1、if语句1.1、if1.2、 else1.3、 分支中包含多条语句1.4、嵌套if1.5、 悬空else问题 2、关系操作符3、 条件操作符总结 C语言是结构化的程序设计语言&…

第04章_IDEA的安装与使用(下)(IDEA断点调试,IDEA常用插件)

文章目录 第04章_IDEA的安装与使用&#xff08;下&#xff09;8. 快捷键的使用8.1 常用快捷键8.2 查看快捷键1、已知快捷键操作名&#xff0c;未知快捷键2、已知快捷键&#xff0c;不知道对应的操作名 8.3 自定义快捷键8.4 使用其它平台快捷键 9. IDEA断点调试(Debug)9.1 为什么…

一零七七、将Hexo cl Hexo g Hexo s通过systemctl命令管理

背景&#xff1a; 服务器需要执行hexo s来运行项目&#xff0c;但这个命令是基于前台的&#xff0c;故想直接嫁接在systemctl命令基础上来控制环境&#xff1a; Centos 8 前置环境就不说了,Hexo安装好&#xff0c;起码装完自己得先看hexo命令生效没&#xff0c;前置环境做好后…

Leetcode刷题笔记题解(C++):LCR 102. 目标和

思路&#xff1a;利用回溯去遍历&#xff0c;回溯结束条件为遍历到最后一个数字&#xff0c;如果符合target则目标数1 class Solution { public://记录合为结果的数量int count 0;int findTargetSumWays(vector<int>& nums, int target) {//利用回溯来寻找backtrac…