二十三种设计模式-装饰器模式

news2025/1/18 15:41:46

一、定义与核心思想

装饰器模式是一种结构型设计模式,其核心思想是动态地给一个对象添加一些额外的职责。通过这种方式,可以在不改变原有对象结构的基础上,灵活地增加新的功能,使得对象的行为可以得到扩展,同时又保持了原有类的简洁性。

二、组成要素

装饰器模式主要由以下几个要素组成:

  1. 抽象组件(Component)

    • 这是一个接口或抽象类,用于定义对象的接口,即声明了所有具体组件和装饰器类都需要实现的方法。它使得装饰器类可以与被装饰的具体组件类在接口上保持一致,从而可以在运行时动态地组合对象。

    • 例如,定义一个Component接口,其中声明了一个operation()方法。

  2. 具体组件(ConcreteComponent)

    • 实现抽象组件接口的具体类,它定义了对象的基本行为和状态,是被装饰的具体对象。

    • 例如,ConcreteComponent类实现了Component接口,在operation()方法中实现了具体的功能。

  3. 抽象装饰器(Decorator)

    • 也实现了抽象组件接口,它内部包含了一个对抽象组件的引用,通过这个引用可以调用被装饰对象的方法。抽象装饰器类中还定义了一些新的方法或属性,用于添加新的功能。

    • 例如,Decorator类实现了Component接口,并且有一个Component类型的成员变量component,在operation()方法中先调用component.operation(),然后添加新的行为。

  4. 具体装饰器(ConcreteDecorator)

    • 继承自抽象装饰器类,实现了添加具体功能的方法。每个具体装饰器类都实现了在抽象装饰器中声明的添加功能的方法,并且可以有自己独特的功能。

    • 例如,ConcreteDecoratorAConcreteDecoratorB都是Decorator的子类,在它们的operation()方法中分别添加了不同的新功能。

三、实现示例

以下是使用Java语言实现装饰器模式的一个简单示例:

// 抽象组件接口
interface Component {
    void operation();
}

// 具体组件类
class ConcreteComponent implements Component {
    @Override
    public void operation() {
        System.out.println("具体组件的操作");
    }
}

// 抽象装饰器类
abstract class Decorator implements Component {
    protected Component component;

    public void setComponent(Component component) {
        this.component = component;
    }

    @Override
    public void operation() {
        if (component != null) {
            component.operation();
        }
    }
}

// 具体装饰器A类
class ConcreteDecoratorA extends Decorator {
    private String addedState;

    @Override
    public void operation() {
        super.operation();
        addedState = "New State";
        System.out.println("具体装饰器A的操作");
    }
}

// 具体装饰器B类
class ConcreteDecoratorB extends Decorator {
    @Override
    public void operation() {
        super.operation();
        addedBehavior();
        System.out.println("具体装饰器B的操作");
    }

    private void addedBehavior() {
        // 添加新的行为
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        Component component = new ConcreteComponent();
        ConcreteDecoratorA decoratorA = new ConcreteDecoratorA();
        ConcreteDecoratorB decoratorB = new ConcreteDecoratorB();

        decoratorA.setComponent(component);
        decoratorB.setComponent(decoratorA);

        decoratorB.operation();
    }
}

在这个示例中,客户端代码首先创建了一个具体组件对象component,然后创建了两个具体装饰器对象decoratorAdecoratorB。通过setComponent方法将component对象与装饰器对象关联起来,并且装饰器对象之间也可以相互关联。最后调用decoratorB.operation()方法时,会依次调用decoratorA.operation()component.operation()方法,并在每个装饰器中添加新的行为。

四、优点

  1. 扩展性好

    • 可以通过添加新的装饰器类来扩展对象的功能,而无需修改原有的组件类代码,符合开闭原则。

  2. 灵活性高

    • 可以根据需要动态地添加或组合不同的装饰器,以达到不同的功能效果,比静态继承方式更加灵活。

  3. 避免了复杂的继承关系

    • 如果使用继承来扩展功能,可能会导致大量的子类产生,而装饰器模式可以避免这种情况,使系统更加简洁。

五、缺点

  1. 可能会产生很多小类

    • 每个装饰器类都是一个小类,如果装饰器很多,可能会导致类的数量急剧增加,增加了系统的复杂性。

  2. 调试难度较大

    • 由于装饰器的动态组合,可能会使得对象的行为变得难以跟踪和调试,特别是当装饰器层次较多时。

六、应用场景

  1. 功能扩展

    • 当需要给一个对象动态地添加额外的功能时,如给文本组件添加边框、颜色、字体等装饰效果。

  2. 增强对象行为

    • 在不改变原有对象的基础上,增强对象的行为,如在网络通信中,对数据进行加密、压缩等处理,可以通过装饰器模式动态地添加这些功能。

  3. 多层装饰

    • 当需要对对象进行多层装饰,以组合出多种不同的功能效果时,装饰器模式能够很好地满足需求,如在构建复杂的用户界面组件时,通过多个装饰器来实现不同的视觉效果和交互行为。

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

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

相关文章

Windows远程桌面网关出现重大漏洞

微软披露了其Windows远程桌面网关(RD Gateway)中的一个重大漏洞,该漏洞可能允许攻击者利用竞争条件,导致拒绝服务(DoS)攻击。该漏洞被标识为CVE-2025-21225,已在2025年1月的补丁星期二更新中得到…

Shell正则表达式与文本处理三剑客(grep、sed、awk)

一、正则表达式 Shell正则表达式分为两种: 基础正则表达式:BRE(basic regular express) 扩展正则表达式:ERE(extend regular express),扩展的表达式有、?、|和() 1.1 基本正则表…

基于 Spring Boot 和 Vue.js 的全栈购物平台开发实践

在现代 Web 开发中,前后端分离的架构已经成为主流。本文将分享如何使用 Spring Boot 和 Vue.js构建一个全栈购物平台,涵盖从后端 API 开发到前端页面实现的完整流程。 1. 技术栈介绍 后端技术栈 JDK 1.8:稳定且广泛使用的 Java 版本。 Spring…

Golang Gin系列-3:Gin Framework的项目结构

在Gin教程的第3篇,我们将讨论如何设置你的项目。这不仅仅是把文件扔得到处都是,而是要对所有东西的位置做出明智的选择。相信我,这些东西很重要。如果你做得对,你的项目会更容易处理。当你以后不再为了找东西或添加新功能而绞尽脑…

网络编程-UDP套接字

文章目录 UDP/TCP协议简介两种协议的联系与区别Socket是什么 UDP的SocketAPIDatagramSocketDatagramPacket 使用UDP模拟通信服务器端客户端测试 完整测试代码 UDP/TCP协议简介 两种协议的联系与区别 TCP和UDP其实是传输层的两个协议的内容, 差别非常大, 对于我们的Java来说, …

3.数据库系统

3.1数据库的基本概念 3.1.1:数据库体系结构 3.1.1.1集中式数据库系统 数据是集中的 数据管理是集中的 数据库系统的素有功能(从形式的用户接口到DBMS核心)都集中在DBMS所在的计算机 3.1.1.2C/S结构 客户端负责数据表示服务服务器主要负责数据库服务 数据库系统分为前端和后端…

探索 Transformer²:大语言模型自适应的新突破

目录 一、来源: 论文链接:https://arxiv.org/pdf/2501.06252 代码链接:SakanaAI/self-adaptive-llms 论文发布时间:2025年1月14日 二、论文概述: 图1 Transformer 概述 图2 训练及推理方法概述 图3 基于提示的…

【北京迅为】iTOP-4412全能版使用手册-第八十七章 安装Android Studio

iTOP-4412全能版采用四核Cortex-A9,主频为1.4GHz-1.6GHz,配备S5M8767 电源管理,集成USB HUB,选用高品质板对板连接器稳定可靠,大厂生产,做工精良。接口一应俱全,开发更简单,搭载全网通4G、支持WIFI、蓝牙、…

LDD3学习8--linux的设备模型(TODO)

在LDD3的十四章,是Linux设备模型,其中也有说到这个部分。 我的理解是自动在应用层也就是用户空间实现设备管理,处理内核的设备事件。 事件来自sysfs和/sbin/hotplug。在驱动中,只要是使用了新版的函数,相应的事件就会…

Jira中bug的流转流程

Jira中bug的状态 1. 处理Bug的流程2. bug状态流转详述bug的状态通常包括 1. 处理Bug的流程 2. bug状态流转详述 bug的状态通常包括 未解决 1. 测试人员创建一个bug,填写bug的详细信息,如概要、bug级别、复现步骤、现状、预期结果等 2. 定位bug&#x…

解决关于Xcode16提交审核报错

# 问题描述 The following issues occurred while distributing your application. Asset validation failed Invalid Executable. The executable xxx.app/Frameworks/HappyDNS.framework/HappyDNS contains bitcode.(lD:ef5dd249-731f-4731-8173-8e4a12519352) Asset valida…

windows下安装并使用node.js

一、下载Node.js 选择对应你系统的Node.js版本下载 Node.js官网下载地址 Node.js中文网下载地址??? 这里我选择的是Windows64位系统的Node.js20.18.0(LTS长期支持版本)版本的.msi安装包程序 官网下载: 中文网下载: 二、安…

基于SpringBoot+Vue旅游管理系统的设计和实现(源码+文档+部署讲解)

个人名片 🔥 源码获取 | 毕设定制| 商务合作:《个人名片》 ⛺️心若有所向往,何惧道阻且长 文章目录 个人名片环境需要技术栈功能介绍功能说明 环境需要 开发语言:Java 框架:springboot JDK版本:JDK1.8 数据库&…

python之二维几何学习笔记

一、概要 资料来源《机械工程师Python编程:入门、实战与进阶》安琪儿索拉奥尔巴塞塔 2024年6月 点和向量:向量的缩放、范数、点乘、叉乘、旋转、平行、垂直、夹角直线和线段:线段中点、离线段最近的点、线段的交点、直线交点、线段的垂直平…

RabbitMQ---消息确认和持久化

(一)消息确认 1.概念 生产者发送消息后,到达消费端会有以下情况: 1.消息处理成功 2.消息处理异常 如果RabbitMQ把消息发送给消费者后就把消息删除,那么就可能会导致,消息处理异常想要再获取这条消息的时…

map和set c++

关联式容器也是⽤来存储数据的,与序列式容器不同的是,关联式容器逻辑结构通常是⾮线性结构,两个位置有紧密的关联关系,交换⼀下,他的存储结构就被破坏了。顺序容器中的元素是按关键字来保存和访问的。关联式容器有map/…

turtle教学课程课堂学习考试在线网站

完整源码项目包获取→点击文章末尾名片!

Digital Document System (DDS)

Digital Document System (DDS) 数字档案平台 信息注入

Springer Nature——Applied Intelligence 投稿指南

投稿系统:Editorial Manager (Manuscript and Peer Review) : 使用Editorial Manager 投稿系统的期刊列表:期刊列表 期刊主页:Spring Nature 主页 投稿主页:Spring Nature Submit SystemSubmission Guidelines: Official Submissi…

如何在前端给视频进行去除绿幕并替换背景?-----Vue3!!

最近在做这个这项目奇店桶装水小程序V1.3.9安装包骑手端V2.0.1小程序前端 最近,我在进行前端开发时,遇到了一个难题“如何给前端的视频进行去除绿幕并替换背景”。这是一个“数字人项目”所需,我一直在冥思苦想。终于有了一个解决方法…