6. 装饰器

news2024/12/23 19:22:57

UML

在这里插入图片描述

  • 聚合(Aggregation)关系:大雁和雁群,上图中空心菱形+箭头表示聚合关系
  • 组合(Composition)关系:大雁和翅膀 ,实心菱形+箭头表示组合(Composition)关系

测试代码

#include <iostream>
#include <stdio.h>
#include <mutex>//锁头文件
 
using namespace std;
 
class Component{
public:
    virtual void Operation() = 0;
    virtual ~Component(){
 
    }
};
class ConcreteComponent:public Component
{
public:
    void Operation(){
        cout << "ConcreteComponent" << endl;
    }
};
 
class Decorator:public Component{
protected:
    Component *component = nullptr;
public:
    void SetComponent(Component *_component){
        this->component = _component;
    }
    void Operation(){
        if(component != nullptr){
            component->Operation();
        }
    }
};
class ConcreteDecoratorA:public Decorator
{
private:
    string addedState;
public:
    void Operation(){
        Decorator::Operation();
        addedState = "new State";
        cout << "具体装饰对象A的操作" << endl;
    }
};
 
class ConcreteDecoratorB:public Decorator
{
public:
    void Operation(){
        Decorator::Operation();
        AddedBehavior();
        cout << "具体装饰对象B的操作" << endl;
    }
private:
    void AddedBehavior()
    {
        cout << "AddedBehavior" << endl;
    }
};
int main(void)
{
    ConcreteComponent *c = new ConcreteComponent();
    ConcreteDecoratorA *d1 = new ConcreteDecoratorA();
    ConcreteDecoratorB *d2 = new ConcreteDecoratorB();
    d1->SetComponent(c);
    d2->SetComponent(d1);
    d2->Operation();
    cout << "--endl--" << endl;
    return 0;
}
 

输出

ConcreteComponent
具体装饰对象A的操作
AddedBehavior
具体装饰对象B的操作
--endl--

装饰模式是利用SetComponent来对对象进行包装的。这样每个装饰对象的实现就和如何使用这个对象分离开了,每个装饰对象只关心自己的功能,不需要关心如何被添加到对象链当中

装饰模式变身

如果只有一个ConcreteComponent类而没有抽象的Component类,那么Decorator类可以是ConcreteComponent的一个子类。同样道理,如果只有一个ConcreteDecorator类,那么就没有必要建立一个单独的Decorator类,而可以把Decorator和ConcreteDecorator的责任合并成一个类

根据这段文字的描述,UML结构图变身后的形态
在这里插入图片描述
C++改写后的UML图和代码
在这里插入图片描述

代码:

#include <iostream>
#include <stdio.h>
#include <mutex>//锁头文件
 
using namespace std;
 
//“Person”类(ConcreteComponent)
class Person{
public:
    Person(){
    }
    Person(string _name):name(_name){
    }
    virtual void Show(){
        cout << "装扮的:" << this->name << endl;
    }
private:
    string name;
};
//服饰类(Decorator)
class Finery:public Person
{
public:
 
    Person *component = nullptr;
    void Decorate(Person *_component){
        this->component = _component;
    }
    virtual void Show(){
        if(component != nullptr){
            component->Show();
        }
    }
};
class fengyi:public Finery
{
public:
    virtual void Show(){
        cout << "风衣" << endl;
        Finery::Show();
    }
};
 
class yundongxie:public Finery
{
public:
    virtual void Show(){
        cout << "运动鞋" << endl;
        Finery::Show();
    }
};
class mojing:public Finery
{
public:
    void Show(){
        cout << "墨镜" << endl;
        Finery::Show();
    }
};
class kouzhao:public Finery
{
public:
    void Show(){
        cout << "口罩" << endl;
        Finery::Show();
    }
};
class xifu:public Finery
{
public:
    void Show(){
        cout << "西服" << endl;
        Finery::Show();
    }
};
int main(void)
{
    cout << "装扮1" << endl;
    Person *p1 = new Person("lkmao");
    fengyi *fy = new fengyi();
    yundongxie *ydx = new yundongxie();
    fy->Decorate(p1);
    ydx->Decorate(fy);
    ydx->Show();
 
    cout << endl << "装扮2" << endl;
    Person *p2 = new Person("laoliu");
    mojing *mj = new mojing();
    kouzhao *kz = new kouzhao();
    xifu *xf = new xifu();
    mj->Decorate(p2);
    kz->Decorate(mj);
    xf->Decorate(kz);
    xf->Show();
 
    cout << "--endl--" << endl;
    return 0;
} 

输出

装扮1
运动鞋
风衣
装扮的:lkmao
 
装扮2
西服
口罩
墨镜
装扮的:laoliu
--endl--

参考:https://blog.csdn.net/yueni_zhao/article/details/128946954

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

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

相关文章

IDEA2023.2.1中创建第一个Tomcat的web项目

首先&#xff0c;创建一个普通的java项目。点击【file】-【new】-【project】 创建一个TomcatDemo项目 创建如下图 添加web部门。点击【file】-【project structure】 选择【modules】-选中项目“TomcatDemo” 点击项目名上的加号【】&#xff0c;添加【web】模块 我们就会发现…

【微信小程序】文章设置

设置基本字体样式&#xff1a;行高、首行缩进 font-size: 32rpx;line-height: 1.6em;text-indent: 2em;padding: 20rpx 0;border-bottom: 1px dashed var(--themColor); 两端对齐 text-align: justify; css文字两行或者几行显示省略号 css文字两行或者几行显示省略号_css…

FPGA project : dht11 温湿度传感器

没有硬件&#xff0c;过几天上板测试。 module dht11(input wire sys_clk ,input wire sys_rst_n ,input wire key ,inout wire dht11 ,output wire ds ,output wire …

72、Spring Data JPA 的 Specification 动态查询

Specification&#xff1a;规范、规格 ★ Specification查询 它也是Spring Data提供的查询——是对JPA本身 Criteria 动态查询 的包装。▲ 为何要有动态查询 页面上常常会让用户添加不同的查询条件&#xff0c;程序就需要根据用户输入的条件&#xff0c;动态地组合不同的查询…

外星人入侵游戏-(创新版)

&#x1f308;write in front&#x1f308; &#x1f9f8;大家好&#xff0c;我是Aileen&#x1f9f8;.希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流. &#x1f194;本文由Aileen_0v0&#x1f9f8; 原创 CSDN首发&#x1f412; 如…

不同类型程序的句柄研究

先做一个winform程序&#xff1b;随便放几个控件&#xff1b; 用窗口句柄查看工具看一下&#xff1b;form和上面的每个控件都有一个句柄&#xff1b; 然后看一下记事本&#xff1b;记事本一共包含三个控件&#xff0c;各自有句柄&#xff1b; 这工具的使用是把右下角图标拖到要…

服务器迁移:无缝过渡指南

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

基于SSM+Vue的高校实验室管理系统的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用Vue技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

线程的方法(未完成)

线程的方法 1、sleep(long millis) 线程休眠&#xff1a;让执行的线程暂停一段时间&#xff0c;进入计时等待状态。 static void sleep(long millis):调用此方法后&#xff0c;当前线程放弃 CPU 资源&#xff0c;在指定的时间内&#xff0c;sleep 所在的线程不会获得可运行的机…

如何使用Java语言判断出geek是字符串参数类型,888是整数参数类型,[hello,world]是数组参数类型,2.5是双精度浮点数类型?

如何使用Java语言判断出geek是字符串参数类型&#xff0c;888是整数参数类型&#xff0c;[hello,world]是数组参数类型&#xff0c;2.5是双精度浮点数类型&#xff1f; Java是一种静态类型的编程语言&#xff0c;这意味着我们需要在编译时为变量指定具体的类型。但是&#xff…

web应用及微信小程序版本更新检测方案实践

背景&#xff1a; 随着项目体量越来越大&#xff0c;用户群体越来越多&#xff0c;用户的声音也越来越明显&#xff1b;关于应用发版之后用户无感知&#xff0c;导致用户用的是仍然还是老版本功能&#xff0c;除非用户手动刷新&#xff0c;否则体验不到最新的功能&#xff1b;这…

ICCV 2023 | MPI-Flow:从单视角构建的多平面图像中学习光流

ICCV 2023 | MPI-Flow&#xff1a;从单视角构建的多平面图像中学习光流 引言&#xff1a;主要贡献&#xff1a;Motivation&#xff1a;算法细节&#xff1a;Optical Flow Data GenerationIndependent Object MotionsDepth-Aware Inpainting 实验结果&#xff1a; 来源&#xff…

QT:使用分组框、单选按钮、普通按钮、标签、行编辑器、垂直分布、水平分布做一个小项目

widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QRadioButton> //单选按钮 #include <QGroupBox> //分组框 #include <QHBoxLayout> //水平布局 #include <QVBoxLayout> //垂直布局 #include <QPushButton>…

MFC主框架和视类PreCreateWindow()函数学习

在VC生成的单文档应用程序中&#xff0c;主框架类和视类均具有PreCreateWindow函数&#xff1b; 从名字可知&#xff0c;可在此函数中添加一些代码&#xff0c;来控制窗口显示后的效果&#xff1b; 并且它有注释说明&#xff0c; Modify the Window class or styles here by…

RHCSA 重定向、vim练习题

1.重定向练习题 (1)新建一个文件redirect.txt&#xff0c;并在其中写入20210804RHCSA,保存并退出 先输入命令 [rootlocalhost ~]# vim redirect.txt进入vim编辑器后&#xff0c;按快捷键“i”进入编辑模式&#xff0c;再写入数据&#xff0c;写完之后按“esc"键退出编辑…

python 采用selenium+cookies 获取登录后的网页

百度网页由于需要登陆手机短信验证。比较麻烦 这里我采用先人工登录百度账号&#xff0c;然后将百度账号的相关cookies保存下来 然后采用selenium动态登录网页 整体代码如下 from selenium import webdriverimport timeoptions webdriver.ChromeOptions()options.add_argu…

LLM 08-分布式训练

LLM 08-分布式训练 8.1 为什么分布式训练越来越流行 近年来&#xff0c;深度学习被广泛应用到各个领域&#xff0c;包括计算机视觉、语言理解、语音识别、广告推荐等。在这些不同的领域中&#xff0c;一个共同的特点就是模型规模越来越大&#xff0c;比如 GPT-3 模型的参数量达…

华为云云耀云服务器L实例评测|基于L实例使用Docker部署MySQL服务并连接MySQL—phpMyAdmin管理工具

文章目录 一、云耀云服务器产品优势1、智能不卡顿2、价优随心用3、上手更简单4、管理更省心 二、远程连接云耀云服务器L实例三、安装Docker、docker-compse1、docker安装2、docker-compose安装 四、方法① 使用Docker安装部署MySQL服务五、方法② 使用docker-compse安装部署MyS…

2023年 python结合excel实现快速画图(零基础快速入门)

目录 1.适用人群 2.环境配置 3.基本用法 3.1 数据读取 3.2 数据分析 3.3 数据组装 3.4 制表&#xff1a; 4.快速提升 5.效果展示 1.适用人群 电脑有python环境&#xff0c;会python基本使用&#xff0c;需要短时间内完成大量画图任务的数据分析的人群。&#xff08;有…

AlexNet——训练花数据集

目录 一、网络结构 二、创新点分析 三、知识点 1. nn.ReLU(inplace) 2. os.getcwd与os.path.abspath 3. 使用torchvision下的datasets包 4. items()与dict()用法 5. json文件 6. tqdm 7. net.train()与net.val() 四、代码 AlexNet是由Alex Krizhevsky、Ilya S…