锋行_THU_SJTU

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

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

装饰者模式的整体思路比较简单,就是在类的实例中包含一个同类型的成员变量,然后用实例来装饰该成员变量。这样就就可以实现嵌套装饰。

书中该部分的例子是咖啡。

Coffee.h

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

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

class Mocha: public Beverage {
public:
    Mocha(Beverage* b);
    ~Mocha();
    std::string getDescription();
    double cost();

private:
    Beverage* beverage;
};

Coffee.cpp

#include <iostream>
#include "Coffee.h"

std::string Beverage::getDescription() {
    return description;
}

Espresso::Espresso() {
    description = "Espresso";
}

double Espresso::cost() {
    return 1.99;
}

Mocha::Mocha(Beverage* b) {
    beverage = b;
}

Mocha::~Mocha() {
    delete beverage;
}

std::string Mocha::getDescription() {
    return beverage->getDescription()+" Mocha";
}

double Mocha::cost() {
    return beverage->cost()+0.2;
}

需要注意的问题:

1. 构造函数中的参数要传指针。或者这么说,我现在认为这种继承关系,用父类作为参数类型的时候,都应该传指针,这样不容易导致问题。(我的理解是,如果是用引用进行传递,其传入的数据的类型就是父类的类型,这会导致在调用成员函数的时候出现问题)

2. 忘记用列表初始化了(捂脸)。

blog中装饰模式的例子是装饰手机,基本上与书中咖啡的例子相同。见:https://blog.csdn.net/wuzhekai1985/article/details/6672614

两者相比:

1. 根据blog的代码,基本上证明了我自己实现中的猜想(1)。

2. 根据测试代码,继承的类型,在新建实例的时候,也是以指针的形式来完成的。比如

Phone *iphone = new NokiaPhone("6300");  
Phone *dpa = new DecoratorPhoneA(iphone); //装饰,增加挂件   、
Phone *dpb = new DecoratorPhoneB(dpa);
//装饰,屏幕贴膜

 

posted on 2018-06-09 15:32  锋行_THU_SJTU  阅读(116)  评论(0编辑  收藏  举报