今天就让我们来了解一下装饰者模式吧~~~
首先何为装饰呢?装饰的解释:特定的建筑物或室内按照一定的思路和风格进行美化的一种活动。就是对对对象进行包装啦~~比如有一天你带着女朋友逛街,女朋友说“我要喝HouseBlend!!”虽然有点贵但是没办法啊!! 这时女朋友说“啧!! 太难喝了!!,我要加Milk(牛奶)”。喝了一口。“好像还不合胃口哦~~,我要加这个,我还要加个” (哎~~ 幸亏我没有女朋友哦 哈哈)。咳咳!!我们言归正传。此例子中,被装饰者是HouseBlend,装饰者是 Milk,Mocha,Soy,Whip。大家发现没?不管是HouseBlend还是Milk,Mocha,Soy,Whip,它们都是饮料啊。所以装饰者与被装饰者的类型是一样的,也就是它们有共同的父类。
首先我们应该知道,利用继承设计子类的行为,是在编译时期静态决定的,而且所有的子类都会继承相同的行为(is_a关系)。使用继承无法动态的进行装饰,也不具有扩展性和弹性,而且有时候会导致类爆炸!!所以这种设计模式是死板的,还有如果基类进行改变的话,其所有的子类都必须改变。因此,我们可以使用组合对象动态的达到继承的效果。
装饰者模式的核心思想:动态的将责任附加到对象上。
class CondimentDecorator :public Beverage { //装饰者的行为基类
public:
CondimentDecorator(std::shared_ptr<Beverage> _bp):ptr(_bp),condimentdecoratorname(std::make_unique<std::string>("CondimentDecorator")) {};
public:
void GetDescription()const override;
protected:
std::shared_ptr<Beverage>ptr; //将装饰者与被被装饰者进行组合,可以加入新的装饰对象。
private:
std::shared_ptr<std::string>condimentdecoratorname;
};
void CondimentDecorator::GetDescription()const {
std::cout << condimentdecoratorname->c_str() << std::endl;
}
其类图如下:
完整代码如下:
#include<iostream>
#include<memory>
typedef double PRICE;
class Beverage { //构建装饰者与被装饰者的同一接口(装饰者与被装饰者的父类型相同)
public:
virtual PRICE cost() = 0;
virtual void GetDescription()const = 0;
};
class HouseBlend :public Beverage {
public:
HouseBlend() :houseblend(std::make_unique<std::string>("HouseBlend")) {};
~HouseBlend() {};
public:
PRICE cost()override;
void GetDescription()const override;
private:
std::shared_ptr<std::string>houseblend;
};
PRICE HouseBlend::cost() {
return 1.0;
}
void HouseBlend::GetDescription()const {
std::cout << houseblend->c_str() << " ";
}
class DarkRoast :public Beverage {
public:
DarkRoast() :darkroastname(std::make_unique<std::string>("DarkRoast")) {};
~DarkRoast() {};
public:
PRICE cost()override;
void GetDescription()const override;
private:
std::shared_ptr<std::string>darkroastname;
};
PRICE DarkRoast::cost() {
return 2.0;
}
void DarkRoast::GetDescription()const {
std::cout << darkroastname->c_str() << std::endl;
}
class Espresso :public Beverage {
public:
Espresso() :espressoname(std::make_unique<std::string>("Espresso")) {};
~Espresso() {};
public:
PRICE cost()override;
void GetDescription()const override;
private:
std::shared_ptr<std::string>espressoname;
};
PRICE Espresso::cost(){
return 3.0;
}
void Espresso::GetDescription()const {
std::cout << espressoname->c_str() << std::endl;
}
class Decaf :public Beverage {
public:
Decaf() :decafname(std::make_unique<std::string>("Decaf")) {};
~Decaf() {};
public:
PRICE cost()override;
void GetDescription()const override;
private:
std::shared_ptr<std::string>decafname;
};
PRICE Decaf::cost() {
return 4.0;
}
void Decaf::GetDescription()const {
std::cout << decafname->c_str() << std::endl;
}
class CondimentDecorator :public Beverage { //装饰者的行为基类
public:
CondimentDecorator(std::shared_ptr<Beverage> _bp):ptr(_bp),condimentdecoratorname(std::make_unique<std::string>("CondimentDecorator")) {};
public:
void GetDescription()const override;
protected:
std::shared_ptr<Beverage>ptr;
private:
std::shared_ptr<std::string>condimentdecoratorname;
};
void CondimentDecorator::GetDescription()const {
std::cout << condimentdecoratorname->c_str() << std::endl;
}
class Milk :public CondimentDecorator {
public:
Milk(std::shared_ptr<Beverage> _bp) :CondimentDecorator(_bp), milkname(std::make_shared<std::string>("Milk")) {};
~Milk() {};
public:
PRICE cost()override;
void GetDescription()const override;
public:
std::shared_ptr<std::string>milkname;
};
PRICE Milk::cost(){
return 5.0 + ptr->cost();
}
void Milk::GetDescription()const {
std::cout << milkname->c_str() << " ";
}
class Mocha :public CondimentDecorator {
public:
Mocha(std::shared_ptr<Beverage> _bp) :CondimentDecorator(_bp), mochaname(std::make_unique<std::string>("Mocha")) {};
~Mocha() {};
public:
PRICE cost()override;
void GetDescription()const override;
private:
std::shared_ptr<std::string>mochaname;
};
PRICE Mocha::cost() {
return 6.0 + ptr->cost();
}
void Mocha::GetDescription()const {
std::cout << mochaname->c_str() << " ";
}
class Soy :public CondimentDecorator {
public:
Soy(std::shared_ptr<Beverage>_sp) :CondimentDecorator(_sp), soyname(std::make_unique<std::string>("Soy")) {};
~Soy() {};
public:
PRICE cost()override;
void GetDescription()const override;
private:
std::shared_ptr<std::string>soyname;
};
PRICE Soy::cost() {;
return 7.0 + ptr->cost();
}
void Soy::GetDescription()const {
std::cout << soyname->c_str() << " ";
}
class Whip :public CondimentDecorator {
public:
Whip(std::shared_ptr<Beverage>_wp) :CondimentDecorator(_wp), whipname(std::make_unique<std::string>("Whip")) {};
~Whip() {};
public:
PRICE cost()override;
void GetDescription()const override;
private:
std::shared_ptr<std::string>whipname;
};
PRICE Whip::cost() {
return 8.0 + ptr->cost();
}
void Whip::GetDescription()const {
std::cout << whipname->c_str() << " ";
}
int main(void)
{
std::shared_ptr<HouseBlend>houseblend(std::make_shared<HouseBlend>()); //我要喝HouseBlend(被装饰者)
houseblend->GetDescription();
std::cout << "houseblend price: " << houseblend->cost() << std::endl;
std::cout << std::endl;
std::shared_ptr<Milk>milk(std::make_shared<Milk>(houseblend)); // 加入milk(装饰者)
milk->GetDescription();
std::cout << "add milk price: " << milk->cost() << std::endl;
std::cout << std::endl;
std::shared_ptr<Mocha>mocha(std::make_shared<Mocha>(milk)); //加入mocha(装饰者)
mocha->GetDescription();
std::cout << "add mocha price: " << mocha->cost() << std::endl;
std::cout << std::endl;
std::shared_ptr<Soy>soy(std::make_shared<Soy>(mocha)); //加入soy(装饰者)
soy->GetDescription();
std::cout << "add soy price: " << soy->cost() << std::endl;
std::cout << std::endl;
std::shared_ptr<Whip>whip(std::make_shared<Whip>(soy)); //加入whip(装饰者)
whip->GetDescription();
std::cout << "add whip price: " << whip->cost() << std::endl;
std::cout << std::endl;
auto price = whip->cost();
std::cout << "All Price: " << price << std::endl;
system("pause");
return 0;
}