码迷,mamicode.com
首页 > 其他好文 > 详细

大话锦集(三)装饰模式(Decorator)

时间:2015-11-18 16:11:01      阅读:173      评论:0      收藏:0      [点我收藏+]

标签:

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

其结构图如下:

技术分享

Component是定义一个对象接口,可以给这些对象动态地添加责任。ConcreteComponent是定义了一个具体的对象,也可以给这个对象添加一些职责。Decorator装饰抽象类,继承了Component,从外类来扩展Component类的功能,但对于Component来说,是无需知道Decorator的存在。ConcreteDecorator就是具体的装饰对象,起到了给Component添加职责的功能。

下面是我用C语言代码实现的,如果有误请指出,以免误人!!!

class Component{
public:
    virtual void Operation()
    {
        printf("Component Operation\n");
    }
};

class ConcreteCompoent :public Component{
public:
    void Operation()
    {
        printf("ConcreteComponent Operation\n");
    }
};

class Decorator :public Component{
protected:
    Component* component;
public:
    Decorator()
    {
        this->component = nullptr;
    }

    ~Decorator()
    {
        delete component;
    }

    void setComponent(Component* com)
    {
        if (component == nullptr)
        this->component = com;
    }

    void Operation()
    {
        component->Operation();
    }
};

class ConcreteDecoratorA :public Decorator
{
private:
    string addedState;//本类的都有功能,以区别ConcreteDecoratorB
public:
    void Operation()
    {
        Component::Operation();
        addedState = "New State";
        printf("具体装饰对象A的操作\n");
    }
};

class ConcreteDecoratorB :public Decorator
{
private:
    string addedState;//本类的都有功能,以区别ConcreteDecoratorB
public:
    void Operation()
    {
        Component::Operation();
        AddedBehavior();
    }
    void AddedBehavior()
    {
        //本类都有的方法,以区别于ConcreteDecoratorA
        printf("具体装饰对象B的操作\n");
    }
};

//client
void main(void)
{
    ConcreteCompoent* com = new ConcreteCompoent;
    ConcreteDecoratorA *comA = new ConcreteDecoratorA;
    ConcreteDecoratorB *comB = new ConcreteDecoratorB;
    comA->setComponent(com);
    comB->setComponent(comA);
    comB->Operation();
   delete com;
delete comA;
delete comB;
}

装饰模式是利用setComponent来对对象进行包装的,这样每个装饰对象的实现就和如何使用这个对象分离开了,每个装饰对象只关心自己的功能,不需要关心如何被添加到对象链当中。

如果只有一个ConcreteComponent类而没有抽象的Componet类,那么Decorator类可以是ConcreteComponent的一个子类。同样道理,如果只有一个ConcreteDecorator类,那么就没有必要建立一个单独的Decorator类,而可以把Decorator和ConcreteDecorator的责任合并成一个类。

以下是《大话设计模式》上面的“小菜穿衣约会MM”的例子用C++实现下:

class Person{
private:
    string name;
public:
    Person(){}
    Person(string name)
    {
        this->name = name;
    }
    virtual void show()
    {
        cout << name <<"的装扮: ";
    }
};

class Finery :public Person
{
protected:
    Person *component;
public:
    Finery(){}
    void Decorate(Person *com)
    {
        this->component = com;
        component->show();
    }
    void show()
    {

    }
};

class TShirts :public Finery{
public:
    void show()
    {
        cout << "T恤 ";
    }
};

class Trouser :public Finery{
public:
    Trouser(){}
    void show()
    {
        cout << "跨库 ";
    }
};
class Sneakers :public Finery{
public:
    void show()
    {
        cout << "球鞋 ";
    }
};
class Suit :public Finery{
public:
    void show()
    {
        cout << "西装 ";
    }
};

class Tie :public Finery{
public:
    void show()
    {
        cout << "领带 ";
    }
};

class LeatherShoes :public Finery{
public:
    void show()
    {
        cout << "皮鞋 ";
    }
};

//client
void main(void)
{
    Person *p = new Person("小菜");
    Sneakers *snekers = new Sneakers();
    Trouser *trouser = new Trouser();
    TShirts *shirt = new  TShirts();

    snekers->Decorate(p);
    trouser->Decorate(snekers);
    shirt->Decorate(trouser);
    shirt->show();
    delete p;
    delete snekers;
    delete trouser;
    delete shirt;
}

装饰模式是为已有功能动态地添加更多功能的一种方式。当系统需要新功能的时候,是向旧的类中添加新的代码,这些新加的代码通常装饰了原有类的核心职责或主要行为,在主类中加入了新的字段,新的方法和新的逻辑,从而增加了主类的复杂度,而这些新加入的东西仅仅是为了满足一些只在某种特定情况下才会执行的特殊行为的需要。而装饰模式却提供了一个非常好的解决方案,它把每个要装饰的功能放在单独的类中,并让这个类包装它要装饰的对象,因此,当需要执行特殊行为时,客户端代码就可以在运行时根据需要有选择地、按顺序地使用装饰功能包装对象了。

装饰模式的优点:把类中的装饰功能从类中移除,可以简化原有的类,有效地把类的核心职责和装饰功能区分开来,而且可以去除相关类中重复的装饰逻辑。

大话锦集(三)装饰模式(Decorator)

标签:

原文地址:http://www.cnblogs.com/tgycoder/p/4974653.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!