装饰器模式【结构型模式C++】

embedded/2024/10/21 5:24:21/

1.概述

  装饰器模式是一种结构型设计模式, 允许你通过将对象放入包含行为的特殊封装对象中来为原对象绑定新的行为。

2.结构

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

3.实现  

3.1 实例类比

   以对新买的手机为例,当买了一个手机,一般都会贴保护膜,加装手机壳,有的还会加装各类挂失。下面是实现此过程的类图:

3.2 具体实现 
#include <iostream>
#include <string>
#include<vector>using namespace std;//手机抽象类	
class Phone
{
public:virtual void Do() = 0;
};//实现抽象接口
class Huawei:public Phone
{void Do()override{cout << "对华为手机开始装饰"<< endl;}
};// 装饰抽象角色——继承抽象构件角色,包含一个抽象构件角色对象的实例	
class Decorator :public Phone
{
protected:Phone *phone_;public:Decorator(Phone* phone):phone_(phone){}void Do(){if (phone_ != nullptr){phone_->Do();}}
};//具体装饰角色——手机贴上保护膜class Protectorfilm :public Decorator
{
public:Protectorfilm(Phone* phone) : Decorator(phone) {}void Do(){phone_->Do();Addfilm();}void Addfilm(){cout << "手机贴保护膜" << endl;}
};//具体装饰角色——手机保护壳
class Shell :public Decorator
{
public:Shell(Phone* phone) : Decorator(phone) {}void Do(){phone_->Do();AddShell();}void AddShell(){cout << "手机安装保护壳" << endl;}
};//具体装饰角色——手机挂饰	
class Accessory :public Decorator
{
public:Accessory(Phone* phone) : Decorator(phone) { }void Do(){phone_->Do();AddAccessory();}void AddAccessory(){cout << "手机安装挂件" << endl;		}
};int main()
{cout << "===装饰模式===" << endl;//现在获得了一个手机Phone *phone = new Huawei();//裸机一个,先贴保护膜Decorator*protectorfilm = new Protectorfilm(phone);protectorfilm->Do();cout << "=======================" << endl;//再加个保护外壳Decorator *shell = new Shell(protectorfilm);shell->Do();cout << "=======================" << endl;//最后加装挂件Decorator *accessory = new Accessory(shell);accessory->Do();cout << "=======================" << endl;
}

3.3运行结果 

4.装饰器模式优缺点

  优点:

  1. 装饰模式和继承关系的目的都是拓展对象的功能,但是装饰模式可以提供比继承更多的灵活性。装饰模式允许系统动态的决定“贴上”一个需要的“装饰”,或者出掉一个不需要的“装饰”,继承关系不同,继承是静态的,它在系统运行前就决定了。
  2.  通过使用不同具体的装饰类以及这些装饰类的组合,可以创造出很多不同行为的组合。
  3. 比继承更多的灵活性,每一种不同的组合均需要事先通过子类的继承方式设计好。

     缺点:

  1. 会产生比继承关系更多的对象。使得查错变得困难,特别是这些对象看上去都很相像。 

5 应用场景

  • 用于扩展一个类的功能或者给一个类添加附加职责
  • 不能通过继承的方式对现有系统的类进行功能扩展时,可以考虑使用装饰模式进行功能扩展。
  • 不能使用继承方式的原因是系统现有大量独立的类,如果通过继承方式进行扩展,可能会出现类爆炸;

http://www.ppmy.cn/embedded/23318.html

相关文章

git使用

从远程同步到本地&#xff1a; 1、git clone http://gitlab.icinfo.co/data/abragent.git 2、输入用户名&#xff0c;密码&#xff1a;从这里获取name和acess_token 查看所有远程分支&#xff1a;如果您想查看远程仓库中所有的分支&#xff08;而不只是默认的origin&#xff0…

爱某查APP - Abtk

⚠️前言⚠️ 本文仅用于学术交流。 学习探讨逆向知识&#xff0c;欢迎私信共享学习心得。 如有侵权&#xff0c;联系博主删除。 请勿商用&#xff0c;否则后果自负。 接口网址 aHR0cHM6Ly9haXFpY2hhLmJhaWR1LmNvbS9hcHAvYWR2YW5jZUZpbHRlckFqYXg 加密位置分析 app版本&a…

sqlalchemy单条记录查询函数对比

sqlalchemy有哪些单条记录查询函数 first()one()scalar() first函数 语法 session.filter(数据模型类名.字段名"xxx").first()first函数特点 结果可以使用多条数据或者一条数据&#xff0c;但是结果不能为空&#xff0c;否则会报错。 one函数 语法 session.f…

C语言求 MD5 值

MD5值常被用于验证数据的完整性&#xff0c;嵌入式开发时经常用到。md5sum命令可以求MD5码&#xff0c;下面介绍如何用C语言实现MD5功能。 一、求字符串MD5值 1、md5sum命令 $ echo -n "12345678" | md5sum //获取"12345678"字符串的md5值 结果&…

30 OpenCV 点多边形测试

文章目录 点多边形测试pointPolygonTest示例 点多边形测试 pointPolygonTest pointPolygonTest( InputArray contour,// 输入的轮廓 Point2f pt, // 测试点 bool measureDist // 是否返回距离值&#xff0c;如果是false&#xff0c;1表示在内面&#xff0c;0表示在边界上&a…

LeetCode 2739. 总行驶距离

题目链接https://leetcode.cn/problems/total-distance-traveled/?envTypedaily-question&envId2024-04-25 简单题&#xff0c;看代码思考一下即可理解 class Solution {public int distanceTraveled(int mainTank, int additionalTank) {int res 0;while (mainTank >…

【Transformer原理解析】

Transformer是一种基于自注意力机制&#xff08;Self-Attention Mechanism&#xff09;的深度学习模型&#xff0c;它在自然语言处理&#xff08;NLP&#xff09;领域取得了显著的成就&#xff0c;特别是在机器翻译任务中。以下是Transformer原理的简要介绍以及使用PyTorch实现…

Docker-compose的介绍与用法

Docker-compose Docker Compose 是一个开源的容器编排工具&#xff0c;由 Docker 官方开发。它允许开发者定义一个或多个 Docker 容器作为单个服务&#xff0c;并将这些服务组合成一个项目。这些定义被保存在一个 YAML 文件中&#xff0c;称为 docker-compose.yml。 使用 Dock…