设计模式使用场景实现示例(结构型模式——装饰器模式)

在一个被高山和浓密森林包围的古老王国中,有一位技艺高超的工匠名叫李奥。李奥擅长制作各种各样的物品,从精致的首饰到坚固的盔甲。然而,他最引以为傲的创造是一把能够根据持有者的需要变换形态的神奇剑。

这把剑被命名为“千面剑”。起初,它只是一把普通的铁剑,但李奥利用了一种古老的技术——我们现代人可能会称之为“装饰器模式”。通过这种技术,李奥能够为剑加上不同的魔法元素作为“装饰”,使剑的功能随时可以改变,而不需要重新制造。

有一天,国王的使者来到李奥的工坊,请求一把能够在即将到来的大战中为国王带来胜利的特殊武器。李奥决定将“千面剑”交给国王。

在战争中,这把剑展示了其真正的力量。当国王需要对抗敌人的重甲骑士时,剑变成了一把锋利无匹的长剑;当面对快速移动的敌人时,它又能变成轻巧的短剑。在战斗的不同阶段,剑的“装饰”根据需要进行更换,每次都完美地适应了战场的状况。

装饰器模式(Decorator Pattern)

装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许你动态地为对象添加新的行为,而无需改变其代码。装饰器模式通过创建一个装饰类来包装原始类,从而增强或改变其功能。

适用场景

  1. 需要扩展一个类的功能

    • 需要为一个类添加一些额外的职责,而不希望修改原始类的代码。
  2. 动态添加功能

    • 希望通过组合多个装饰器动态地添加功能。
  3. 希望实现功能的按需组合

    • 通过多个装饰器可以组合出不同的功能组合,避免创建大量的子类。

实现示例(Java)

以下是一个简单的装饰器模式的实现示例,展示如何动态地为一个对象添加新功能。

1. 定义组件接口
public interface Component {void operation();
}
2. 定义具体组件类
public class ConcreteComponent implements Component {@Overridepublic void operation() {System.out.println("ConcreteComponent operation");}
}
3. 定义装饰器抽象类
public abstract class Decorator implements Component {protected Component component;public Decorator(Component component) {this.component = component;}@Overridepublic void operation() {component.operation();}
}
4. 定义具体装饰器类
public class ConcreteDecoratorA extends Decorator {public ConcreteDecoratorA(Component component) {super(component);}@Overridepublic void operation() {super.operation();addedBehavior();}private void addedBehavior() {System.out.println("ConcreteDecoratorA added behavior");}
}public class ConcreteDecoratorB extends Decorator {public ConcreteDecoratorB(Component component) {super(component);}@Overridepublic void operation() {super.operation();addedBehavior();}private void addedBehavior() {System.out.println("ConcreteDecoratorB added behavior");}
}
5. 客户端代码
public class Client {public static void main(String[] args) {Component component = new ConcreteComponent();Component decoratorA = new ConcreteDecoratorA(component);Component decoratorB = new ConcreteDecoratorB(decoratorA);decoratorB.operation();}
}

注释说明

  1. 组件接口

    • Component 接口定义了一个方法 operation,这是所有组件和装饰器都需要实现的方法。
  2. 具体组件类

    • ConcreteComponent 是一个具体的组件类,实现了 Component 接口的方法。
  3. 装饰器抽象类

    • Decorator 是一个抽象类,实现了 Component 接口,并持有一个 Component 对象。它的 operation 方法调用了被装饰对象的 operation 方法。
  4. 具体装饰器类

    • ConcreteDecoratorAConcreteDecoratorB 是具体的装饰器类,它们继承自 Decorator 并添加了新的行为。
  5. 客户端代码

    • Client 类通过组合多个装饰器来增强 ConcreteComponent 的功能。decoratorB 包装了 decoratorA,而 decoratorA 包装了 component,最终调用 operation 方法时,会依次调用各个装饰器和具体组件的方法。

类图

Client|v
Component <---- Decorator <---- ConcreteDecoratorA^                                ||                                v
ConcreteComponent          ConcreteDecoratorB

总结

装饰器模式通过创建装饰器类来包装原始类,使得你可以动态地添加或改变对象的行为。它适用于需要扩展类的功能且不希望修改原始类代码的场景,同时通过组合多个装饰器可以实现功能的按需组合,避免创建大量的子类。

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

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

相关文章

WEB前端09-前端服务器搭建(Node.js/nvm/npm)

前端服务器的搭建 在本文中&#xff0c;我们将介绍如何安装和配置 nvm&#xff08;Node Version Manager&#xff09;以方便切换不同版本的 Node.js&#xff0c;以及如何设置 npm&#xff08;Node Package Manager&#xff09;使用国内镜像&#xff0c;并搭建一个简单的前端服…

MySQL-显示所有错误信息

1 需求 需求1&#xff1a;默认值 需求2&#xff1a;查询当前值 需求3&#xff1a;设置显示所有错误信息 2 语法 3 示例 在 MySQL 中&#xff0c;当执行 SQL 语句时发生的错误通常不会直接显示所有的错误信息&#xff0c;而是返回一个错误代码和简短的描述。但是&#xff0c;…

类和对象(三)

默认成员函数 接下来继续看剩下的两个默认成员函数。 const成员函数 将const修饰的成员函数称之为const成员函数&#xff0c;const修饰成员函数放到成员函数参数列表的后 ⾯。const实际修饰该成员函数隐含的this指针&#xff0c;表明在该成员函数中不能对类的任何成员进⾏修…

秋招突击——7/17——复习{二分查找——搜索插入位置、搜索二维矩阵,}——新作{链表——反转链表和回文链表,子串——和为K的子数组}

文章目录 引言新作二分模板二分查找——搜索插入位置复习实现 搜索二维矩阵复习实现 新作反转链表个人实现参考实现 回文链表个人实现参考实现 和为K的子数组个人实现参考实现 总结 引言 今天算法得是速通的&#xff0c;严格把控好时间&#xff0c;后面要准备去面试提前批了&a…

C语言实例-约瑟夫生者死者小游戏

问题&#xff1a; 30个人在一条船上&#xff0c;超载&#xff0c;需要15人下船。于是人们排成一队&#xff0c;排队的位置即为他们的编号。报数&#xff0c;从1开始&#xff0c;数到9的人下船&#xff0c;如此循环&#xff0c;直到船上仅剩15人为止&#xff0c;问都有哪些编号…

C语言 | Leetcode C语言题解之第260题只出现一次的数字III

题目&#xff1a; 题解&#xff1a; int* singleNumber(int* nums, int numsSize, int* returnSize) {int xorsum 0;for (int i 0; i < numsSize; i) {xorsum ^ nums[i];}// 防止溢出int lsb (xorsum INT_MIN ? xorsum : xorsum & (-xorsum));int type1 0, type2…

【Mysql】Docker下Mysql8数据备份与恢复

[TOC] 【Mysql】Docker下Mysql8数据备份与恢复 1 创建Mysql容器 格式 docker run -d --name容器名称 -p 宿主端口号:3306 -e MYSQL_ROOT_PASSWORDmysql密码 -e MYSQL_PASSWORDmysql密码 -e TZAsia/Shanghai -v 宿主目录-数据:/var/lib/mysql -v 宿主目录-备份数据:/back…

多态性概念 OOPS

大家好&#xff01;今天&#xff0c;我们将探讨面向对象编程 (OOP) 中的一个基本概念 - 多态性。具体来说&#xff0c;我们将重点介绍其三种主要形式&#xff1a;方法重载、方法覆盖和方法隐藏。对于任何使用 OOP 语言&#xff08;例如 C#&#xff09;的程序员来说&#xff0c;…

NET 语言识别,语音控制操作、语音播报

System.Speech. 》》System.Speech.Synthesis; 语音播报 》》System.Speech.Recognition 语音识别 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Speech.Recog…

谓词 lambda bind()

对于许多算法&#xff0c;不想使用默认的运算方式&#xff0c;可以使用它的重载版本&#xff0c;新的参数接收谓词&#xff0c;从而会对序列中的元素调用谓词&#xff0c;元素类型必须能转换为谓词参数的类型 可调用表达式&#xff1a;可以使用&#xff08;&#xff09;调用运…

【音视频】音频重采样

文章目录 前言音频重采样的基本概念音频重采样的原因1. 设备兼容性2. 文件大小和带宽3. 音质优化4. 标准化和规范5. 多媒体同步6. 降低处理负载重采样的注意事项 总结 前言 音频重采样是指将音频文件的采样率转换成另一种采样率的过程。这在音频处理和传输中是一个常见且重要的…

保研面试高频问题——day1

1.你觉得参加建模类的比赛对你大学生活发挥着怎样的作用&#xff1f; 答&#xff1a;感谢老师的提问&#xff0c;参加建模类比赛对大学生活具有显著的积极影响。它不仅锻炼了我的数学建模和计算机编程技能&#xff0c;还提升了我的团队协作和沟通能力。在解决复杂问题的过程中…

mac二进制安装operator-sdk

0. 前置条件 1. 安装go 安装步骤略。 1. 下载operator-sdk源码包 https://github.com/operator-framework/operator-sdk 1.1 选择适合当前go版本的operator版本&#xff0c;在operator-sdk/go.mod文件中可以查看Operator-sdk使用的go版本。 2. 编译 源码包下载后&#x…

2024.7.20 暑期训练记录(6)

CF 1391D - 505&#xff08;思维状压dp&#xff09; 首先简化问题&#xff0c;发现一个矩阵如果要满足条件&#xff0c;那它其中的每一个 2 2 2\times 2 22 的小矩阵都要满足条件&#xff0c;于是很容易发现 4 4 4\times4 44 的矩阵是一定不满足条件的&#xff08;因为是…

C语言航空售票系统

以下是系统部分页面 以下是部分源码&#xff0c;需要源码的私信 #include<stdio.h> #include<stdlib.h> #include<string.h> #define max_user 100 typedef struct ft {char name[50];//名字char start_place[50];//出发地char end_place[50];//目的地char …

kafka-client如何打印连接日志

在Kafka客户端中打印连接日志&#xff0c;通常涉及配置日志框架来捕获和输出Kafka客户端在建立连接过程中的相关信息。由于Kafka客户端使用SLF4J&#xff08;Simple Logging Facade for Java&#xff09;作为日志门面&#xff0c;实际的日志实现&#xff08;如Log4j2、Logback等…

JAVA 异步编程(线程安全)二

1、线程安全 线程安全是指你的代码所在的进程中有多个线程同时运行&#xff0c;而这些线程可能会同时运行这段代码&#xff0c;如果每次运行的代码结果和单线程运行的结果是一样的&#xff0c;且其他变量的值和预期的也是一样的&#xff0c;那么就是线程安全的。 一个类或者程序…

https和http有哪些区别?

在今天的互联网世界中&#xff0c;我们经常听到关于HTTPS和HTTP的术语。它们都是超文本传输协议&#xff08;HTTP&#xff09;的变种&#xff0c;但它们之间存在着重要的区别。本篇博客将深入探讨HTTPS与HTTP之间的差异以及为什么HTTPS在现代网络中变得如此重要。 目录 1. HT…

多线程初阶(二)- 线程安全问题

目录 1.观察count 原因总结 2.解决方案-synchronized关键字 &#xff08;1&#xff09;synchronized的特性 &#xff08;2&#xff09;如何正确使用 语法格式 3.死锁 &#xff08;1&#xff09;造成死锁的情况 &#xff08;2&#xff09;死锁的四个必要条件 4.Java标准…

[C/C++入门][for]22、输出奇偶数之和

复习一下我们前面如何判断奇数 判断一个整数是奇数还是偶数&#xff0c;最常用的方法是利用模运算&#xff08;%&#xff09;。模运算符返回除法的余数。对于任何整数n&#xff0c;当你用n % 2&#xff08;n模2&#xff09;来计算时&#xff0c;如果结果是0&#xff0c;那么n就…