当前位置: 首页 > article >正文

重温设计模式----装饰模式

文章目录

    • 装饰模式定义
    • UML 图
    • 其主要优点包括:
    • 装饰模式的主要角色有:
    • C++ 代码示例
    • 总结

装饰模式定义

动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式必生成子类更加灵活

装饰模式(Decorator Pattern)属于结构型设计模式,它允许向一个现有的对象添加新的功能,同时又不改变其结构。这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

UML 图

在这里插入图片描述

其主要优点包括:

比继承更灵活:继承是在编译时静态决定的,而装饰模式可以在运行时动态地给对象添加职责,更加灵活地扩展功能。
可以对一个对象多次装饰:能够按照需要多次用不同的装饰类去修饰同一个对象,层层叠加功能。
符合开闭原则:对扩展开放,对修改关闭。可以在不修改原有代码的基础上添加新的装饰功能。

装饰模式的主要角色有:

抽象构件(Component):定义一个对象接口,可以给这些对象动态添加职责。
具体构件(ConcreteComponent):实现了抽象构件接口,是被装饰的原始对象。
抽象装饰类(Decorator):继承自抽象构件,并且包含一个指向抽象构件的指针,其目的是为了能包裹具体构件以及其他装饰类,同时也定义了与抽象构件一致的接口。
具体装饰类(ConcreteDecorator):实现抽象装饰类,负责给构件对象添加新的职责。

C++ 代码示例

以下是一个简单的用 C++ 实现装饰模式的代码示例,模拟给一个简单图形绘制添加不同装饰效果的场景:

#include <iostream>
#include <string>
#include<Windows.h>
// 抽象构件
class Shape
{
public:
	virtual void draw() = 0;
	virtual ~Shape() {}
};

// 具体构件,比如这里的圆形
class Circle : public Shape
{
public:
	void draw() override
	{
		std::cout << "Drawing a circle" << std::endl;
	}
};

// 抽象装饰类,继承自抽象构件
class ShapeDecorator : public Shape
{
protected:
	Shape* decoratedShape;
public:
	ShapeDecorator(Shape* shape) : decoratedShape(shape) {}
	void draw() override
	{
		if (decoratedShape)
		{
			decoratedShape->draw();
		}
	}
};

// 具体装饰类,比如添加红色边框装饰
class RedBorderDecorator : public ShapeDecorator
{
public:
	RedBorderDecorator(Shape* shape) : ShapeDecorator(shape) {}
	void draw() override 
	{
		ShapeDecorator::draw();
		addRedBorder();
	}
private:
	void addRedBorder()
	{
		std::cout << "Adding red border" << std::endl;
	}
};

// 另一个具体装饰类,比如添加阴影装饰
class ShadowDecorator : public ShapeDecorator
{
public:
	ShadowDecorator(Shape* shape) : ShapeDecorator(shape) {}
	void draw() override 
	{
		ShapeDecorator::draw();
		addShadow();
	}
private:
	void addShadow()
	{
		std::cout << "Adding shadow" << std::endl;
	}
};

int main()
{
	Shape* circle = new Circle();

	// 第一次装饰,添加红色边框
	Shape* redBorderCircle = new RedBorderDecorator(circle);
	// 第二次装饰,在有红色边框的基础上添加阴影
	Shape* decoratedCircle = new ShadowDecorator(redBorderCircle);

	decoratedCircle->draw();

	// 释放内存,注意要按照创建顺序的逆序释放
	delete decoratedCircle;
	delete redBorderCircle;
	delete circle;
	char t;
	std::cin>>t;
	return 0;
}

在这里插入图片描述

在上述代码中:
Shape 是抽象构件,定义了 draw 这个抽象方法用于绘制图形。
Circle 作为具体构件实现了 Shape 接口,代表实际要被装饰的基础图形。
ShapeDecorator 是抽象装饰类,它持有一个指向 Shape 的指针,在 draw 方法中调用被装饰对象的 draw 方法,方便后续装饰类在此基础上添加额外功能。
RedBorderDecorator 和 ShadowDecorator 是具体装饰类,它们分别重写了 draw 方法,先调用父类(也就是被装饰对象的)draw 方法,然后添加各自独特的装饰功能,像添加红色边框或者添加阴影。
在 main 函数里,可以看到先创建了一个圆形对象,然后通过多次创建不同的装饰类对象,层层对圆形进行装饰,最后调用 draw 方法就能看到带有多种装饰效果的图形绘制的逻辑展示,并且最后按照创建顺序的逆序释放了内存,避免内存泄漏。

总结

装饰模式,其实可以理解为套娃,一层套一层


http://www.kler.cn/a/453074.html

相关文章:

  • MATLAB符号计算-符号表达式基础运算操作
  • FPGA的DMA应用——pcileech
  • EdgeX Core Service 核心服务之 Core Command 命令
  • OpenCV相机标定与3D重建(36)计算两幅图像之间基本矩阵(Fundamental Matrix)的函数findFundamentalMat()的使用
  • 群晖Cloud Sync一键同步让数据管理变得简单
  • 《战神:诸神黄昏》游戏运行时提示mss32.dll丢失怎么办?
  • SSE(Server-Sent Events)返回n ,前端接收数据时被错误的截断【如何避免SSE消息中的换行符或回车符被解释为事件消息的结束】
  • Halcon 的标定
  • 如何识别钓鱼邮件和诈骗网站?(附网络安全意识培训PPT资料)
  • hhdb客户端介绍(54)
  • 数据结构基本认识与必要知识点准备工作
  • 大型语言模型(LLMs)演化树 Large Language Models
  • Wux weapp 组件库的 bug—— wux-picker选择器组件无法正确初始化到选定的value
  • 基于TP5框架的家具购物小程序的设计与实现【附源码、文档】
  • HTTP,续~
  • 记一次Vue3中使用vue-awesome-swiper遇到的坑
  • vscode写python,遇到问题:ModuleNotFoundError: No module named ‘pillow‘(已解决 避坑)
  • 前端案例---自定义鼠标右键菜单
  • HTML 新手易犯的标签属性设置错误
  • sentinel学习笔记6-限流降级(上)
  • 创建线程的四种方式
  • 大数据技术原理与应用期末复习-代码
  • 深度学习camp-第J5周:DenseNet+SE-Net实战
  • 定位方式:css
  • 选择排序 冒泡排序 MySQL 架构
  • [python SQLAlchemy数据库操作入门]-08.ORM删除不再需要的股票记录