常用设计模式系列(十)—装饰者模式

第一节

前言

各位好,首先我要先恭喜下自己粉丝即将破百,也谢谢各位的捧场,不过也跟我自己的努力密不可分,我也要继续加油,输出更好的文章来回报大家,也希望大家多提建议,有问题我也会及时改进。争取早日跟上各位大佬的步伐。

今天讲解的是创建型设计模式第三篇—装饰者模式(也叫修饰者模式),同样我们通过模式的名字去看实现过程,所谓装饰,就是在本体原有功能的基础上加上修饰,但不能更改原有本体的结构,使得原本的类在原有的结构不变动的基础上增加更多的功能,来拥有更多的功能,这个不修改本体去完成扩展的方式,就叫装饰者模式。

第二节

装饰者模式

装饰者(Decorator)模式的定义:指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式。大多情况下,扩展一个类的功能许多人会选择继承的方式。但是继承的耦合度比较高,随着需要扩展功能的增加,子类会变得越来越复杂和臃肿,装饰者模式使用组合关系来创建一个包装对象来包含真实对象(原有对象),并且在原有对象的结构体不变的前提下,增加额外的功能,这个就是装饰者的实现过程。

装饰者模式组成

1

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

2

具体构件(ConcreteComponent)角色:实现抽象构件,通过装饰角色为其添加一些职责,即需要装饰的原有对象本体。

3

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

4

具体装饰(ConcreteDecorator)角色:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任,具体的装饰者,扩展的功能其实还是具体装饰者做的。

场景举例

我们小区楼下有一个卖鸡蛋灌饼的大妈,他们家每天的生意都很好,需要吃个灌饼都需要排队,一个基础版的灌饼就是灌饼+榨菜+生菜,在灌饼原有基础上老板也推出了套餐A和套餐B和豪华版套餐,A套餐可以加一种食物、B套餐可以加两种食物,豪华版就是三种食物,食物分别是辣条、煎蛋、烤肠,我和我的朋友对食物的喜欢程度不同,我喜欢加烤肠,我的朋友家底比较厚,他喜欢豪华版套餐,但是仔细想想,其实我们吃的都还是个灌饼,但是老板在原有灌饼的基础上进行修饰,抽象出了三个修饰的灌饼套餐版本,具体的套餐内容由每个顾客决定,这个不修改本体但又给本体扩展的过程,使用的就是修饰者模式。

UML图

第三节

代码实现

1.创建抽象构建“灌饼”类

package com.yang.decorator;/** * @ClassName AbstractComponent * @Description 抽象构建角色灌饼 * @Author IT小白架构师之路 * @Date 2020/12/20 20:44 * @Version 1.0 **/publicinterfaceAbstractPancake{/**     * 灌饼可以吃     */publicvoideat();}

2.创建具体构件角色“鸡蛋灌饼类”

package com.yang.decorator;/** * @ClassName EggPancake * @Description 具体构件角色-鸡蛋灌饼 * @Author IT小白架构师之路 * @Date 2020/12/20 20:48 * @Version 1.0 **/publicclassEggPancakeimplementsAbstractPancake{@Overridepublicvoideat(){        System.out.println("鸡蛋灌饼本来有生菜、榨菜");    }}

3.创建装饰抽象角色类

package com.yang.decorator;/** * @ClassName DecoratorPancake * @Description 装饰抽象角色 装饰的鸡蛋灌饼的抽象 * @Author IT小白架构师之路 * @Date 2020/12/20 20:50 * @Version 1.0 **/publicclassDecoratorPancakeimplementsAbstractPancake{//成员对象引入具体构件角色,就是要修饰的对象private AbstractPancake abstractPancake;//构造赋值具体构件publicDecoratorPancake(AbstractPancake abstractPancake){this.abstractPancake = abstractPancake;    }@Overridepublicvoideat(){        abstractPancake.eat();    }}

4.创建具体装饰角色A和B“灌饼套餐A和B”

package com.yang.decorator;/** * @ClassName ConcreteDecoratorPakageOne * @Description 具体装饰者A套餐 * @Author IT小白架构师之路 * @Date 2020/12/20 20:53 * @Version 1.0 **/publicclassConcreteDecoratorAextendsDecoratorPancake{publicConcreteDecoratorA(AbstractPancake abstractPancake){super(abstractPancake);    }@Overridepublicvoideat(){        addOne();super.eat();    }/**     * 加一种吃的     */publicvoidaddOne(){        System.out.println("给鸡蛋灌饼增加了烤肠");    }}package com.yang.decorator;/** * @ClassName ConcreteDecoratorB * @Description 具体装饰者B套餐 * @Author IT小白架构师之路 * @Date 2020/12/20 20:57 * @Version 1.0 **/publicclassConcreteDecoratorBextendsDecoratorPancake{publicConcreteDecoratorB(AbstractPancake abstractPancake){super(abstractPancake);    }@Overridepublicvoideat(){        addTwo();super.eat();    }publicvoidaddTwo(){        System.out.println("灌饼增加了烤肠、辣条");    }}

5.创建客户端进行测试

package com.yang.decorator;/** * @ClassName Client * @Description 客户端 * @Author IT小白架构师之路 * @Date 2020/12/20 20:59 * @Version 1.0 **/publicclassClient{publicstaticvoidmain(String[] args){//生成具体构件        AbstractPancake abstractPancake = new EggPancake();//生成具体扩展构件A套餐        DecoratorPancake decoratorPancake = new ConcreteDecoratorA(abstractPancake);//调用原有的基础方法        decoratorPancake.eat();        System.out.println("-------------我是分割线------------------");//生成具体扩展构件B套餐        decoratorPancake = new ConcreteDecoratorB(abstractPancake);        decoratorPancake.eat();    }}

6.程序运行结果如下,在原有的类结构保持不变的情况下完成装饰,增加更多的功能

给鸡蛋灌饼增加了烤肠鸡蛋灌饼本来有生菜、榨菜-------------我是分割线------------------灌饼增加了烤肠、辣条鸡蛋灌饼本来有生菜、榨菜

第四节

装饰者模式的优缺点及适用场景

优点:

1.在原有对象结构不变的情况下完成功能扩展,比较灵活。

2.装饰类可以增加多个,使用不同的装饰类可以完成不同的功能扩展。

3.具体构件类与具体装饰类可以独立变化,可以根据需要增加新的具体构件和具体装饰类,原类库不需要改变。

缺点:

1.使用装饰者模式,当需要的装饰场景较多时,会产生大量的具体装饰类,会增加系统资源占用,可能会影响程序性能。

2.使用装饰模式虽然比继承更灵活,但是当对象被多次修饰时,当程序运行过程中出现问题,排错过程会变得更加复杂。

适用场景:

1.需要在不影响原有对象的情况下,动态、透明的给原有对象扩展功能内容场景时。

2.不能采用继承的方式对原有对象进行扩展时,可以使用装饰模式。

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

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

相关文章

摆摊计划1(万一以后找不到工作)

货源:阿里巴巴正规平台 卖炸串 硬件: 多功能烤肠机 购买链接:脆皮烤肠机燃煤气商用油炸锅商用摆摊热狗机肠机关东煮组合机批发 (1688.com) 成本:379.6元 食材: 淀粉肠(100支试水)&#xff…

TCP/IP协议

✏️作者:银河罐头 📋系列专栏:JavaEE 🌲“种一棵树最好的时间是十年前,其次是现在” 目录 TCP/IP协议应用层协议自定义应用层协议DNS 传输层协议端口号UDP协议UDP协议端格式 TCP协议TCP协议段格式TCP工作机制确认应答…

基于HTML+CSS+JavaScript制作美食文化网站 ——卡通创意的烧烤(5个页面) html静态网页设计制作 dw静态网页成品模板素材网页 web前端网页设计与制作 div静态网页设计

👨‍🎓静态网站的编写主要是用HTML DIVCSS JS等来完成页面的排版设计👩‍🎓,常用的网页设计软件有Dreamweaver、EditPlus、HBuilderX、VScode 、Webstorm、Animate等等,用的最多的还是DW,当然不同软件写出的…

c语言-喝饮料问题

/* 喝饮料问题&#xff1a; 1瓶饮料1元&#xff0c;2个空瓶可以换一瓶饮料&#xff0c;给20元&#xff0c;可以喝多少饮料 */#define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h>int main() {int man 0, kong 0, sum 0;man 20; //一开始可以买的饮料数sum 0; /…

如何完美吃下二叉树?——二叉树练习题

文章目录 开胃前菜 基础概念选择题主菜 二叉树oj题1.单值二叉树题目思路1代码思路2代码递归展开图 2. 检查两颗树是否相同题目代码 3. 对称二叉树题目思路代码 4. 二叉树的前序遍历题目代码 5. 另一颗树的子树思路代码 6.二叉树遍历题目代码 7.二叉树的层序遍历准备环节代码实现…

动物园游记

这是学习笔记的第 1887 篇文章 今天本来打算去科技馆&#xff0c;结果发现就今天闭馆&#xff0c;真是不巧&#xff0c;于是改换了方向去了北京动物园。 早两年说动物园&#xff0c;基本都和服装批发能联系起来&#xff0c;我是纯粹的去看动物的。确切的说是陪孩子去看动物的。…

【Java核心技术卷】I/O详析

文章目录 概述Java io基本概念关于流流的分类 Java io框架一、以字节为单位的输出流的框架图&#xff08;1&#xff09;框架图图示&#xff08;2&#xff09;OutputStream详解&#xff08;3&#xff09;OutputStream子类&#xff08;4&#xff09;引申&#xff1a;打印流 二、以…

深圳-上海-呼伦贝尔-漠河-哈尔滨环行手记

C语言的精髓是指针&#xff0c;这是手艺人的小幸运&#xff0c;但这是程序员的悲哀。 今年&#xff08;2018年春节前&#xff09;的假期比较特殊&#xff0c;我这一出去就是20多天&#xff0c;请了十来天的年假…1月27号就出发离开深圳了&#xff0c;考虑到1月25号和1月26号两天…

魔幻的2020,对我来说却是逐渐觉醒的一年

2020年的最后一天&#xff0c;按照惯例总结一下成果&#xff0c;同时也制定一下来年的目标&#xff0c;每年不总得给自己立几个flag。 关于公众号 先说公众号&#xff0c;其实开通了很多年&#xff0c;直到今天&#xff0c;还差一百多粉丝才突破一万&#xff0c;这样的成绩算…

美团 大规模商品知识图谱的构建与应用

作者 | 曹雪智博士 美团 技术专家 来源 | DataFunTalk 在互联网新零售的大背景下&#xff0c;商品知识图谱作为新零售行业数字化的基石&#xff0c;提供了对于商品相关内容的立体化、智能化、常识化的理解&#xff0c;对上层业务的落地起到了至关重要的作用。 相比于美团大脑中…

连投两笔,低温预制烤肠为何成为小红书的“心头爱”?

近年来&#xff0c;随着人们生活水平的不断提高和生活节奏的加快&#xff0c;消费者的食品消费观念已经从最初的满足于温饱发展成为追求高品质的消费&#xff0c;对食品健康、质量和用餐效率等提出新要求&#xff0c;低温预制食品的需求不断提升。 根据 Frost & Sullivan&…

基于JAVA的网上水果生鲜超市商城SSM【数据库设计、论文、源码、开题报告】

叿狆号:“IT软件学习社” 主要使用技术 springspringmvcmybatisjspmysqltomcat 功能介绍 &#xff08;1&#xff09;登录注册功能&#xff1a;用户打开系统&#xff0c;浏览挑选生鲜&#xff0c;在购买生鲜之前&#xff0c;要进行注册登录&#xff0c;保证一人一个账号&…

路边2元一根的烤肠,里面究竟是什么肉?

放学之后&#xff0c;下班之余&#xff0c;大家有没有被路边滩上红彤彤、2元一根的烤肠&#xff08;热狗&#xff09;所吸引&#xff1f;那个扑鼻香味&#xff0c;能让你瞬间流口水有没有&#xff1f; 可是&#xff0c;单纯的你有没有想过&#xff0c;这些看上去就很美味的烤肠…

泰酷辣!有人把 81 个国内大模型汇总在一张图里!

在科技的世界里&#xff0c;一场革命正在悄然进行。这场革命的主角&#xff0c;就是我们今天要讲的“大模型”。这些大模型&#xff0c;就像一群巨人&#xff0c;正在各个领域中挥舞着他们的力量&#xff0c;引领着一场前所未有的技术变革。 在国内&#xff0c;这场大模型的研发…

Python 吞噬世界,GPT 吞噬 Python!ChatGPT 上线最强应用:分析数据、生成代码都精通

当地 7 月 7 日&#xff0c;OpenAI 在社交平台表示&#xff0c;将向所有 ChatGPT Plus 用户开放代码解析器&#xff08;Code Interpreter&#xff09;功能。消息一出便瞬间引发了开发者们的广泛关注&#xff0c;该功能被有的开发者认为是自 OpenAI 发布 GPT-4 以来最强大的功能…

GPT-4 终于开放了!

2023年&#xff0c;OpenAI的ChatGPT已经成为了一个不可忽视的存在。作为一种基于GPT模型的聊天机器人&#xff0c;ChatGPT在过去的一年多时间里里取得了令人瞩目的进步。从最初的简单问答&#xff0c;到现在能够进行深度对话&#xff0c;甚至可以执行代码&#xff0c;ChatGPT的…

draw.io和plantuml替代visio画图工具

目录 1.drawio <1>.Chrome plugin <2>.网址访问 <3>.draw.io快捷键 2.plantuml开源工具 <1>.网址 1.drawio <1>.Chrome plugin name&#xff1a;Diagrams for Confluence 跨平台&#xff0c;免费,在线画图。替代visio。<2>.网址访…

如何将simulink的图像导出到VISIO中

平时&#xff0c;我们在Simulink中获得的图像&#xff0c;有时需要进行修改&#xff0c;或者说图像大小比较大&#xff0c;在Simulink中操作起来比较卡。这时我们就需要将Simulink的图像导出出到Visio中。 首先&#xff0c;通过仿真&#xff0c;得到SCOPE图像&#xff0c;打开…

Visio画代码调用图

为什么一定要用上面的这个基本形状&#xff1f;而不是自己拖一个长方形出来&#xff1f;接下来就显示出优势了&#xff0c;可以很方便地连接在中点处&#xff0c;强迫症友好。 如果用长方形&#xff0c;就不能很准确地连接。 画起来真的很需要耐心&#xff0c;我放弃了 成品…

关于visio的使用

1、visio在画流程图中&#xff0c;对开发者帮助很大&#xff0c;特别是在写程序都要进行程序流程图 新建一个流程图进行绘画 2、根据流程图选择需要的款图 3.选择上面的填充使得矩形框变为白色&#xff0c;然后在里面打字 . 4、对图形进行拖动&#xff0c;出现竖直的线&#…