装饰者模式
2020 年 08 月 31 日 195 846 字 暂无评论

01.概念

  • 装饰( Decorator )模式又叫做包装模式。通过一种对客户端透明的方式来扩展对象的功能,是继承关系的一个替换方案。
  • 装饰模式就是把要添加的附加功能分别放在单独的类中,并让这个类包含它要装饰的对象,当需要执行时,客户端就可以有选择地、按顺序地使用装饰功能包装对象。

02.类图角色和职责

在装饰模式中的各个角色有:

  • 抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。
  • 具体构件(Concrete Component)角色:定义一个将要接收附加责任的类。
  • 装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。
  • 具体装饰(Concrete Decorator)角色:负责给构件对象"贴上"附加的责任。

适用于:

  • 装饰者模式Decorator Pattern)动态的给一个对象添加一些额外的职责。就增加功能来说,此模式比生成子类更为灵活。

03.例程代码

#include <iostream>

using namespace std;

class Car
{
public:
        virtual void show() = 0;
private:
};

class RunCar : public Car
{
public:
        void run()
        {
                cout << "I can run" << endl;
        }
        virtual void show()
        {
                run();
        }
private:
};

class SwimCarDirector : public Car
{
public:
        SwimCarDirector(Car* car)
        {
                m_car = car;
        }
        void swim()
        {
                cout << "I can swim" << endl;
        }
        virtual void show()
        {
                m_car->show();
                swim();
        }
private:
        Car* m_car;
};

class FlyCarDirector : public Car
{
public:
        FlyCarDirector(Car* car)
        {
                m_car = car;
        }
        void fly()
        {
                cout << "I can fly" << endl;
        }
        virtual void show()
        {
                m_car->show();
                fly();
        }

private:
        Car* m_car;
};


void main()
{
        Car* mycar = NULL;
        mycar = new RunCar;
        mycar->show();
        cout << "--------------------------------" << endl;

        FlyCarDirector* flycar = new FlyCarDirector(mycar);
        flycar->show();
        cout << "--------------------------------" << endl;

        SwimCarDirector* swimcar = new SwimCarDirector(flycar);
        swimcar->show();
        cout << "--------------------------------" << endl;
}
  • 输出
I can run
--------------------------------
I can run
I can fly
--------------------------------
I can run
I can fly
I can swim
--------------------------------

04.装饰者模式与适配者模式的区别

  • 关于新职责:适配器也可以在转换时增加新的职责,但主要目的不在此。装饰者模式主要是给被装饰者增加新职责的。
  • 关于原接口:适配器模式是用新接口来调用原接口,原接口对新系统是不可见或者说不可用的。装饰者模式原封不动的使用原接口,系统对装饰的对象也通过原接口来完成使用。(增加新接口的装饰者模式可以认为是其变种--“半透明”装饰者)
  • 关于其包裹的对象:适配器是知道被适配者的详细情况的(就是那个类或那个接口)。装饰者只知道其接口是什么,至于其具体类型(是基类还是其他派生类)只有在运行期间才知道。

05.适用场景与优缺点

5.1适用场景

  • 需要扩展一个类的功能,或给一个类增加附加责任。
  • 需要动态地给一个对象增加功能,这些功能可以再动态地撤销。
  • 需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变得不现实。

5.2优点

  • Decorator模式与继承关系的目的都是要扩展对象的功能,但是Decorator可以提供比继承更多的灵活性。
  • 通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。

5.3缺点

  • 这种比继承更加灵活机动的特性,也同时意味着更加多的复杂性。
  • 装饰模式会导致设计中出现许多小类,如果过度使用,会使程序变得很复杂。
  • 装饰模式是针对抽象组件(Component)类型编程。但是,如果你要针对具体组件编程时,就应该重新思考你的应用架构,以及装饰者是否合适。当然也可以改变Component接口,增加新的公开的行为,实现“半透明”的装饰者模式。在实际项目中要做出最佳选择。

版权属于:zfh

本文链接:http://zfhblog.com/index.php/archives/127/



评论已关闭