设计模式——装饰器模式

embedded/2024/11/28 16:30:36/

装饰器模式是结构型设计模式,在Python中有一个非常著名的装饰器wrapper,它的实现方法就是使用了该设计模式,装饰器可以修饰类也可以修饰函数。

从类的设计上说,他的本质是在不定义子类的情况下动态的给对象添加一些额外的功能。举个简单的例子来说,假设你有一个芭比娃娃类,你想要为它穿上不同颜色、款式的衣服,如果每一个颜色/款式都要实现一个子类,就会产生大量的类。事实上,我们可以考虑用装饰模式动态地添加和删除,而而不需要修改芭比娃娃类本身,这样使得代码更加简洁和灵活。

基本结构

  • 组件Component:通常是抽象类或者接口,是具体组件和装饰者的父类,定义了具体组件需要实现的方法,比如说我们定义的Coffee为组件。
  • 具体组件ConcreteComponent:实现了Component接口的具体类,是被装饰的对象。
  • 装饰类Decorator:一个抽象类,给具体组件添加功能,但是具体的功能由子类具体装饰者完成
  • 具体装饰类ConcreteDecorater:扩展抽象类,负责向Component对象添加新的行为,例如加牛奶的咖啡,还有加糖的咖啡也是。

代码

/*** The base Component interface defines operations that can be altered by* decorators.*/
class Component {public:virtual ~Component() {}virtual std::string Operation() const = 0;
};
/*** Concrete Components provide default implementations of the operations. There* might be several variations of these classes.*/
class ConcreteComponent : public Component {public:std::string Operation() const override {return "ConcreteComponent";}
};
/*** The base Decorator class follows the same interface as the other components.* The primary purpose of this class is to define the wrapping interface for all* concrete decorators. The default implementation of the wrapping code might* include a field for storing a wrapped component and the means to initialize* it.*/
class Decorator : public Component {/*** @var Component*/protected:Component* component_;public:Decorator(Component* component) : component_(component) {}/*** The Decorator delegates all work to the wrapped component.*/std::string Operation() const override {return this->component_->Operation();}
};
/*** Concrete Decorators call the wrapped object and alter its result in some way.*/
class ConcreteDecoratorA : public Decorator {/*** Decorators may call parent implementation of the operation, instead of* calling the wrapped object directly. This approach simplifies extension of* decorator classes.*/public:ConcreteDecoratorA(Component* component) : Decorator(component) {}std::string Operation() const override {return "ConcreteDecoratorA(" + Decorator::Operation() + ")";}
};
/*** Decorators can execute their behavior either before or after the call to a* wrapped object.*/
class ConcreteDecoratorB : public Decorator {public:ConcreteDecoratorB(Component* component) : Decorator(component) {}std::string Operation() const override {return "ConcreteDecoratorB(" + Decorator::Operation() + ")";}
};
/*** The client code works with all objects using the Component interface. This* way it can stay independent of the concrete classes of components it works* with.*/
void ClientCode(Component* component) {// ...std::cout << "RESULT: " << component->Operation();// ...
}int main() {/*** This way the client code can support both simple components...*/Component* simple = new ConcreteComponent;std::cout << "Client: I've got a simple component:\n";ClientCode(simple);std::cout << "\n\n";/*** ...as well as decorated ones.** Note how decorators can wrap not only simple components but the other* decorators as well.*/Component* decorator1 = new ConcreteDecoratorA(simple);Component* decorator2 = new ConcreteDecoratorB(decorator1);std::cout << "Client: Now I've got a decorated component:\n";ClientCode(decorator2);std::cout << "\n";delete simple;delete decorator1;delete decorator2;return 0;
}

输出

Client: I've got a simple component:
RESULT: ConcreteComponentClient: Now I've got a decorated component:
RESULT: ConcreteDecoratorB(ConcreteDecoratorA(ConcreteComponent))

上述代码很好理解,就是使用了一个装饰器类继承原先的组件,然后重载组件的操作符,利用了C++中的虚函数,即动态多态实现了给对象动态添加额外功能。该模式同时间接体现单一职责原则:你可以将实现了许多不同行为的一个大类拆分为多个较小的类。

装饰模式适合应用场景

  • 如果你希望在无需修改代码的情况下即可使用对象, 且希望在运行时为对象新增额外的行为, 可以使用装饰模式。装饰能将业务逻辑组织为层次结构, 你可为各层创建一个装饰, 在运行时将各种不同逻辑组合成对象。 由于这些对象都遵循通用接口, 客户端代码能以相同的方式使用这些对象。

  • 如果用继承来扩展对象行为的方案难以实现或者根本不可行, 你可以使用该模式。许多编程语言使用 final最终关键字来限制对某个类的进一步扩展。 复用最终类已有行为的唯一方法是使用装饰模式: 用封装器对其进行封装。


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

相关文章

C#笔记(5)

一、winform项目与窗体控件 1、部分类的使用 好处&#xff1a;让自动生成的代码后置&#xff0c;我们编写程序的代码显得更加简洁 特点&#xff1a;在最后编译的时候&#xff0c;仍然编译成一个窗体类。 窗体和控件的基本使用 3、Event事件&#xff08;委托--》事件&#…

代理模式 (Proxy Pattern)

文章目录 代理模式 (Proxy Pattern)原理分类优点缺点示例代码静态代理1. 定义接口2. 创建真实类3. 创建代理类4. 客户端代码输出结果 动态代理&#xff08;基于 JDK&#xff09;1. 定义接口和真实类2. 创建动态代理类3. 客户端代码输出结果 UML 类图静态代理动态代理 使用场景小…

Qt中的套件(如MSVC2019)提示no complier set in kit

起因 是我想在qt创建自定义控件新建项目的时候发现有黄色警告&#xff1a;提示no complier set in kit 但是其实我早发现了但是我选择忽视然后选择了minGW编译器。。。。但是现在我不得不解决呜呜呜呜&#xff08;小声&#xff09; 提示原因是因为没有编译器&#xff0c;所以…

【Python爬虫五十个小案例】爬取豆瓣电影Top250

博客主页&#xff1a;小馒头学python 本文专栏: Python爬虫五十个小案例 专栏简介&#xff1a;分享五十个Python爬虫小案例 &#x1fab2;前言 在这篇博客中&#xff0c;我们将学习如何使用Python爬取豆瓣电影Top250的数据。我们将使用requests库来发送HTTP请求&#xff0c;…

HarmonyOS开发:DevEco Studio的Beta3(5.0.5.200)新增和增强特性

新增特性 DevEco Studio支持开发API 13工程。DevEco Profiler Frame模板新增Lost Frames和Hitch Time泳道&#xff0c;用于识别和优化卡顿和丢帧现象。具体请参考Frame分析。hvigor-config.json5中properties下新增ohos.arkCompile.noEmitJs字段&#xff0c;用于指定ArkTS编译…

基于 Nginx Ingress Controller 的四层(TCP)转发配置

基于 Nginx Ingress Controller 的四层&#xff08;TCP&#xff09;转发配置 1. 简介 本指南将展示如何通过配置 ConfigMap 来实现 Nginx Ingress Controller 的四层转发&#xff08;TCP&#xff09;&#xff0c;并通过配置测试应用程序验证配置的有效性。本文中使用的 Kuber…

ChatGPT的应用场景:开启无限可能的大门

ChatGPT的应用场景:开启无限可能的大门 随着人工智能技术的快速发展,自然语言处理领域迎来了前所未有的突破。其中,ChatGPT作为一款基于Transformer架构的语言模型,凭借其强大的语言理解和生成能力,在多个行业和场景中展现出了广泛的应用潜力。以下是ChatGPT八个最具代表…

人工智能在医疗保健领域的潜在应用

人工智能在医疗保健领域的潜在应用 一、影像识别与辅助诊断 医学影像解读 医学影像解读一直是医生的重要工作之一&#xff0c;然而由于医学影像学习曲线陡峭、误诊率高等问题&#xff0c;这一领域迫切需要人工智能技术的介入。利用深度学习算法&#xff0c;人工智能可以对医学影…