您的位置:首页 > 编程语言 > C语言/C++

c++设计模式:装饰者模式(Decorator Pattern)

2013-04-06 19:12 615 查看
定义:

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

场景:

我们购买咖啡的时候,可以要求在其中加入各种调料,例如:蒸奶、豆浆、摩卡或覆盖奶泡,而咖啡店也会根据所加入的调料收取不同的费用,所以当我们设计订单系统的时候就需要考虑到这些调料部分啦。顾客的需求不一,如果我们针对每种配方都声明一个类得话,系统的维护将会十分头疼。此时装饰者模式就派上用场啦。我们可以根据顾客的需要动态的扩展顾客定制的咖啡,让其加上不同的调料,最终计算出顾客所需缴纳的费用。它的实现有点类似于递归,在实际使用的时候可以慢慢体会。

类图:



c++代码如下:

不使用指针版本:



#include <iostream>
#include <string>
using namespace std;

class Beverage
{
public:
virtual ~Beverage() {};
virtual string getDescription(); // 必须是虚函数,否则会造成后期使用时描述显示不正确
virtual double cost() = 0;
protected:
string m_description;
};

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

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

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

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

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

class Mocha:public CondimentDecorator
{
public:
Mocha(Beverage* pBeverage);
string getDescription();
double cost();
protected:
Beverage* m_pBeverage;
};

class Milk:public CondimentDecorator
{
public:
Milk(Beverage* pBeverage);
string getDescription();
double cost();
protected:
Beverage* m_pBeverage;
};

class Soy:public CondimentDecorator
{
public:
Soy(Beverage* pBeverage);
string getDescription();
double cost();
protected:
Beverage* m_pBeverage;
};

class Whip:public CondimentDecorator
{
public:
Whip(Beverage* pBeverage);
string getDescription();
double cost();
protected:
Beverage* m_pBeverage;
};

string Beverage::getDescription()
{
return m_description;
}

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

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

HouseBlend::HouseBlend()
{
m_description = "House Blend Coffee";
}

double HouseBlend::cost()
{
return 0.89;
}

DarkRoast::DarkRoast()
{
m_description = "Dark Roast Coffee";
}

double DarkRoast::cost()
{
return 0.99;
}

Decaf::Decaf()
{
m_description = "Decaf Coffee";
}

double Decaf::cost()
{
return 1.05;
}

Mocha::Mocha(Beverage* pBeverage)
{
m_pBeverage = pBeverage;
}

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

double Mocha::cost()
{
return 0.20 + m_pBeverage->cost();
}

Milk::Milk(Beverage* pBeverage)
{
m_pBeverage = pBeverage;
}

string Milk::getDescription()
{
return m_pBeverage->getDescription() + " + Milk";
}

double Milk::cost()
{
return 0.10 + m_pBeverage->cost();
}

Soy::Soy(Beverage* pBeverage)
{
m_pBeverage = pBeverage;
}

string Soy::getDescription()
{
return m_pBeverage->getDescription() + " + Soy";
}

double Soy::cost()
{
return 0.15 + m_pBeverage->cost();
}

Whip::Whip(Beverage* pBeverage)
{
m_pBeverage = pBeverage;
}

string Whip::getDescription()
{
return m_pBeverage->getDescription() + " + Whip";
}

double Whip::cost()
{
return 0.10 + m_pBeverage->cost();
}

int main()
{
Espresso espresso;
cout << espresso.getDescription() << " $" << espresso.cost() << endl;

DarkRoast darkRoast;
Mocha mocha1(&darkRoast);
Mocha mocha2(&mocha1);
Whip whip1(&mocha2);
cout << whip1.getDescription() << " $" << whip1.cost() << endl;

HouseBlend houseBlend;
Soy soy1(&houseBlend);
Mocha mocha3(&soy1);
Whip whip2(&mocha3);
cout << whip2.getDescription() << " $" << whip2.cost() << endl;

return 0;
}




使用指针版本:



#include <iostream>
#include <string>
using namespace std;

class Beverage
{
public:
virtual ~Beverage() {};
virtual string getDescription();
virtual double cost() = 0;
protected:
string m_description;
};

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

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

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

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

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

class Mocha:public CondimentDecorator
{
public:
Mocha(Beverage* pBeverage);
~Mocha();
string getDescription();
double cost();
protected:
Beverage* m_pBeverage;
};

class Milk:public CondimentDecorator
{
public:
Milk(Beverage* pBeverage);
~Milk();
string getDescription();
double cost();
protected:
Beverage* m_pBeverage;
};

class Soy:public CondimentDecorator
{
public:
Soy(Beverage* pBeverage);
~Soy();
string getDescription();
double cost();
protected:
Beverage* m_pBeverage;
};

class Whip:public CondimentDecorator
{
public:
Whip(Beverage* pBeverage);
~Whip();
string getDescription();
double cost();
protected:
Beverage* m_pBeverage;
};

string Beverage::getDescription()
{
return m_description;
}

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

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

HouseBlend::HouseBlend()
{
m_description = "House Blend Coffee";
}

double HouseBlend::cost()
{
return 0.89;
}

DarkRoast::DarkRoast()
{
m_description = "Dark Roast Coffee";
}

double DarkRoast::cost()
{
return 0.99;
}

Decaf::Decaf()
{
m_description = "Decaf Coffee";
}

double Decaf::cost()
{
return 1.05;
}

Mocha::Mocha(Beverage* pBeverage)
{
m_pBeverage = pBeverage;
}

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

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

double Mocha::cost()
{
return 0.20 + m_pBeverage->cost();
}

Milk::Milk(Beverage* pBeverage)
{
m_pBeverage = pBeverage;
}

Milk::~Milk()
{
delete m_pBeverage;
}

string Milk::getDescription()
{
return m_pBeverage->getDescription() + " + Milk";
}

double Milk::cost()
{
return 0.10 + m_pBeverage->cost();
}

Soy::Soy(Beverage* pBeverage)
{
m_pBeverage = pBeverage;
}

Soy::~Soy()
{
delete m_pBeverage;
}

string Soy::getDescription()
{
return m_pBeverage->getDescription() + " + Soy";
}

double Soy::cost()
{
return 0.15 + m_pBeverage->cost();
}

Whip::Whip(Beverage* pBeverage)
{
m_pBeverage = pBeverage;
}

Whip::~Whip()
{
delete m_pBeverage;
}

string Whip::getDescription()
{
return m_pBeverage->getDescription() + " + Whip";
}

double Whip::cost()
{
return 0.10 + m_pBeverage->cost();
}
int main()
{
Beverage* pBeverage = new Espresso();
cout << pBeverage->getDescription() << " $" << pBeverage->cost() << endl;

Beverage* pBeverage2 = new DarkRoast();
pBeverage2 = new Mocha(pBeverage2);
pBeverage2 = new Mocha(pBeverage2);
pBeverage2 = new Whip(pBeverage2);
cout << pBeverage2->getDescription() << " $" << pBeverage2->cost() << endl;

Beverage* pBeverage3 = new HouseBlend();
pBeverage3 = new Soy(pBeverage3);
pBeverage3 = new Mocha(pBeverage3);
pBeverage3 = new Whip(pBeverage3);
cout << pBeverage3->getDescription() << " $" << pBeverage3->cost() << endl;
delete pBeverage;
delete pBeverage2;
delete pBeverage3;
return 0;
}




运行后结果如下:

Espresso $1.99

Dark Roast Coffee + Mocha + Mocha + Whip $1.49

House Blend Coffee + Soy + Mocha + Whip $1.34

参考图书:《Head First 设计模式》
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: