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

1.概述

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

2.结构

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

3.实现  

3.1 实例类比

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

3.2 具体实现 
cpp 复制代码
#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 应用场景

  • 用于扩展一个类的功能或者给一个类添加附加职责
  • 不能通过继承的方式对现有系统的类进行功能扩展时,可以考虑使用装饰模式进行功能扩展。
  • 不能使用继承方式的原因是系统现有大量独立的类,如果通过继承方式进行扩展,可能会出现类爆炸;
相关推荐
路溪非溪2 小时前
python标准库使用总结
开发语言·python
青少儿编程课堂3 小时前
蓝桥杯·全国青少年信息素养大赛·电子学会Python/C++考级:折半搜索优化子集枚举(Meet in the Middle)解析
c++·python·算法·bfs·信息学竞赛
SomeOtherTime4 小时前
Rust 面向对象介绍(AI回答)
开发语言·python·rust
wo_jack4 小时前
C++ 入门笔记(十七):list 入门 —— 为什么 list 不能 sort?
数据结构·c++·面试·stl·list
zh_xuan4 小时前
kotlin常见面试题
开发语言·kotlin·面试题
青少儿编程课堂5 小时前
蓝桥杯青少组图形化 + 全国青少年信息素养大赛 + 电子学会Scratch考级:校园连连看解析
c++·python·算法·bfs·信息学竞赛
草莓熊Lotso6 小时前
【C++ 基于微服务的即时通讯系统】文件存储子服务实战:UUID生成、文件IO封装与全接口单元测试
开发语言·网络·数据库·c++·微服务·架构·单元测试
huaqianzkh7 小时前
WinForm C#:循环修改控件UI闪烁卡顿?SuspendLayout / ResumeLayout 与 BeginUpdate 优化
开发语言·ui·c#
沐晓时光17 小时前
C语言入门,内存函数知识讲解
c语言·开发语言
David猪大卫1 天前
【C++修炼】map 和 set 的使用
c语言·开发语言·数据结构·c++·经验分享·笔记·学习