装饰器模式

Posted 心之所向,素履以往

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了装饰器模式相关的知识,希望对你有一定的参考价值。

1、引言

最近在看Openstack源码,发现里面大量使用了装饰器模式,以前也接触过装饰器模式,只了解它是在原有对象上加了一层封装,保持原有逻辑不变。今天仔细想想,完全可以再重新写一个类,把原来的对象包进去,将原来用到该对象的地方替换成现有对象即可,那为什么还要弄出来一个装饰器模式?

2、装饰器模式

允许向一个现有的对象添加新的功能,同时又不改变其结构。装饰者可以在所委托被装饰者的行为之前或之后加上自己的行为,以达到特定的目的。

3、装饰器的结构

装饰器模式由组件和装饰者组成。

抽象组件(Component):需要装饰的抽象对象。 
具体组件(ConcreteComponent):是我们需要装饰的对象 
抽象装饰类(Decorator):内含指向抽象组件的引用及装饰者共有的方法。 
具体装饰类(ConcreteDecorator):被装饰的对象。

4、装饰器的实现

由于是装饰的关系,这次我们用人和衣服当例子,衣服装饰人。首先定义一个被装饰的类表示人:

class Person
{
private:
    int id_;

public:
    Person() : id_(0){}
    Person(int id) : id_(id){}
    virtual ~Person(){}

    virtual void Show(){ printf("%d\\n",id_); }
};

然后定义装饰类衣服:

class Clothes : public Person
{
public:
    Clothes() {}
    virtual ~Clothes() {}

    void Decorator(Person* p)
    {
        person_ = p;
    }

    virtual void Show()
    {
        if (person_)
        {
            person_->Show();
        }
    }
protected:
    Person* person_;
};

最后实现具体的装饰类TShirt和Shoes:

class TShirt : public Clothes
{
public:
    void Show()
    {
        printf("TShirt ");
        person_->Show();
    }
};


class Shoes : public Clothes
{
public:
    void Show()
    {
        printf("Shoes ");
        person_->Show();
    }
};

 调用装饰器装饰人:

void TestDecrator()
{
    Person xa(110);
    
    TShirt shirt;
    Shoes  shoes;
    shirt.Decorator(&xa);
    shoes.Decorator(&shirt);
    shoes.Show();
}

 

5、装饰器的优点

可以动态的给一个对象添加功能。

有效的把类的核心职责和装饰功能区分开。

 

以上是关于装饰器模式的主要内容,如果未能解决你的问题,请参考以下文章

设计模式之装饰器模式

装饰器模式问题 - 如何调用嵌套装饰器方法?

学习设计模式之装饰器模式

装饰器模式

PHP 装饰器模式

设计模式之装饰器模式