【设计模式】装饰

Decorator模式,可以不改变原有类,或者凡索的继承就可以改变其行为。不会破坏原有接口。

我觉得decorator是最优雅的一个模式。设计模式中的小贵妇,小喜欢。

还是那个经典的咖啡加牛奶,糖的问题。其实牛奶咖啡不是咖啡,也不是牛奶。只是一个组合体,所以用继承等来解决从概念上就有点说不通。何况还会带来乘积关系的子类膨胀。直接写代码吧:

 
 
/**
 * @file test_decorator.h
 * @author itegel
 * @date 2014/04/02 17:10:16
 * @brief 
 *  
 **/

#ifndef  __TEST_DECORATOR_H_
#define  __TEST_DECORATOR_H_

#include <iostream>

//component
class Component{
    public:
        Component(){}
        virtual void Describe() = 0;
};

// concrete component
class Coffee : public Component{
    public:
        Coffee(){}
        virtual void Describe() {
            std::cout<<"I am just one cup of coffee!"<<std::endl;
        }
};

// concrete component
class Tea : public Component{
    public:
        Tea(){}
        virtual void Describe() {
            std::cout<<"I am just one cup of tea!"<<std::endl;
        }
};


//milk
class MilkComponent : public Component{
    public:
        MilkComponent(Component * component){
            component_ = component;
        }
        virtual void Describe() {
            component_->Describe();
            std::cout<<"I am added milk!"<<std::endl;
        }
    private:
        Component * component_;
};

//sugar
class SugarComponent : public Component{
    public:
        SugarComponent(Component * component){
            component_ = component;
        }
        virtual void Describe() {
            component_->Describe();
            std::cout<<"I am added sugar!"<<std::endl;
        }
    private:
        Component * component_;
};

#endif  //__TEST_DECORATOR_H_

/* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */


client:

/**
 * @file test_decorator.cpp
 * @author itegel
 * @date 2014/04/02 17:22:47
 * @brief 
 *  
 **/

#include "test_decorator.h"

int main(){
    std::cout<<"milk coffee:"<<std::endl;
    Coffee coffee;
    MilkComponent milk_coffee(&coffee);
    milk_coffee.Describe();

    std::cout<<std::endl<<"milk, sugar tea:"<<std::endl;
    Tea tea;
    SugarComponent sugar_tea(&tea);
    MilkComponent milk_sugar_tea(&sugar_tea);
    milk_sugar_tea.Describe();
    return 0;
}

输出:

milk coffee:
I am just one cup of coffee!
I am added milk!

milk, sugar tea:
I am just one cup of tea!
I am added sugar!
I am added milk!

可以先看看client代码,跟人们的正常认识和真是生活更贴切。我先磨一杯咖啡,加点牛奶。如果觉得苦了还可以再加一点糖....

而且加糖,加牛奶等这些还可以累加,跟顺序也无关。

我想他可能存在的问题是,如果想增加个接口,那么被装饰的类和装饰类都需要相应修改。不过装饰类一般也不会很多。用这一点点代价换取子类膨胀等问题,我觉得很多时候都是值当的。而如果只需要一个装饰类的时候,该模式也可以简单退化为直接从父类继承出响应的装饰类即可。

我觉得装饰模式比较惊喜的特点是,可以用任何顺序叠加不同装饰。就像刷墙漆,可以一层一层刷很多遍。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值