装饰者模式

装饰者模式的引入:咖啡店的实例,当咖啡店想用多种饮料与咖啡混搭的时候,会产生排列组合数量级的类,每次多加入一种搭配的饮料,就要产生许多类。为了避免类爆炸,我们可以不为每种组合做成一个类,而是把搭配饮料作为一种基础咖啡饮料的属性,这种设计的问题有:1)当某种搭配饮料的价格产生变化的时候会改变代码;2)当加入某种新型搭配饮料的时候,也需要改变代码;3)当某种搭配型饮料我们需要两份的时候无法处理;4)子类会继承许多没有意义的东西。那么如何做才能让设计同时具备以上两种设计的优势呢?即又能保证扩展的灵活性又能不产生类爆炸。

装饰者模式:动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。

#ifndef BEVERAGE_H
#define BEVERAGE_H

#include <string>

using namespace std;

class Beverage
{
public:
    Beverage(string s):description(s)
    {
    }
    Beverage(){}
    virtual string getDescription()
    {
        return description;
    }
    virtual double cost() = 0;
protected:
    string description;
};

#endif
Beverage.h
#ifndef DARKROAST_H
#define DARKROAST_H

#include "Beverage.h"

class DarkRoast : public Beverage
{
public:
    DarkRoast ():Beverage("DarkRoast")
    {}
    double cost()
    {
        return 30;
    }
};

#endif
DarkRoast.h
#ifndef DECAF_H
#define DECAF_H

#include "Beverage.h"

class Decaf : public Beverage
{
public:
    Decaf() : Beverage("Decaf")
    {}
    double cost()
    {
        return 50;
    }
};

#endif
Decaf.h
#ifndef ESPRESSO_H
#define ESPRESSO_H

#include "Beverage.h"

class Espresso : public Beverage
{
public:
    Espresso() : Beverage("Espresso")
    {}
    double cost()
    {
        return 40;
    }
};

#endif
Espresso.h
#ifndef HOUSEBLEND_H
#define HOUSEBLEND_H

#include "Beverage.h"

class HouseBlend : public Beverage
{
public:
    HouseBlend():Beverage("HouseBlend")
    {}
    double cost()
    {
        return 20;
    }
};

#endif
Houseblend.h
#ifndef CONDIMENTDECORATOR_H
#define CONDIMENTDECORATOR_H

#include "Beverage.h"

class CondimentDecorator : public Beverage
{
public:
    virtual string getDescription() = 0;
};

#endif
CondimentDecorator.h
#ifndef MILK_H
#define MILK_H

#include "CondimentDecorator.h"
#include "Beverage.h"

class Milk : public CondimentDecorator
{
private:
    Beverage* beverage;
public:
    Milk( Beverage* b )
    {
        beverage = b;
    }
    Milk(){}
    virtual ~Milk()
    {
        if (NULL!=beverage)
        {
            delete beverage;
            beverage = NULL;
        }        
    }
    double cost ()
    {
        return beverage->cost() + 0.1;
    }
    string getDescription()
    {
        return beverage->getDescription() + "," + "Milk";
    }
};

#endif
Milk.h
#ifndef MOCHA_H
#define MOCHA_H

#include "CondimentDecorator.h"
#include "Beverage.h"

class Mocha : public CondimentDecorator
{
private:
    Beverage* beverage;
public:
    Mocha( Beverage* b )
    {
        beverage = b;
    }
    Mocha(){}
    virtual ~Mocha()
    {
        if (NULL != beverage)
        {
            delete beverage;
            beverage = NULL;
        }        
    }
    double cost ()
    {
        return beverage->cost() + 0.2;
    }
    string getDescription()
    {
        return beverage->getDescription() + "," + "Mocha";
    }
};

#endif
Mocha.h

装饰者模式存在的问题: 1)这种设计会产生许多小类,这些小类使得使用程序API的用户很难搞懂。

                                2)使用装饰者模式实例化组件的时候,通常需要很多new操作,会增加代码的复杂度。可以使用抽象工厂解决该问题。

                                3)当组件类型必须是子类的时候,装饰者将无法进行装饰。

posted @ 2015-08-26 16:11  lisiyuannnn  阅读(155)  评论(0)    收藏  举报