github地址:https://github.com/lining91/DecoratorPattern
动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式提供了比继承更有弹性的替代方案。为已有功能动态地添加更多功能的一种方式。
装饰模式把每个要装饰的功能放在单独的类中,并让这个类包装所要装饰的对象,当需要执行特殊行为时,可以在运行时根据需要有选择地、按顺序地使用装饰功能包装对象。
利用继承设计子类的行为,是在编译时静态决定的,而且所有的子类都会继承到相同的行为。然而,利用组合的做法来扩展对象的行为,是可以在运行时根据需求动态的进行扩展。
装饰模式使用了对象组合,防止出现继承滥用的问题。
问题描述:
星巴克咖啡有多种具体类型的咖啡(如DarkRoast、Espresso等),需要加入不同的调料(如Mocha、Soy、Whip等)。
代码如下:
公共抽象类:
// 饮料基类
class CBevarage
{
public:
virtual string getDescription( )
{
return desc;
}
virtual ~CBevarage(){}
public:
virtual int cost( ) = 0;
public:
string desc;
};
具体的饮料类:
// 具体饮料DarkRoast类
class CDarkRoast : public CBevarage
{
public:
CDarkRoast( )
{
desc = "DarkRoast";
}
int cost( )
{
return 8;
}
};
// 具体饮料Espresso类
class CEspresso : public CBevarage
{
public:
CEspresso( )
{
desc = "Espresso";
}
int cost( )
{
return 7;
}
};
装饰类:
// 调料装饰类
class CCondimentDecorator : public CBevarage
{
public:
virtual string getDescription( ) = 0;
};
// 调料Mocha类
class CMocha : public CCondimentDecorator
{
public:
CMocha( CBevarage* pValue ) : pBevarage( pValue )
{
}
string getDescription( )
{
return pBevarage->getDescription() + ", Mocha";
}
int cost( )
{
return pBevarage->cost() + 2;
}
public:
CBevarage* pBevarage;
};
// 调料Soy类
class CSoy : public CCondimentDecorator
{
public:
CSoy( CBevarage* pValue ) : pBevarage( pValue )
{
}
string getDescription( )
{
return pBevarage->getDescription() + ", Soy";
}
int cost( )
{
return pBevarage->cost() + 3;
}
public:
CBevarage* pBevarage;
};
//// 调料Whip类
class CWhip : public CCondimentDecorator
{
public:
CWhip( CBevarage* pValue ) : pBevarage( pValue )
{
}
string getDescription( )
{
return pBevarage->getDescription() + ", Whip";
}
int cost( )
{
return pBevarage->cost() + 3;
}
public:
CBevarage* pBevarage;
};
main文件:
void main()
{
cout << "第一种饮料:" << endl;
CBevarage* pDarkRoast = new CDarkRoast();
pDarkRoast = new CMocha( pDarkRoast );
pDarkRoast = new CWhip( pDarkRoast );
cout << "材料有:" << pDarkRoast->getDescription() << endl;
cout << "价格:" << pDarkRoast->cost() << endl;
cout << "第二种饮料:" << endl;
CBevarage* pEspresso = new CEspresso();
pEspresso = new CWhip( pEspresso );
pEspresso = new CSoy( pEspresso );
cout << "材料有:" << pEspresso->getDescription() << endl;
cout << "价格:" << pEspresso->cost() << endl;
system( "pause" );
return;
}
运行结果如下: