大话设计模式C++版本-03-装饰模式

简介: 大话设计模式C++版本-03-装饰模式

概念

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

允许向一个现有的对象添加新的功能,同时又不改变其结构

优点:装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。

缺点:多层装饰比较复杂。


应用场景

  1. 在不想增加很多子类的情况下扩展类。
  2. 动态增加功能,动态撤销。


一般步骤

定义一个基类,并带有一个功能的函数。如:Person类里有个Show()功能;

class Person
{
public:
  Person(){};
  Person(string name)
  {
    this->name = name;
  }
  ~Person() {}
  virtual void Show() // 展示装扮
  {
    cout << "装扮的" << name <<  endl;
  }
private:
  string name;
};

定义一个装饰类,继承前面的基类,并且有一个装饰的函数可以装饰基类的指针,且重写基类的那个功能函数(Show),并在函数里调用基类的功能函数(Show);

这一步非常关键,是这个模式里最重要的一步

class Finery : public Person // 装饰类
{
public:
  void Decorate(Person* person) // 装扮指定的人,在这个模式里最重要的一个函数
  {
    boy = person;
  }
  void Show()
  {
    if (boy)
    {
      boy->Show();
    }
  }
private:
  Person* boy;
};

定义具体的功能类,继承前面的装饰类,且重写功能函数(Show);

class TShirt : public Finery
{
public:
  void Show()
  {
    printf("Tshirt ");
    Finery::Show();
  }
};
class BigTrouser : public Finery
{
public:
  void Show()
  {
    printf("BigTrouser ");
    Finery::Show();
  }
};

完整实例

#include <cstdio>
#include <iostream>
#include <string>
using namespace std;
class Person
{
public:
  Person(){};
  Person(string name)
  {
    this->name = name;
  }
  ~Person() {}
  virtual void Show() // 展示装扮
  {
    cout << "装扮的" << name <<  endl;
  }
private:
  string name;
};
class Finery : public Person // 装饰类
{
public:
  void Decorate(Person* person) // 装扮指定的人,在这个模式里最重要的一个函数
  {
    boy = person;
  }
  void Show()
  {
    if (boy)
    {
      boy->Show();
    }
  }
private:
  Person* boy;
};
class TShirt : public Finery
{
public:
  void Show()
  {
    printf("Tshirt ");
    Finery::Show();
  }
};
class BigTrouser : public Finery
{
public:
  void Show()
  {
    printf("BigTrouser ");
    Finery::Show();
  }
};
int main()
{
  Person *xc = new Person("小菜");
  cout << "第一钟装扮" << endl;
  TShirt *tshirt = new TShirt();
  BigTrouser  *BigTrouser  = new BigTrouser();
  tshirt->Decorate(xc);  // 用T恤装扮小菜
  BigTrouser->Decorate(tshirt); // 用裤子 装扮 "已装扮了T恤" 的小菜
  BigTrouser->Show();
  return 0;
}

参考资料

程杰老师的《大话设计模式

装饰器模式|菜鸟教程

目录
相关文章
|
23天前
|
设计模式 PHP
php设计模式--装饰模式(七)装饰模式完成文章编辑
php设计模式--装饰模式(七)装饰模式完成文章编辑
12 0
|
2月前
|
C++
二叉树进阶面试题(精华总结)【C++版本】
二叉树进阶面试题(精华总结)【C++版本】
|
2月前
|
设计模式 编译器 API
【C/C++ Pimpl模式】隐藏实现细节的高效方式 (Pimpl Idiom: An Efficient Way to Hide Implementation Details)
【C/C++ Pimpl模式】隐藏实现细节的高效方式 (Pimpl Idiom: An Efficient Way to Hide Implementation Details)
67 1
|
2月前
|
消息中间件 负载均衡 监控
【ZMQ PUB模式指南】深入探究ZeroMQ的PUB-SUB模式:C++编程实践、底层原理与最佳实践
【ZMQ PUB模式指南】深入探究ZeroMQ的PUB-SUB模式:C++编程实践、底层原理与最佳实践
194 1
|
2月前
|
设计模式 中间件 程序员
【C/C++ 奇异递归模板模式 】C++中CRTP模式(Curiously Recurring Template Pattern)的艺术和科学
【C/C++ 奇异递归模板模式 】C++中CRTP模式(Curiously Recurring Template Pattern)的艺术和科学
20 3
|
8天前
|
设计模式 存储 Java
C++从入门到精通:3.5设计模式——提升代码可维护性与可扩展性的关键
C++从入门到精通:3.5设计模式——提升代码可维护性与可扩展性的关键
|
8天前
|
设计模式 Go
[设计模式 Go实现] 结构型~装饰模式
[设计模式 Go实现] 结构型~装饰模式
|
25天前
|
人工智能 机器人 Linux
【C++】Linux下如何查看opencv的版本
【C++】Linux下如何查看opencv的版本
|
1月前
|
XML JSON JavaScript
推荐一个比较好用的c++版本http协议库-cpp-httplib
推荐一个比较好用的c++版本http协议库-cpp-httplib
45 1
|
1月前
|
JSON Linux API
一个C++版本的Sqlite3封装--SmartDb
一个C++版本的Sqlite3封装--SmartDb
14 0