装饰模式(大话设计模式)C/C++版本

news2024/9/23 21:32:20

装饰模式

在这里插入图片描述

需求分析:

1. 选择服饰 => 服饰类
2. 输出结果
对象是人 => 人类

将Person类中一大堆服饰功能抽象出服饰类,然后通过Person类聚合服饰属性,通过Set行为来设置服饰属性,最后达到灵活打扮的效果

装饰模式
动态地给一个对象添加一些额外的职责,就增加功能来说 装饰模式比生成子类更为灵活
1. 装饰对象的实现和如何使用该对象分离开了,每个装饰对象只关心自己的功能,不需要关心如何被添加到对象链当中。
2. 装饰模式是结构性的模式,将所需要的功能按正确的顺序串联起来进行控制

使用场景

之前:旧类新增功能,向旧类添加新的属性和新的行为,增加了类的复杂度,破坏了开闭原则;
现在:装饰功能作为一个单独类存在,就可以在运行时灵活的增加到旧类中。

总结:
将类中的装饰功能从类中移除(简化类,避免类的膨胀),具体装饰类通过聚合父类来灵活增加父类功能;
有效的将一个大类的核心职责和装饰功能区分开了。

C++

#include <iostream>
using namespace std;

// ConcreteComponent即Component
class Person
{
protected:
    string name;

public:
    Person(){};
    Person(string name) : name(name){};
    virtual void show()
    {
        cout << "装扮的" << name << endl;
    }
};

// Decorator类(装饰类),继承了Persson类,并且弱拥有Person类
class Finery : public Person
{
protected:
    Person *component;

public:
    Finery() : component(nullptr) {}
    void Decorate(Person *component)
    {
        this->component = component;
    }
    virtual void show()
    {
        if (component)
            component->show();
    }
};

// ConcreteDecorator类
class TShirts : public Finery
{
public:
    virtual ~TShirts() {}
    virtual void show()
    {
        cout << "Tshirt" << endl;
        Finery::show();
    }
};

// ConcreteDecorator类
class Jeans : public Finery
{
public:
    virtual ~Jeans() {}
    virtual void show()
    {
        cout << "Jeans" << endl;
        Finery::show();
    }
};

int main()
{
    Person *p = new Person("小菜");
    TShirts *oTShirt = new TShirts();
    Jeans *oJeans = new Jeans();
    oTShirt->Decorate(p);
    oJeans->Decorate(oTShirt);
    oJeans->show();

    delete p;
    p = nullptr;
    delete oTShirt;
    oTShirt = nullptr;
    delete oJeans;
    oJeans = nullptr;
    return 0;
}

C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Component 类型定义
typedef struct Person
{
    char *name;
    void (*show)(struct Person *);
} Person;

// Decorator 类型定义
typedef struct Finery
{
    Person base;
    Person *component;
} Finery;

// ConcreteDecorator 类型定义
typedef struct TShirts
{
    Finery base;
} TShirts;

typedef struct Jeans
{
    Finery base;
} Jeans;

// 实现 Finery 的 show 方法
void finery_show(Finery *self)
{
    if (self->component && self->component->show)
    {
        self->component->show(self->component);
    }
}

// 实现 TShirts 的 show 方法
void tshirts_show(TShirts *self)
{
    printf("Tshirt\n");
    finery_show((Finery *)self);
}

// 实现 Jeans 的 show 方法
void jeans_show(Jeans *self)
{
    printf("Jeans\n");
    finery_show((Finery *)self);
}

// Finery 构造函数
Finery *finery_new(Person *component)
{
    Finery *self = malloc(sizeof(Finery));
    self->base.show = finery_show;
    self->component = component;
    return self;
}

// TShirts 构造函数
TShirts *tshirts_new(Finery *component)
{
    TShirts *self = malloc(sizeof(TShirts));
    self->base.base.show = tshirts_show;
    self->base.component = component;
    return self;
}

// Jeans 构造函数
Jeans *jeans_new(Finery *component)
{
    Jeans *self = malloc(sizeof(Jeans));
    self->base.base.show = jeans_show;
    self->base.component = component;
    return self;
}

// ConcreteComponent 方法实现
void person_show(Person *self)
{
    printf("装扮的 %s\n", self->name);
}

int main()
{
    Person *p = malloc(sizeof(Person));
    p->name = strdup("小菜");
    p->show = person_show;

    Finery *oTShirt = finery_new(p);
    TShirts *tshirts = tshirts_new(oTShirt);

    Finery *oJeans = finery_new(tshirts);
    Jeans *jeans = jeans_new(oJeans);

    jeans->base.base.show(jeans);

    free(p->name);
    free(p);
    free(tshirts);
    free(oTShirt);
    free(jeans);
    free(oJeans);
    return 0;
}

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

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

相关文章

如何查找电脑的MAC地址

一. 什么是mac地址&#xff1f; mac地址本质上帮助我们连接到我们遇到的大多数本地网络。每个网络适配器通常由网络接口​​控制器(NIC) 制造商分配一个唯一的 mac 地址。 二. 如何查找mac地址 1.点击网络和Internet设置 2.点击WLAN点击硬件属性 3.即可查看mac地址

css基础(1)

CSS CCS Syntax CSS 规则由选择器和声明块组成。 CSS选择器 CSS选择器用于查找想要设置样式的HTML元素 一般选择器分为五类 Simple selectors (select elements based on name, id, class) 简单选择器&#xff08;根据名称、id、类选择元素&#xff09; //页面上的所有 …

【漏洞复现】某赛通 电子文档安全管理系统 多个接口存在远程命令执行漏洞

免责声明&#xff1a; 本文内容旨在提供有关特定漏洞或安全漏洞的信息&#xff0c;以帮助用户更好地了解可能存在的风险。公布此类信息的目的在于促进网络安全意识和技术进步&#xff0c;并非出于任何恶意目的。阅读者应该明白&#xff0c;在利用本文提到的漏洞信息或进行相关测…

WPF学习(3) -- 控件模板

一、操作过程 二、代码 <Window x:Class"学习.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d"http://schemas.microsoft.com/expressio…

Linux系统编程-线程同步详解

线程同步是指多个线程协调工作&#xff0c;以便在共享资源的访问和操作过程中保持数据一致性和正确性。在多线程环境中&#xff0c;线程是并发执行的&#xff0c;因此如果多个线程同时访问和修改共享资源&#xff0c;可能会导致数据不一致、竞态条件&#xff08;race condition…

Python3.6.6 OpenCV 将视频中人物标记或者打马赛克或加图片并保存为不同格式

1、轻松识别视频人物并做出标记 需安装face_recongnition与dlib&#xff0c;过程有点困难&#xff0c;还请网上查找方法 import face_recognition import cv2 #镜像源 -i https://pypi.mirrors.ustc.edu.cn/simple # 加载视频 video_file E:\\videos\\1.mp4 video_capture …

taocms 3.0.1 本地文件泄露漏洞(CVE-2021-44983)

前言 CVE-2021-44983 是一个影响 taoCMS 3.0.1 的远程代码执行&#xff08;RCE&#xff09;漏洞。该漏洞允许攻击者通过上传恶意文件并在服务器上执行任意代码来利用这一安全缺陷。 漏洞描述 taoCMS 是一个内容管理系统&#xff08;CMS&#xff09;&#xff0c;用于创建和管…

IDEA中Git常用操作及Git存储原理

Git简介与使用 Intro Git is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency. Git是一款分布式版本控制系统&#xff08;VSC&#xff09;&#xff0c;是团队合作开发…

树莓派pico入坑笔记,esp01/01s使用

目录 关于树莓派pico和circuitpython的更多玩法&#xff0c;请看树莓派pico专栏 说明 关于at指令 WiFi的at指令 UDP的at指令 样例程序 调试助手端输入指令 sta端程序 效果 进阶使用 库函数说明 样例代码 关于树莓派pico和circuitpython的更多玩法&#xff0c;请看树…

【Superset】dashboard 自定义URL

URL设置 在发布仪表盘&#xff08;dashboard&#xff09;后&#xff0c;可以通过修改看板属性中的SLUG等&#xff0c;生成url 举例&#xff1a; http://localhost:8090/superset/dashboard/test/ 参数设置 以下 URL 参数可用于修改仪表板的呈现方式&#xff1a;此处参考了官…

Linux 下 redis 集群部署

目录 1. redis下载 2. 环境准备 3. redis部署 3.1 修改系统配置文件 3.2 开放端口 3.3 安装 redis 3.4 验证 本文将以三台服务器为例&#xff0c;介绍在 linux 系统下redis的部署方式。 1. redis下载 下载地址&#xff1a;Index of /releases/ 选择需要的介质下载&am…

[NSSRound#4 SWPU]1zweb

非预期解&#xff1a; 输入/flag&#xff0c;点击查看 预期解&#xff1a; upload.php <?php if ($_FILES["file"]["error"] > 0){echo "上传异常"; } else{$allowedExts array("gif", "jpeg", "jpg"…

GuLi商城-商品服务-API-品牌管理-JSR303自定义校验注解

自定义注解规则: 可以参考@NotNull注解 package com.nanjing.common.valid;import javax.validation.Constraint; import javax.validation.Payload; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target;i…

数据结构(空间复杂度介绍)超详细!!!

1. 数据结构前言 1.1 数据结构 数据结构是计算机存储、组织数据的形式&#xff0c;指相互之间存在一种或多种特定关系的数据元素的集合 1.2 算法 算法&#xff1a;良好的计算过程&#xff0c;它取一个或一组的值为输入&#xff0c;并产生出一个或一组的值作为输出。即算法经…

react的解构赋值

我最近在用react讨生活。我的感觉&#xff0c;react开发效率不高。这当然应该是我还不熟悉react的缘故。但是&#xff0c;在阅读react代码过程中&#xff0c;其中一个容易困惑的地方是它到处充斥着的解构赋值。当然了&#xff0c;解构赋值并不是React特有的功能&#xff0c;而是…

多表联合的查询(实例)、对于前端返回数据有很多表,可以分开操作、debug调试教程

2024.7.13 一、 对于多表的更深层的认识1. 认识2. 多表联合查询的列子&#xff1a;3. 对于多表查询的进一步认识4. 在实现功能的时候&#xff0c;原本对于省市县这样的表&#xff0c;对于项目的要求&#xff0c;是直接全部查询出来&#xff0c;然后开始使用&#xff0c;但我想着…

在 CentOS 6.4 VPS 上安装和保护 phpMyAdmin 的方法

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 简介 许多网站和应用程序需要数据库来存储和管理大量信息。MySQL 和 MariaDB 是流行的数据库管理系统&#xff0c;因为它们具有灵活性、…

redisTemplate报错为nil,通过redis-cli查看前缀有乱码

public void set(String key, String value, long timeout) {redisTemplate.opsForValue().set(key, value, timeout, TimeUnit.SECONDS);} 改完之后 public void set(String key, String value, long timeout) {redisTemplate.setKeySerializer(new StringRedisSerializer()…

前端工程化10-webpack静态的模块化打包工具之各种loader处理器

9.1、案例编写 我们创建一个component.js 通过JavaScript创建了一个元素&#xff0c;并且希望给它设置一些样式&#xff1b; 我们自己写的css,要把他加入到Webpack的图结构当中&#xff0c;这样才能被webpack检测到进行打包&#xff0c; style.css–>div_cn.js–>main…

万界星空科技MES系统:食品加工安全的实时监控与智能管理

万界星空科技MES系统通过集成多种技术和功能&#xff0c;能够实时监控食品加工过程中各环节的安全风险。以下是对该系统如何实现实时监控的详细分析&#xff1a; 一、集成传感器和数据分析技术 万界星空科技MES系统利用集成的传感器和数据分析技术&#xff0c;实时监控生产过程…