【软考】设计模式之装饰器模式

news2024/11/17 4:35:50

目录

          • 1. 说明
          • 2. 应用场景
          • 3. 结构图
          • 4. 构成
          • 5. 适用性
          • 6. 优点
          • 7. 缺点
          • 8. java示例

1. 说明
  • 1.动态地给一个对象添加一些额外的职责
  • 2.Decorator Pattern。
  • 3.就增加功能而言,装饰器模式比生成子类更加灵活。
  • 4.一种在不改变现有对象结构的情况下,动态地给对象增加一些职责(即增加额外功能)的设计模式。
  • 5.属于对象结构型模式。
2. 应用场景
  • 1.扩展功能:当需要给某个对象添加额外的功能,但又不想修改其源代码或结构时,可以使用装饰器模式。例如,在软件开发中,可以使用装饰器模式来扩展类的功能,而无需创建新的子类。
  • 2.动态代理:装饰器模式允许在运行时动态地给对象添加或撤销功能。这对于需要动态修改对象行为的场景非常有用。
  • 3.缓存功能:通过装饰器模式,可以为对象添加缓存功能,以提高系统的性能。例如,可以在数据访问层使用装饰器模式来缓存数据,减少对数据库的频繁访问。
  • 4.日志记录:在系统中,经常需要记录对象的操作历史或状态变化。通过装饰器模式,可以轻松地给对象添加日志记录功能,方便后续的调试和错误追踪。
  • 5.用户界面定制:在图形用户界面(GUI)设计中,可以使用装饰器模式来定制和扩展控件的功能。例如,可以为按钮添加动画效果、改变样式或添加额外的交互功能。
  • 6.文件处理:在处理文件时,可以使用装饰器模式来添加各种文件处理功能,如压缩、加密、解密等。这样,用户可以根据需要选择不同的装饰器来处理文件。
  • 7.网络请求:在发送网络请求时,可以使用装饰器模式来添加各种请求处理功能,如超时重试、身份验证、请求签名等。这些功能可以在不修改原始请求代码的情况下动态地添加到请求中。
  • 8.数据处理:在处理数据时,可以使用装饰器模式来添加各种数据处理功能,如排序、过滤、转换等。这些功能可以根据需要动态地添加到数据处理流程中。
3. 结构图

在这里插入图片描述

4. 构成
  • 1.Commponent(抽象组件):定义一个对象接口,可以给这些对象动态地添加职责。定义一个接口或抽象类,规定被装饰对象的行为。
  • 2.ConcreteComponent(具体组件):定义一个对象,可以给这个对象添加职责。实现抽象组件接口或继承抽象组件类,是装饰器模式中的原始对象。
  • 3.Decorator(抽象装饰器):维持一个指向Component对象的指针,并定义一个与Component接口一致的接口。继承或实现抽象组件接口,并持有一个指向抽象组件的引用。抽象装饰器通常还包含一些用于增加额外功能的方法。
  • 4.ConcreteDecorator(具体装饰器):向组件添加职责。继承抽象装饰器类,并实现具体的额外功能。具体装饰器可以根据需要添加多个,以实现不同的效果。
5. 适用性
  • 1.在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
  • 2.处理那些可以撤销的职责
  • 3.当不能采用生成子类的方式进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是,由于类定义被隐藏,或类定义不能用于生成子类。
6. 优点
  • 1.灵活性:装饰器是继承的有力补充,比继承更加灵活。它可以在不改变原有对象的情况下,动态地给一个对象扩展功能,实现即插即用。
  • 2.可扩展性:通过使用不同的装饰类以及这些装饰类的排列组合,可以实现不同的效果,满足不同的需求。
  • 3.遵循开闭原则:装饰器模式在扩展功能时,不需要修改原有类的代码,符合开闭原则(对扩展开放,对修改关闭)。
7. 缺点
  • 1.增加复杂性:装饰器模式会增加许多子类,过度使用会增加程序的复杂性。
  • 2.难以理解:如果装饰器类过多,可能会使代码变得难以理解和维护。
8. java示例
  • 1.抽象组件
package com.learning.decorator.person;

/**
 * 抽象组件
 * 定义一个人的接口
 * 获取人的描述
 */
public interface Person {
    String getDescription();  
}
  • 2.具体组件
package com.learning.decorator.person;

/**
 * 基础的人
 * 具体组件
 */
public class BasePerson implements Person {
    /**
     * 人的姓名
     */
    private String name;  
  
    public BasePerson(String name) {  
        this.name = name;  
    }  
  
    @Override  
    public String getDescription() {  
        return name;  
    }  
}
  • 3.抽象装饰器
package com.learning.decorator.person;

/**
 * 抽象装饰器
 * 衣服装饰器
 */
public abstract class ClothingDecorator implements Person {
    //被装饰的对象
    protected Person person;  
  
    public ClothingDecorator(Person person) {  
        this.person = person;  
    }  
  
    @Override  
    public String getDescription() {  
        return decorate(person.getDescription());  
    }  
  
    protected abstract String decorate(String description);  
}
  • 4.具体装饰器帽子装饰器
package com.learning.decorator.person;

/**
 * 具体装饰器
 * 帽子装饰器
 */
public class HatDecorator extends ClothingDecorator {
    public HatDecorator(Person person) {  
        super(person);  
    }

    /**
     * 帽子装饰,戴了一个帽子
     * @param description
     * @return
     */
    @Override  
    protected String decorate(String description) {  
        return description + "戴了一个帽子";
    }  
}
  • 5.具体装饰器围巾装饰器
package com.learning.decorator.person;

/**
 * 具体装饰器
 * 毛巾装饰器
 */
public class ScarfDecorator extends ClothingDecorator {
    public ScarfDecorator(Person person) {  
        super(person);  
    }

    /**
     * 覆盖父类的方法, 戴了一条围巾
     * @param description
     * @return
     */
    @Override  
    protected String decorate(String description) {  
        return description + "戴了一条围巾";
    }  
}
  • 6.客户端
package com.learning.decorator.person;

public class Client {
    public static void main(String[] args) {  
        Person person = new BasePerson("张三");
        System.out.println(person.getDescription());
  
        Person personWithHat = new HatDecorator(person);
        System.out.println(personWithHat.getDescription());
  
        Person personWithHatAndScarf = new ScarfDecorator(personWithHat);
        System.out.println(personWithHatAndScarf.getDescription());
  
    }
}
  • 7.示例截图
    在这里插入图片描述

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

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

相关文章

c++(二)

C(二) 类和对象C中的结构体和C中的结构体有什么区别C中的结构体和类有什么区别访问限定符类的定义对象类与对象之间的关系封装 this指针类中特殊的成员函数构造函数默认构造函数普通构造函数拷贝构造函数浅拷贝深拷贝 析构函数 类和对象 什么是结构体&a…

简易CAD程序:Qt多文档程序的一种实现

注&#xff1a;文中所列代码质量不高&#xff0c;但不影响演示我的思路 实现思路说明 实现DemoApplication 相当于MFC中CWinAppEx的派生类&#xff0c;暂时没加什么功能。 DemoApplication.h #pragma once#include <QtWidgets/QApplication>//相当于MFC中CWinAppEx的派生…

AI语音识别技术-ASR

一、首先什么是ASR技术&#xff1f; 语音识别技术是一种将人的语音转换为文本的技术。其目标是将人类的语音中的词汇内容转换为计算机可读的输入&#xff0c;ASR技术就是将人的语言转化为计算机能够识别的文字的过程。 二、ASR技术应用中遇到的难点 在自动语音识别应用场景中&…

快速搭建流媒体服务

1、安装流媒体服务 源码地址&#xff1a;https://gitee.com/ossrs/srs 本次采用docker安装 docker run --rm -it -p 1935:1935 -p 1985:1985 -p 8080:8080 -p 8000:8000/udp -p 10080:10080/udp registry.cn-hangzhou.aliyuncs.com/ossrs/srs:5 查看运行效果&#xff…

2024年5月19日优雅草蜻蜓K知识付费系统旗舰版v1.0.9进度更新

v1.1.0更新 v1.1.0更新 2024年5月19日优雅草蜻蜓K知识付费系统旗舰版v1.0.9进度更新&#xff0c;首页体育栏目完善新增用户发布页面 开发进度 首页体育栏目完善 新增用户发布页面 新增用户登录完善 新增学习课程页面完善-过往课程数据完成 去掉其他三方登录&#xff0c;新增…

linux安装KubeSphere

linux安装KubeSphere 介绍 KubeSphere 是在目前主流容器调度平台 Kubernetes 之上构建的企业级分布式多租户容器平台&#xff0c;提供简单易用的操作界面以及向导式操作方式&#xff0c;在降低用户使用容器调度平台学习成本的同时&#xff0c;极大减轻开发、测试、运维的日常…

Centos7.9安装卸载Docker

文章目录 1、官网安装1.1、卸载旧版本Docker1.2、通过rpm仓库安装1.2.1、设置仓库1.2.2、安装Docker Engine1.2.3、启动Docker1.2.4、验证安装 1.3、通过rpm软件包安装1.4、通过便捷脚本安装 2、yum安装2.1、安装docker-ce以及客户端2.2、启动docker2.3、配置镜像加速 3、卸载D…

Shell编程之条件判断语句

目录 一、条件判断 1、test命令 2、文件测试 3、整数值比较 4、字符串判断 5、逻辑测试 二、if语句 1、if单分支语句 2、双分支语句 3、多分之语句 4、case 分支语句 一、条件判断 Shell环境根据命令执行后的返回状态值&#xff08;echo $?&#xff09;来判断是否执行成…

docker如何拉取nginx最新镜像并运行

要拉取Docker Hub上的最新Nginx镜像&#xff0c;您可以使用以下命令&#xff1a; docker pull nginx 这个命令会从Docker Hub下载最新版本的Nginx镜像。如果您想要拉取特定版本的Nginx镜像&#xff0c;可以指定版本号&#xff0c;例如&#xff1a; docker pull nginx:1.18.0 拉…

思科模拟器--06.单臂路由升级版--多端路由互连实验--24.5.20

实验图纸如下: 第0步: 先放置六台个人电脑,一台交换机和一台2911路由器(千兆路由器(G0开头的)) 接着,用直通线将 PC0的F0,PC1的F0分别和交换机的F0/0, F0/1连接 交换机的F0/3和路由器的G0/0连接 PC2的F0,PC3的F0分别和交换机的F0/4, F0/5连接 交换机的F0/6和路由器的G0/1…

MySQL---函数与约束

目录 一、函数 1. 字符串函数 2. 数值函数 3. 日期函数 4. 流程函数 5. 总结 二、约束 1. 概述 2. 约束演示 3. 外键约束 3.1 添加外键 3.2 删除外键 3.3 外键删除更新行为 4. 总结 一、函数 1. 字符串函数 命令如下所示&#xff1a; -- concat select concat("Hel…

Qt | QGridLayout 类(网格布局)

01、上节回顾 Qt | QBoxLayout 及其子类(盒式布局)02、QGridLayout 简介 1、网格布局原理(见下图): 基本原理是把窗口划分为若干个单元格,每个子部件被放置于一个或多个单元格之中,各 单元格的大小可由拉伸因子和一行或列中单元格的数量来确定,若子部件的大小(由 sizeH…

园区网的基本了解

园区网使用的典型技术---IEEE802.3标准/IEEE802.11标准 封闭式园区网络 ---由内部人员使用&#xff0c;不能访问互联网。 ---制订各式各样的规章制度 ---NAC&#xff0c;网络接入控制 开放式园区网络 ---服务于公众的&#xff0c;认证 园区网的发展 第一代&#xff1a;…

开关电源重点可靠性测试项目与测试方法

为确保开关电源在复杂工作环境下的安全性与稳定性&#xff0c;各种安全性测试成为不可或缺的环节。本文将深入探讨几项关键的安全性测试项目&#xff0c;帮助用户全面了解如何评估开关电源的可靠性和安全性。 一、过压保护测试方法 目的是为了检测当输出电压过高时&#xff0c;…

express.js--token中间件验证及token解析(三)

主要作用 访问路由接口时&#xff0c;哪些需要校验token 通过token解析身份信息&#xff0c;就可以知道是哪个人 框架基本搭建express.js--基本用法及路由模块化(一)-CSDN博客 如何生成tokenexpress.js--生成token(二)-CSDN博客 middleware/index.js const jwt require(…

【linux】yumvim工具理解使用

目录 Linux 软件包管理器 yum 关于 rzsz 注意事项 查看软件包 Linux开发工具 Linux编辑器-vim使用 vim的基本概念 vim的基本操作 vim正常模式命令集 vim末行模式命令集 简单vim配置 配置文件的位置 sudo提权 Linux 软件包管理器 yum 1.yum是什么&#xff1…

Java基础22(JSON解析 注解)

目录 一、JSON解析 1. JSON语法 2. JSON的用途 3. Java解析JSON 4. 使用Fastjson 4.1 Fastjson 的优点 4.2 Fastjson 导包 4.3 Fastjson的主要对象 4.4 常用方法 将Java对象 "序列化"&#xff08;转换&#xff09; 为JSON字符串&#xff1a; 将JSON字符串…

薪资不公、晋升无望?动笔写一份申诉材料吧!

薪资不公、晋升无望&#xff1f;动笔写一份申诉材料吧&#xff01; 引言&#xff1a;每个努力工作的人都值得公平对待 在职场上&#xff0c;我们付出了汗水和智慧&#xff0c;期待着相应的回报——合理的工资和公正的晋升机会。然而&#xff0c;现实并不总是如此美好。当你感觉…

康谋分享 | aiSim5基于生成式AI扩大仿真测试范围(终)

在前面的几章节中探讨了aiSim仿真合成数据的置信度&#xff0c;此外在场景重建和测试流程闭环的过程中&#xff0c;难免会面临3D场景制作重建耗时长、成本高、扩展性低以及交通状况复杂程度难以满意等问题&#xff0c;当前的主要挑战在于如何自动化生成3D静态场景并添加动态实例…

深入理解C#中的IO操作 - FileStream流详解与示例

文章目录 一、FileStream类的介绍二、文件读取和写入2.1 文件读取&#xff08;FileStream.Read&#xff09;2.2 文件写入&#xff08;FileStream.Write&#xff09; 三、文件复制、移动和目录操作3.1 文件复制&#xff08;FileStream.Copy&#xff09;3.2 文件移动&#xff08;…