秒懂设计模式--学习笔记(9)【结构型-装饰器模式】

目录

      • 8、装饰器模式
          • 8.1 装饰器模式(Decorator)
          • 8.2 装修(举例)
          • 8.3 化妆(示例)
          • 8.4 化妆品的多样化
          • 8.5 装饰器
          • 8.6 自由嵌套
          • 8.7 装饰器模式的各角色定义
          • 8.8 装饰器模式

8、装饰器模式

8.1 装饰器模式(Decorator)
  • 能够在运行时动态地为原始对象增加一些额外的功能
  • 装饰器非常类似于“继承”,它们都是为了增强原始对象的功能,区别在于方式的不同
    • 后者是在编译时(compile-time)静态地通过对原始类的继承完成
    • 前者则是在程序运行时(run-time)通过对原始对象动态地“包装”完成,是对类实例(对象)“装饰”的结果
  • 测试类结构
    装饰器测试类结构
8.2 装修(举例)
  • 不改变其原始结构的前提下使客体功能得到扩展、增强
  • 以室内装潢为例
    • 装修风格多种多样
    • 朴素的毛坯房能给业主留有更大的装修选择空间,以根据自己的喜好进行二次加工
    • 成品一定是由半成品加工而成的
    • 灵活多变的装饰才会带来更多的可能,因此装饰器模式应运而生
8.3 化妆(示例)
  • 首先对于任何妆容展示者必然对应一个标准的展示行为show()
  • 我们将它抽象出来定义为接口Showable
  • Showable这个标准行为需要人去实现,定义女生类,素颜展示
    • 如果客户端直接调用show()方法,就会出现素面朝天的结果
    	package decorator;/*** 可展示者**/public interface Showable {/*** 标准展示行为*/public void show();}
    
    • 化妆品我们在这里称为“装饰器”: 化妆品装饰器类Decorator
    	package decorator.base;import decorator.Showable;/*** 化妆品装饰器类**/public class Decorator implements Showable {/***被装饰的展示者*/Showable showable;/*** 构造时注入被装饰者* @param showable*/public Decorator(Showable showable) {this.showable = showable;}@Overridepublic void show() {//化妆品粉饰开始System.out.print("粉饰【");//被装饰者的原生展示方法showable.show();//粉饰结束System.out.print("】");}}
    
    • 装饰器实现类
    	package decorator.entity;import decorator.Showable;/*** 装饰器实现类**/public class Girl implements Showable {@Overridepublic void show() {System.out.print("女生的素颜");}}
    
    • 测试类
    	package decorator.base;import decorator.entity.Girl;		/*** 客户端测试类**/public class Client {public static void main(String[] args) {//用装饰器装饰后后再展示new Decorator(new Girl()).show();}}
    
8.4 化妆品的多样化
  • 化妆品的多样性决定了装饰器应该是多态化的
    • 单个装饰器应该只负责自己的化妆功效
    • 把化妆品按功能分类才能让用户更加灵活地自由搭配,用哪个或不用哪个由用户自己决定,而不是把所有功能都固化在同一个装饰器里
    • 如果让所有化妆品类都实现Showable接口,每个化妆品类里都要引用这个被装饰者,这显然会导致代码冗余。
    • Showable接口是能够满足多态化需求的,但它只是对行为接口的一种规范,极度的抽象并不具备对代码继承的功能
  • 化妆品的多态化还需要接口与抽象类的搭配使用才能两全其美,装饰器类的抽象化势在必行
    • 我们将化妆品装饰器类修改为装饰器抽象类,这主要是为了不允许用户直接实例化此类
    • 调用了被装饰者的show()方法,而不再做任何装饰操作
    • 至于具体如何装饰则属于其子类的某个化妆品类的操作范畴了
    • 抽象装饰器DecoratorAbstract
    	package decorator.ab;import decorator.Showable;/*** 化妆品装饰器类: 抽象类**/public abstract class DecoratorAbstract implements Showable {protected Showable showable;public DecoratorAbstract(Showable showable) {this.showable = showable;}@Overridepublic void show() {// 直接调用不加任何装饰showable.show();}}
    • 实现类
      • 粉底类FoundationMakeup、口红类Lipstick
      package decorator.ab;
      import decorator.Showable;
      /*** 粉底类**/
      public class FoundationMakeup extends DecoratorAbstract {/*** 调用抽象父类的构造注入* @param showable*/public FoundationMakeup(Showable showable) {super(showable);}@Overridepublic void show() {System.out.print("打粉底【");showable.show();System.out.print("】");}
      }
      
      package decorator.ab;import decorator.Showable;/*** 口红类**/
      public class Lipstick extends DecoratorAbstract {public Lipstick(Showable showable) {super(showable);}@Overridepublic void show() {System.out.print("涂口红【");showable.show();System.out.print("】");}
      }
      
      • 不用去实现Showable接口了,而是继承了装饰器抽象类,如此父类中对被装饰者的定义得以继承
      • 重写show()方法, 加上自己特有的操作
    • 客户端类Client
      • 涂口红【打粉底【女生的脸庞】】
      • 需要注意的是一系列构造产生的顺序
 package decorator.ab;import decorator.entity.Girl;
import decorator.Showable;import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.zip.ZipInputStream;/*** 客户端测试类**/
public class Client {public static void main(String[] args) throws FileNotFoundException {test1();test2();}private static void test1() {Girl girl = new Girl();/*** 上粉底*/Showable foundationMakeup = new FoundationMakeup(girl);/*** 涂口红*/Showable medeupGirl = new Lipstick(foundationMakeup);medeupGirl.show();}private static void test2() throws FileNotFoundException {// 1.首先以文件file初始化File file = new File("/压缩包.zip");// 4.最外层再用压缩包输入流ZipInputStream进行最终装饰,使文件输入流具备Zip格式文件的功能ZipInputStream zipInputStream = new ZipInputStream(// 3.外层用缓冲输入流BufferedInputStream进行装饰,使文件输入流具备内存缓冲的功能new BufferedInputStream(// 2.构造文件输入流FileInputStreamnew FileInputStream(file)));}
}
8.5 装饰器
  • 如同“俄罗斯套娃”一般层层嵌套
  • 其实装饰器模式在Java开发工具包(Java Development Kit,JDK)里就有大量应用
    • 例如“java.io”包里一系列的流处理类InputStream、FileInputStream、BufferedInputStream、ZipInputStream等
  • 举个例子,当对压缩文件进行解压操作时,我们就会用构造器嵌套结构进行文件流装饰,如:ab.Client.test2()
8.6 自由嵌套
  • 装饰器模式最终的目的就在于“装饰”对象
  • 其中装饰器抽象类扮演着至关重要的角色,它实现了组件的通用接口
  • 并且使自身抽象化以迫使子类继承,使装饰器固定特性的延续与多态化成为可能
8.7 装饰器模式的各角色定义
  • Component(组件接口):
    • 所有被装饰组件及装饰器对应的接口标准指定进行装饰的行为方法。如:展示接口Showable。
  • ConcreteComponent(组件实现):
    • 需要被装饰的组件实现组件接口标准,只具备自身未被装饰的原始特性。如:类Girl
  • Decorator(装饰器):
    • 装饰器的高层抽象类,
    • 同样实现组件接口标准且包含一个被装饰的组件
  • ConcreteDecorator(装饰器实现)
    • 继承自装饰器抽象类的具体子类装饰器,可以有多种实现,在被装饰组件对象的基础上为其添加新的特性
    • 如: 粉底类FoundationMakeup、口红类Lipstick
8.8 装饰器模式
  • 装饰器模式可以将不同功能的单个模块规划至不同的装饰器类中
  • 客户端可以根据自己的需求自由搭配各种装饰器,每加一层装饰就会有新的特性体现出来
  • 最终使原始对象的特性动态地得到增强

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

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

相关文章

红色文化3D虚拟数字展馆搭建意义深远

在房地产与土地市场的浪潮中,无论是新城规划、乡村振兴,还是商圈建设,借助VR全景制作、虚拟现实和web3d开发技术打造的全链条无缝VR看房新体验。不仅极大提升了带看与成交的转化率,更让购房者足不出户,即可享受身临其境…

能把进程和线程讲的这么透彻的,没有20年功夫还真不行【0基础也能看懂】

本篇会加入个人的所谓鱼式疯言 ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. 🤭🤭🤭可能说的不是那么严谨.但小编初心是能让更多人…

SQL Server 创建用户并授权

创建用户前需要有一个数据库,创建数据库命令如下: CREATE DATABASE [数据库名称]; CREATE DATABASE database1; 一、创建登录用户 方式1:SQL命令 命令格式:CREATE LOGIN [用户名] WITH PASSWORD 密码; 例如,创建…

FlinkErr:org/apache/hadoop/hive/ql/parse/SemanticException

在flink项目中跑 上面这段代码出现如下这个异常&#xff0c; java.lang.NoClassDefFoundError: org/apache/thrift/TException 加上下面这个依赖后不报错 <dependency> <groupId>org.apache.thrift</groupId> <artifactId>libthrift</artifactId…

Python绘制相关系数热力图

相关系数热力图是一种可视化工具&#xff0c;用于展示变量之间的相关性。它在数据分析和统计中非常有用&#xff0c;尤其是在探索数据集的内在关系时。本文将介绍如何使用Python绘制相关系数热力图。 一、准备——导入库 使用Pandas来处理数据&#xff0c;Matplotlib和Seabor…

redis笔记2

redis是用c语言写的,放不频繁更新的数据&#xff08;用户数据。课程数据&#xff09; Redis 中&#xff0c;"穿透"通常指的是缓存穿透&#xff08;Cache Penetration&#xff09;问题&#xff0c;这是指一种恶意或非法请求直接绕过缓存层&#xff0c;直接访问数据库或…

Qt | 绘制椭圆、弧、弦、扇形、圆角矩形

点击上方"蓝字"关注我们 01、简介 1、需要使用到的 QPainter 类中的函数 2、绘制椭圆的方法有 绘制给定矩形的内接椭圆和根据中心点与椭圆 x 方向和 y 方向的半径绘制,原理见下图 3、绘制弧、弦、扇形的原理: 1)、弧是椭圆上的一段曲线,因此其绘制方法就是首先…

STM32之八:IIC通信协议

目录 1. IIC协议简介 1.1 主从模式 1.2 2根通信线 2. IIC协议时序 2.1 起始条件和终止条件 2.2 发送一个字节 2.3 接收一个字节 2.4 应答信号 1. IIC协议简介 IIC协议是一个半双工、同步、一主多从、多主多从的串行通用数据总线。该通信模式需要2根线&#xff1a;SCL、…

ubuntu22.04安装SecureCRT8.7.3,完成顺利使用

材料准备 scrt-sfx安装包 &#xff0c; securecrt_linux_crack.pl 补丁脚本&#xff0c;和两个依赖库 其中securecrt_linux_crack.pl是找的专门适合 8.7.3版本的&#xff0c;网上很多版本的crack.pl只能打补丁以前的老版本。 而更老版本的SecureCRT对ubuntu22支持更不好&#…

【低照度图像增强系列(8)】URetinex-Net算法详解与代码实现(2022|CVPR)

前言 ☀️ 在低照度场景下进行目标检测任务&#xff0c;常存在图像RGB特征信息少、提取特征困难、目标识别和定位精度低等问题&#xff0c;给检测带来一定的难度。 &#x1f33b;使用图像增强模块对原始图像进行画质提升&#xff0c;恢复各类图像信息&#xff0c;再使用目标检…

hmallox勒索病毒科普:了解其威胁与防御策略

hmallox勒索病毒科普&#xff1a;了解其威胁与防御策略 一、引言 在数字化时代&#xff0c;网络安全威胁日益严峻&#xff0c;勒索病毒作为其中的一类恶意软件&#xff0c;给个人和企业带来了巨大损失。hmallox勒索病毒作为Mallox勒索软件家族的新变种&#xff0c;以其高度的…

求职学习笔记day1

自己一直算是一个内耗拖延的人&#xff0c;内耗着考了研&#xff0c;内耗着拖着不找工作&#xff0c;一直拖到了毕业。研究生没考上&#xff0c;工作没有&#xff0c;也羡慕着别人成功的生活&#xff0c;最后毕业的也不太开心。 一、最近总结 游戏 高考结束以来和大学期间作息…

数据结构之初始二叉树(2)

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a;数据结构&#xff08;Java版&#xff09; 二叉树的前置知识&#xff08;概念、性质、、遍历&#xff09; 通过上篇文章的学习&#xff0c;我们…

TCP/IP中的复用、分解和封装

TCP/IP&#xff08;传输控制协议/互联网协议&#xff09;模型中&#xff0c;复用&#xff08;Multiplexing&#xff09;、分解&#xff08;Demultiplexing&#xff09;和封装&#xff08;Encapsulation&#xff09;是关键概念&#xff0c;它们帮助管理和传输数据在网络上的有效…

【Linux】centos7安装PHP7.4报错:libzip版本过低

问题描述 configure: error: Package requirements (libzip > 0.11 libzip ! 1.3.1 libzip ! 1.7.0) were not met: checking for libzip > 0.11 libzip ! 1.3.1 libzip ! 1.7.0... no configure: error: Package requirements (libzip > 0.11 libzip ! 1.3.1 libzi…

Java中线程启动:start()与run()方法的区别

Java中线程启动&#xff1a;start&#xff08;&#xff09;与run&#xff08;&#xff09;方法的区别 1. start()方法2. run()方法3、总结4、示例对比 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 线程是并发执行的基本单位&#xff0c;而…

中科亿海微亮相慕尼黑上海电子展

7月8-10日&#xff0c;备受瞩目的全球电子行业盛会“慕尼黑上海电子展”以空前规模启幕&#xff0c;汇聚了超过1600家参展企业&#xff0c;涵盖了从终端产品制造商到元器件供应商、组装/系统供应商、EMS、ODM/OEM、材料供应商及生产设备供应商的完整产业链。中科亿海微电子科技…

《昇思25天学习打卡营第22天|基于MindSpore的GPT2文本摘要》

#学习打卡第22天# 1. 数据集 1.1 数据下载 使用nlpcc2017摘要数据&#xff0c;内容为新闻正文及其摘要&#xff0c;总计50000个样本。 from mindnlp.utils import http_get from mindspore.dataset import TextFileDataset# download dataset url https://download.mindspor…

活用 localStorage

我维护的这款工具 https://editor.yunwow.cn/ 已经帮我写了 7 篇文章了&#xff0c; 用起来很顺手&#xff0c;因此我打算再给它升级下让它更方便&#xff0c;我决定要给它加个本地缓存功能。我给它提的要求是&#xff1a; 1. 至少能缓存 5 篇文章 2. 能有选择的加载模板 3…

MySQL-对数据库和表的DDL命令

文章目录 一、什么是DDL操作二、数据库编码集和数据库校验集三、使用步骤对数据库的增删查改1.创建数据库2.进入数据库3.显示数据库4.修改数据库mysqldump 5.删除数据库 对表的增删查改1.添加/创建表2.插入表内容3.查看表查看所有表查看表结构查看表内容 4.修改表修改表的名字修…