设计模式----装饰器模式

在软件开发过程中,有时想用一些现存的组件。这些组件可能只是完成了一些核心功能。但在不改变其结构的情况下,可以动态地扩展其功能。所有这些都可以釆用装饰器模式来实现。

装饰器模式

允许向一个现有的对象添加新的功能,同时又不改变他的结构(进行扩展)。

装饰器模式的结构与实现

通常情况下,扩展一个类的功能会使用继承方式来实现。但继承具有静态特征,耦合度高,并且随着扩展功能的增多,子类会很膨胀。如果使用组合关系来创建一个包装对象(即装饰对象)来包裹真实对象,并在保持真实对象的类结构不变的前提下,为其提供额外的功能,这就是装饰器模式的目标。

结构

抽象构件(Component):定义一个抽象接口以规范准备接收附加责任的对象
具体构件(Concrete Component):实现抽象构件,通过装饰器角色为其添加一些职责
抽象装饰(Decorator):继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能
具体装饰(Concrete Decorator):实现抽象装饰的相关方法,并给具体构件对象添加附加的责任

装饰器模式UML图

实现

#include <iostream>
#include <string>
using namespace std;

//装饰器模式
class Phone
{
public:
    Phone(){}
    ~Phone(){}
    virtual void showDecorate(){}
};

class iPhone :public Phone
{
private:
    string _name;
public:
    iPhone(string name)
        :_name(name)
    {}
    ~iPhone(){}
    void showDecorate()
    {
        cout << _name << "装饰器" << endl;
    }
};

class NokiaPhone :public Phone
{
private:
    string _name;
public:
    NokiaPhone(string name)
        :_name(name)
    {}
    ~NokiaPhone(){}
    void showDecorate()
    {
        cout << _name << "装饰器" << endl;
    }
};

class DecoratorPhone :public Phone
{
private:
    Phone* m_phone;
public:
    DecoratorPhone(Phone *phone)
        :m_phone(phone)
    {}
    virtual void showDecorate()
    {
        m_phone->showDecorate();
    }
};

class DecoratePhoneA :public DecoratorPhone
{
public:
    DecoratePhoneA(Phone *phone)
        :DecoratorPhone(phone)
    {}
    void showDecorate()
    {
        DecoratorPhone::showDecorate();
        AddDecorate();
    }
private:
    void AddDecorate()
    {
        cout << "增加挂件" << endl;
    }
};

class DecoratePhoneB :public DecoratorPhone
{
public:
    DecoratePhoneB(Phone* phone)
        :DecoratorPhone(phone)
    {}
    void showDecorate()
    {
        DecoratorPhone::showDecorate();
        AddDecorate();
    }
private:
    void AddDecorate()
    {
        cout << "增加屏膜" << endl;
    }
};

void main()
{
    Phone* phone = new NokiaPhone("6300");
    Phone* phoneA = new DecoratePhoneA(phone);
    Phone* phoneB = new DecoratePhoneB(phone);

    phoneA->showDecorate();
    phoneB->showDecorate();
    
    delete phone; phone = NULL;
    delete phoneA; phoneA = NULL;
    delete phoneB; phoneB = NULL;
}

装饰器模式的优缺点

优点:
可以不用修改原有的接口,就可以实现新功能的添加
装饰者可以很方便的转换原有接口中的实现,可以给装饰者指定不同的ConcreteComponent实现不同的功能。
缺点:
复杂性增加,装饰者模式会导致许多小类的产生。

装饰器模式应用场景

前面讲解了关于装饰器模式的结构与特点,下面介绍其适用的应用场景,装饰器模式通常在以下几种情况使用。

当需要给一个现有类添加附加职责,而又不能采用生成子类的方法进行扩充时。例如,该类被隐藏或者该类是终极类或者采用继承方式会产生大量的子类。
当需要通过对现有的一组基本功能进行排列组合而产生非常多的功能时,采用继承关系很难实现,而采用装饰器模式却很好实现。
当对象的功能要求可以动态地添加,也可以再动态地撤销时。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python_可视化_交互_多条线段点击高亮显示

需求 使用matplotlib 绘制折线图 响应鼠标事件 单击折线 线条高亮显示 解决方法: 使用 mplcursors 库, 一句代码可实现. 代码 import matplotlib.pyplot as plt import mplcursors import numpy as np# 生成一些示例数据 x np.linspace(0, 10, 100) y np.sin(x)# 创建绘图…

Linux的gdb调试

文章目录 一、编译有调试信息的目标文件二、启动gdb调试文件1、查看内容list/l&#xff1a;l 文件名:行号/函数名&#xff0c;l 行号/函数名2、打断点b&#xff1a;b文件名:行号/函数名&#xff0c;b 行号/函数名 与 查看断点info/i&#xff1a;info b3、删除断点d&#xff1a;…

基于InternLM和LangChain搭建自己的知识库

背景 LLM存在一定的局限性&#xff0c;如&#xff1a; 知识时效性受限&#xff1a;如何让LLM能够获取最新的知识专业能力有限&#xff1a;如何打造垂直领域的大模型定制化成本高&#xff1a;如何打造个人专属的LLM应用 正文 为了突破LLM的局限性&#xff0c;目前有两种范式…

Python入门学习:if语句与条件控制--and、or、in、not in详解与实践

Python入门学习&#xff1a;if语句与条件控制–and、or、in、not in详解与实践 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&#x1…

Zookeeper启动报错排查

前言&#xff1a;生产linux部署的zookeeper&#xff0c;执行启动脚本后&#xff0c;还是无法使用&#xff0c;故进行重启排查 在zookeeper的bin目录下执行 ./zkServer.sh start-foreground 可实时查看启动日志排查问题 根据上面的日志可以看出&#xff0c;是zoo.cfg配置文件里…

本地快速部署谷歌开放模型Gemma教程(基于LMStudio)

本地快速部署谷歌开放模型Gemma教程&#xff08;基于LMStudio&#xff09; 一、介绍 Gemma二、部署 Gemma2.1 部署工具2.1 部署步骤 三、总结 一、介绍 Gemma Gemma是一系列轻量级、最先进的开放式模型&#xff0c;采用与创建Gemini模型相同的研究和技术而构建。可以直接运行在…

Kafka安全模式之身份认证

一、简介 Kafka作为一个分布式的发布-订阅消息系统&#xff0c;在日常项目中被频繁使用&#xff0c;通常情况下无论是生产者还是消费者只要订阅Topic后&#xff0c;即可进行消息的发送和接收。而kafka在0.9.0.0版本后添加了身份认证和权限控制两种安全服务&#xff0c;本文主要…

10 Redis之SB整合Redis

7. SB整合Redis Spring Boot 中可以直接使用 Jedis 实现对 Redis 的操作&#xff0c;但一般不这样用&#xff0c;而是使用 Redis操作模板 RedisTemplate 类的实例来操作 Redis。 RedisTemplate 类是一个对 Redis 进行操作的模板类。该模板类中具有很多方法&#xff0c;这些方…

stable-diffusion-webui+sadTalker开启GFPGAN as Face enhancer

接上一篇&#xff1a;在autodl搭建stable-diffusion-webuisadTalker-CSDN博客 要开启sadTalker gfpgan as face enhancer&#xff0c; 需要将 1. stable-diffusion-webui/extensions/SadTalker/gfpgan/weights 目录下的文件拷贝到 :~/autodl-tmp/models/GFPGAN/目录下 2.将G…

杰理-按键多次按下识别多击

杰理-按键多次按下识别多击 #define ALL_KEY_EVENT_CLICK_ONLY 0 //是否全部按键只响应单击事件

ansys计算结果保存

100 &#xff1a; 图片质量 ON&#xff1a;白色背景 右键设置保存图片的背景格式&#xff1a;

基于Python网络爬虫的IT招聘就业岗位数据分析可视化推荐系统

文章目录 基于Python网络爬虫的IT招聘就业岗位数据分析可视化推荐系统项目概述招聘岗位数据爬虫分析系统展示用户注册登录系统首页IT招聘数据开发岗-javaIT招聘数据开发岗-PythonIT招聘数据开发岗-AndroidIT招聘数据开发岗-其它招聘岗位数据分析算法方面运维方面测试方面招聘岗…

redis是单线程,为什么这么快?

redis是纯内存操作&#xff0c;C语言编写&#xff0c;执行速度非常快。 采用单线程&#xff0c;避免不必要的上下文切换&#xff0c;不用考虑线程安全问题。 采用I/O多路复用模型&#xff0c;非阻塞I/O。 例如&#xff1a;bgsave和bgrewriteaof都是在后台执行操作&#xff0…

农业四情监测设备为什么符合高标准农田建设

TH-Q3随着科技的不断进步&#xff0c;智慧农业正逐渐成为现代农业发展的重要方向。其中&#xff0c;农业四情监测系统以其独特的功能和优势&#xff0c;在高标准农田建设中发挥着越来越重要的作用。 一、农业四情监测系统的概念及功能 农业四情监测系统&#xff0c;顾名思义&am…

C++之queue和dqueue

1、queue queue&#xff08;队列&#xff09;&#xff0c;一种数据结构&#xff0c;可以让某些数据结构的操作变得简单。队列&#xff08;queue&#xff09;最大的特点就是先进先出。就是说先放入queue容器的元素一定是要先出队列之后&#xff0c;比它后进入队列的元素才能够出…

算法沉淀——动态规划之回文串问题(上)(leetcode真题剖析)

算法沉淀——动态规划之回文串问题 01.回文子串02.最长回文子串03.分割回文串 IV04.分割回文串 II05.最长回文子序列06.让字符串成为回文串的最少插入次数 01.回文子串 题目链接&#xff1a;https://leetcode.cn/problems/palindromic-substrings/ 给你一个字符串 s &#xf…

08 MyBatis之查询专题(返回对象/Map/List封装Map/Map封装Map)+列名与属性名映射的三种方法

准备: INSERT INTO t_car (id, car_num, brand, guide_price, produce_time, car_type) VALUES (165, 6666, 丰田霸道, 32.00, 2020-11-11, 燃油车); INSERT INTO t_car (id, car_num, brand, guide_price, produce_time, car_type) VALUES (166, 1202, 大众速腾, 30.00, 2020…

IntelliJ IDEA 2023:创新不止步,开发更自由 mac/win版

IntelliJ IDEA 2023激活版是一款强大而智能的集成开发环境(IDE)&#xff0c;为开发者提供了一系列先进的功能和工具&#xff0c;帮助他们更高效地编写、调试和测试代码。 IntelliJ IDEA 2023 软件获取 IntelliJ IDEA 2023继承了其前代版本的优秀基因&#xff0c;并在此基础上进…

基于AMDGPU-ROCm的深度学习环境搭建

在风起云涌的AI江湖&#xff0c;NVIDIA凭借其CUDA生态和优秀的硬件大杀四方&#xff0c;立下赫赫战功&#xff0c;而另一家公司AMD也不甘示弱&#xff0c;带着他的生态解决方案ROCm开始了与不世出的NVIDA的正面硬钢&#xff0c;"ROCm is the answer to CUDA", AMD官网…

177基于matlab的基于S函数的变步长自适应滤波算法

基于matlab的基于S函数的变步长自适应滤波算法&#xff0c;比传统的算法收敛速度更快。传统的LMS算法中&#xff0c;权值向量实时地被更新。这些更新可能会由于噪声的影响而变得不稳定。SVSLMS算法是一种改进的LMS算法&#xff0c;它采用了矢量处理的概念&#xff0c;利用信号和…