设计模式之——装饰者模式

前言:

装饰者模式是结构性设计模式之一,其在不必改变类文件及不适用继承的情况下,动态的扩展一个对象的功能。它通过创建一个包装对象(即装饰)来包裹真实的对象。

一.定义

动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更加灵活。

装饰者模式的结构图:

装饰者模式有如下角色:

  • Component:可以是接口或者是抽象类,被装饰的最原始的对象。
  • ConcreteComponent:组件具体实现类。Component的具体实现,被装饰的具体对象(即包含原有功能的对象)。
  • Decorator:抽象装饰者,新增装饰类,用来扩展原有Component类的功能,对于Component来说无须知道Decorator的存在,所以在他的属性中必然有一个private变量指向Component抽象组件。
  • ConcreteDecorator:装饰者的具体实现类。

二.具体实现

装饰者模式在生活中有很多例子,我们这里来给一个普通的人【原来只会走路】学运动技能【新学会了游泳 + 拳击】后变大师的例子来说明。

(1)抽象组件

我们先定义一个人的抽象类,里面有运动的抽象方法。

public abstract class Person {/*** Person 人有可以运动的抽象方法*/public abstract void sport();
}

(2)组件具体实现类

被装饰的具体对象,这里是具体的一个普通人,作为一个普通人他当然会运动,当然在未被装饰的情况下他只会走路。

public class CommonPerson extends Person {@Overridepublic void sport() {System.out.println("普通人运动只会走路");}
}

(3)抽象装饰者:
抽象装饰者保证了一个对抽象组件的引用,方便调用被装饰对象中的方法。在这里运动大师需要持有人(Person)的引用,方便教授他其他运动,最终成为运动健将。

public abstract class Master extends Person {private Person mPerson;public Master(Person person) {mPerson = person;}@Overridepublic void sport() {mPerson.sport();}
}

(4)装饰者具体实现类:
这里有两个装饰者具体实现类,分别是宁泽涛跟邹市明,他们(装饰者)负责向普通人(被装饰者)教授游泳跟拳击。

public class Ningzetao extends Master {public Ningzetao(Person person){super(person)}@Overridepublic void sport() {super.sport();teachSwimming();}public void teachSwimming(){System.out.println("宁泽涛教普通人游泳");}
}public class Zoushiming extends Master {public Zoushiming(Person person){super(person)}@Overridepublic void sport() {super.sport();teachBoxing();}public void teachBoxing(){System.out.println("邹市明教普通人拳击");}
}

(5)客户端调用:
经过宁泽涛跟邹市明的教导后,普通人经过装饰后,除了会走路之外,也学会了游泳跟拳击。

public class Client {public static void main (String[] args) {//创建普通人,只会走路CommonPerson mCommonPerson = new CommonPerson();//宁泽涛教普通人学游泳,普通人学会了游泳Ningzetao mNingzetao = new Ningzetao(mCommonPerson);mNingzetao.sport();//邹市明教普通人学拳击,普通人学会了拳击Zoushiming mZoushiming = new Zoushiming(mCommonPerson);mZoushiming.sport();}
}

三.使用场景

  • 在不影响其他对象的情况下,以动态,透明的方式给单个对象添加职责。
  • 需要动态的给一个对象添加功能,这些功能可以动态的撤销。
  • 当不能采用继承的方式对系统进行扩充或者采用继承不利于系统扩展和维护。

四.优缺点

优点:

  • 通过组合而非继承的方式,动态的扩展一个对象的功能,在运行时可以选择不同的装饰器从而实现不同的功能。
  • 有效的避免了使用继承的方式扩展对象功能而带来的灵活差,子类无限制扩张的问题。
  • 具体组件类与具体装饰类可以独立变化,用户可以根据需要新增具体组件类跟装饰类,在使用时在对其进行组合,原有代码无需改变,符合“开闭原则”。

缺点:

  • 因为所有对象均继承于Component,所以如果Component内部结构发生改变,则不可避免的影响到所有子类(装饰者于被装饰者)。如果基类改变,则势必影响对象的内部。
  • 装饰者比继承更容易出错,排错也比较困难。对于多次装饰的对象,调试时寻找错误可能需要逐级排查,较为繁琐。所以一般只在必要的时候使用装饰者模式。
  • 装饰层数不能过多,否则会影响效率。

注意:

乍一看装饰者模式跟代理模式很像,其实不然,两者最大的区别是:

装饰者模式应该为所装饰的对象增强功能。

而代理模式对代理的对象施加控制,并不提供对象本身的增强功能。

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

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

相关文章

解决vsc中文乱码

关于vs code使用code runner运行python代码出现中文乱码的解决办法_code runner 运行乱码-CSDN博客 Code Runner插件设置 "set PYTHONIOENCODING=utf8 && python -u"

CSP-S 2024 提高组初赛第一轮初赛试题及答案解析

CSP-S 2024 提高组初赛第一轮初赛试题及答案解析 一、 单项选择题(共15题,每题2分,共计30分:每题有且仅有一个正确选项) 1 在 Linux 系统中,如果你想显示当前工作目录的路径,应该使用哪个命令?( ) A pwd B cd C ls D echo 答案 A 解析 A pwd:这个命令是“prin…

结对项目:四则运算题目生成

这个作业属于哪个课程 22级计科1班这个作业要求在哪里 作业要求这个作业的目标 自动生成小学四则运算题目github项目链接 链接姓名&学号姓名 学号万凯毅 3122004788周彦安 3122004804PSPPSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)Plannin…

帝国CMS搬家后无法发文章或者上传图片无法显示?

如果你在搬家后遇到无法发文章或上传图片的问题,通常是因为权限设置不当导致的。以下是一些详细的步骤来解决这些问题: 1. 检查目录权限 无法发文章检查栏目目录及子文件夹权限确保栏目目录及其子文件夹具有适当的权限。 通常需要将这些目录设置为 777 权限。shchmod -R 777 …

WordPress数据库连接失败是最常见的错误情况

WordPress数据库连接失败常见原因及解决方法 官方提示的三种情况数据库名、用户名或密码错误解决方法:检查并确认数据库名称、用户名和密码是否正确无误。数据库主机地址错误解决方法:通常填写localhost即可;如果是远程数据库,请根据主机提供商提供的地址进行填写。数据库未…

打靶记录 SickOS 1.1

https://www.vulnhub.com/entry/sickos-11,132/主机发现端口扫描探测存活主机,136是靶机,因为靶机是我最后添加的 nmap -sP 192.168.75.0/24 // Starting Nmap 7.93 ( https://nmap.org ) at 2024-09-22 11:36 CST Nmap scan report for 192.168.75.1 Host is up (0.00038s l…

简单部署Memos

从0到1借助宝塔面板快速部署Memos前言:此处以阿里云为例,利用宝塔面板部署 此文章是部署之后写的,因此有些截图是后补充的,缺少一些执行结果展示和详细步骤的缺失,请根据实际情况做调整准备购买阿里云服务器 ECS着手 创建实例进入阿里云控制台,我的资源→云服务器 ECS; …

发展低空经济,对地理信息技术提出了哪些要求

随着低空经济的快速发展,地理信息技术在其中扮演着越来越重要的角色。低空经济涉及无人机、电动垂直起降(eVTOL)飞行器等航空器的低空飞行活动,其对地理信息技术提出了新的要求和挑战。 1. 高精度定位与导航低空经济中的无人机和eVTOL等航空器需要精确的定位和导航服务。地…

05-信息扫描漏洞探测的工具使用

1、安装并使用Nmap扫描一个地址(本机、VPS、虚拟机环境都可以),提供扫描结果截图在https://nmap.org/ nmap官网下载对应的操作系统版本文件。安装完成后对本机10.0.0.151进行 -A(探测操作系统及版本),-T4(加速扫描),-sS(半连接扫描)。2、安装并使用Xray被动扫描,提供过程…

帝国网站管理系统忘记后台账号和密码怎么办?

如果你忘记了帝国网站管理系统的后台账号和密码,可以通过以下几个步骤来尝试恢复或重置: 情况一:只知道密码忘记了使用数据库管理工具登录phpMyAdmin或其他数据库管理工具。 选择帝国CMS所使用的数据库。 找到用户表,通常为phome_enewsuser,但请注意实际表名可能会根据安装…

帝国CMS提示“Notice: Use of undefined constant”错误说明: php.ini配置问题

当你在 PHP 应用中遇到 “Notice: Use of undefined constant” 的错误提示时,这通常是因为代码中引用了一个未定义的常量。这种错误通常不会导致程序崩溃,但会影响代码的可读性和稳定性。 错误原因未定义的常量代码中引用了一个未定义的常量。错误报告级别当前的错误报告级别…

帝国CMS忘记后台管理员帐号怎么办?使用MySQL数据库管理软件phpmyadmin

如果你忘记了帝国CMS后台管理员的账号,可以通过直接查询数据库的方式来找回或重置账号。以下是具体的步骤: 步骤一:登录phpMyAdmin访问phpMyAdmin打开浏览器,访问phpMyAdmin的URL,通常是: http://yourdomain.com/phpmyadmin其中yourdomain.com需要替换成你的实际域名或者…