设计模式(11)装饰模式

装饰模式简介

在软件设计中,对现有的对象进行功能扩展,使得对象更能符合客户的需求。装饰模式可以在不改变一个对象本身的条件下,给对象新增额外的新行为。

装饰模式是一种类似于继承的技术。通过一种无须定义子类的方式给对象动态增加职责,使用对象之间的关联关系取代类之间的继承关系。装饰模式中引入了装饰类,在装饰类中既可以调用待装饰的原有对象的方法,还可以增加新的方法,以扩充原有类的功能。

装饰模式:动态地给一个对象增加一些额外的职责。就扩展功能而言,装饰模式提供了一种比使用子类更加灵活的替代方案。

装饰模式结构

如下图所示:
在这里插入图片描述
从图中可以看出,装饰模式有以下角色:

  • Component(抽象构件):是具体构件类和装饰类的共同基类,声明了在具体构件中定义的方法,客户端可以一致的对待使用装饰前后的对象;
  • ConcreteComponent(具体构件):具体构件定义了构件具体的方法,装饰类可以给它增加更多的功能;
  • Decorator(抽象装饰类):用于给具体构件增加职责,但具体职责在其子类中实现。抽象装饰类通过聚合关系定义一个抽象构件的对象,通过该对象可以调用装饰之前构件的方法,并通过其子类扩展该方法,达到装饰的目的;
  • ConcreteDecorator(具体装饰类): 向构件增加新的功能。

装饰模式代码实例

DecoratorPattern.h

#include <iostream>

using namespace std;

//抽象构件
class Component
{
    
    
public:
  Component() {
    
    }
  virtual void operation() = 0;
};

//具体构件类
class Phone : public Component
{
    
    
public:
  Phone() {
    
    }

  void operation()
  {
    
    
    cout << " 手机 " << endl;
  }
};

//抽象装饰类
class Decorator : public Component
{
    
    
public:
  Decorator() {
    
    }

  Decorator(Component *c)
  {
    
    
    this->component = c;
  }

  void operation()
  {
    
    
    this->component->operation();
  }

  Component *getComponent()
  {
    
    
    return this->component;
  }

  void setComponent(Component *c)
  {
    
    
    this->component = c;
  }

private:
  Component *component;
};

//具体装饰类:手机壳
class DecoratorShell : public Decorator
{
    
    
public:
  DecoratorShell() {
    
    }

  DecoratorShell(Component *c)
  {
    
    
    this->setComponent(c);
  }

  void operation()
  {
    
    
    this->getComponent()->operation();
    this->newBehavior();
  }

  void newBehavior()
  {
    
    
    cout << " 装手机壳 " << endl;
  }
};

//具体装饰类:手机贴纸
class DecoratorSticker : public Decorator
{
    
    
public:
  DecoratorSticker() {
    
    }

  DecoratorSticker(Component *c)
  {
    
    
    this->setComponent(c);
  }

  void operation()
  {
    
    
    this->getComponent()->operation();
    this->newBehavior();
  }

  void newBehavior()
  {
    
    
    cout << " 贴卡通贴纸 " << endl;
  }
};

//具体装饰类:手机挂绳
class DecoratorRope : public Decorator
{
    
    
public:
  DecoratorRope() {
    
    }

  DecoratorRope(Component *c)
  {
    
    
    this->setComponent(c);
  }

  void operation()
  {
    
    
    this->getComponent()->operation();
    this->newBehavior();
  }

  void newBehavior()
  {
    
    
    cout << " 系手机挂绳 " << endl;
  }
};

DecoratorPattern.cpp

#include "DecoratorPattern.h"

int main()
{
    
    
  cout << " First Phone " << endl;
  Component *c1;
  Component *com_Shell1;
  c1 = new Phone();
  com_Shell1 = new DecoratorShell(c1);
  com_Shell1->operation();

  cout << "\n";

  cout << " Second Phone " << endl;
  Component *c2;
  Component *com_Shell2;
  c2 = new Phone();
  com_Shell2 = new DecoratorShell(c2);
  Component *com_Sticker;
  com_Sticker = new DecoratorSticker(com_Shell2);
  com_Sticker->operation();

  cout << "\n";

  cout << " Third Phone " << endl;
  Component *c3;
  Component *com_Shell3;
  c3 = new Phone();
  com_Shell3 = new DecoratorShell(c3);
  Component *com_Sticker2;
  com_Sticker2 = new DecoratorSticker(com_Shell3);
  Component *com_Rope;
  com_Rope = new DecoratorRope(com_Sticker2);
  com_Rope->operation();

  delete c1;
  delete com_Shell1;
  delete c2;
  delete com_Shell2;
  delete com_Sticker;
  delete c3;
  delete com_Sticker2;
  delete com_Rope;

  return 0;
}

装饰模式总结

优点:

  • 对于扩展一个类的新功能,装饰模式比继承更加灵活;
  • 动态扩展一个对象的功能;
  • 可以对一个对象进行多次装饰(如上述例子第二个手机和第三个手机);
  • 具体构件类和具体装饰类可以独立变化和扩展,符合开闭原则。

缺点:

  • 装饰模式中会增加很多小的对象,对象的区别主要在于各种装饰的连接方式不同,而并不是职责不同,大量小对象的产生会占用较多的系统资源;
  • 装饰模式比继承模式更灵活,但也更容易出错,更难于排错。

适用场景:

  • 在不影响其他对象的情况下,给单个对象动态扩展职责;
  • 不适宜采用继承的方式进行扩展的时候,可以考虑使用装饰模式。

おすすめ

転載: blog.csdn.net/qq_24649627/article/details/115373409