设计模式之结构型之装饰模式(C++)

参考资料

1. 概述

名称:装饰模式,装饰者模式,Wrapper,Decorator

装饰设计模式

“套娃模式” 

更好地应对对基本功能的多种扩展,动态完成

如何能更加方便地应对多种方法的任意组合?如何在运行时动态的完成,如果使用继承则是静态的,如果可能的组合的很多,子类的数量将很多

通常使用组合的方式实现

生活中的例子:

装饰模式示例

 UML图

装饰设计模式的结构

 应用场景

  • 希望在运行时为对象新增额外的功能,但是不需要更改设计类的代码,则可以使用装饰模式
  • 如果无法通过继承来扩展功能,则也可以考虑使用装饰模式

实现关键:具体装饰必须在调用父类方法之后或者之前执行自身的行为;装饰基类使用一个成员变量指向被装饰对象的引用

装饰模式的优点:

  • 无需创建新子类就可以扩展对象的行为
  • 可以在运行是添加或者删除对象功能
  • 更加符合单一职责原则,比起实现一个复杂的子类,装饰模式更加符合单一职责原则

缺点:

  • 初始化代码会比较复杂
  • 实现可以任意顺序组合的装饰编码比较困难

一句话总结:装饰模式是一个结构型设计模式,允许你通过将对象放入特殊封装对象来增加新的行为

2. 编码

#include <bits/stdc++.h>
using namespace std;

/**
 * 基本成分的接口
 */
class Component {
 public:
  virtual ~Component() {}
  virtual string Operation() const = 0;
};

/**
 * 具体成分
 */
class ConcreteComponent : public Component {
 public:
  string Operation() const override {
    return "ConcreteComponent";
  }
};

/**
 * 基本装饰器,注意实现了基本成分接口
 */
class Decorator : public Component {
 protected:
  Component* component_;

 public:
  /**
   * @brief 注意这个构造函数
   * @param component 基本成分指针
   */
  Decorator(Component* component) : component_(component) {}

  /**
   * @brief 调用基本成分的功能
   * @return 基本成分操作返回值
   */
  string Operation() const override {
    return component_->Operation();
  }
};

/**
 * 扩展装饰器A
 */
class ConcreteDecoratorA : public Decorator {
 public:
  /**
   * @brief 构造函数会初始化基本装饰器
   * @param component 基本成分指针
   */
  ConcreteDecoratorA(Component* component) : Decorator(component) {}

  /**
   * @brief 注意这里也调用了基本装饰器的操作
   * @return
   */
  string Operation() const override {
    return "ConcreteDecortorA(" + Decorator::Operation() + ")";
  }
};

/**
 * 扩展装饰器B
 */
class ConcreteDecoratorB : public Decorator {
 public:
  /**
   * @brief 构造函数会初始化基本装饰器
   * @param component 基本成分指针
   */
  ConcreteDecoratorB(Component* component) : Decorator(component) {}

  /**
   * @brief 注意这里也调用了基本装饰器的操作
   * @return
   */
  string Operation() const override {
    return "ConcreteDecortorB(" + Decorator::Operation() + ")";
  }
};

void ClientCode(Component* component) {
  cout << "RESULT: " << component->Operation();
}

int main() {
  Component* simple = new ConcreteComponent();
  cout << "Client: I've got a simple component:\n";
  ClientCode(simple);
  cout << "\n\n";

  Component* decorator1 = new ConcreteDecoratorA(simple);
  Component* decorator2 = new ConcreteDecoratorB(decorator1);
  cout << "Client: Now I've got a decorated component:\n";
  ClientCode(decorator2);
  cout << endl;

  delete simple;
  delete decorator1;
  delete decorator2;
  return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值