C++ 设计模式之装饰器模式
简介
1、装饰器模式(Decorator)是一种结构性设计模式,主要用于动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。
2、装饰器模式 (Decorator)应用场景包括但不限于:
2.1、当需要给一个对象动态地增加功能,且这些功能可能在未来会经常变化时。
2.2、当需要给一批兄弟类添加功能,而不是整个继承体系时。
2.3、想要为一个类添加一些职责,但是又不能影响其他类时。
3、装饰器模式 (Decorator)的构成
3.1、抽象组件
class Coffee
{
public:
virtual std::string GetDescription() = 0;
virtual double GetCost() = 0;
virtual ~Coffee() = default;
};
3.2、具体组件
class SimpleCoffee :public Coffee
{
public:
std::string GetDescription();
double GetCost();
};
3.3、抽象装饰器
class CoffeeDecorator : public Coffee
{
public:
CoffeeDecorator(Coffee* coffee);
virtual ~CoffeeDecorator();
protected:
Coffee* coffeeDecorator;
};
3.4、具体装饰器
class MilkDecorator :public CoffeeDecorator
{
public:
MilkDecorator(Coffee* coffee);
std::string GetDescription();
double GetCost();
};
4、装饰器模式 (Decorator)的优点
4.1、更好的扩展性:不需要通过继承来扩展功能,减少了子类的创建,使系统更加灵活,可以动态添加或删除功能。
4.2、更好的复用性:可以在不同的情况下组合不同的装饰类,实现不同的功能,提高代码的复用性。
4.3、更好的分离性:将核心职责与装饰功能分离,遵守了单一职责原则。
5、装饰器模式 (Decorator)的缺点
5.1、会产生很多小对象:大量使用装饰器会导致设计中有许多的小对象,过度使用可能会导致理解和维护困难。
5.2、高层次复杂性:虽然易于扩展,但装饰链的建立可能会增加系统的复杂性。
简单示例
1、定义
// 抽象组件
class Coffee
{
public:
virtual std::string GetDescription() = 0;
virtual double GetCost() = 0;
virtual ~Coffee() = default;
};
// 具体组件
class SimpleCoffee :public Coffee
{
public:
std::string GetDescription();
double GetCost();
};
// 抽象装饰器
class CoffeeDecorator : public Coffee
{
public:
CoffeeDecorator(Coffee* coffee);
virtual ~CoffeeDecorator();
protected:
Coffee* coffeeDecorator;
};
// 具体装饰器
class MilkDecorator :public CoffeeDecorator
{
public:
MilkDecorator(Coffee* coffee);
std::string GetDescription();
double GetCost();
};
// 另一个具体装饰器
class SugarDecorator :public CoffeeDecorator
{
public:
SugarDecorator(Coffee* coffee);
std::string GetDescription();
double GetCost();
};
2、实现
std::string SimpleCoffee::GetDescription()
{
return "Simple Coffee";
}
double SimpleCoffee::GetCost()
{
return 10.0;
}
CoffeeDecorator::CoffeeDecorator(Coffee* coffee) : coffeeDecorator(coffee)
{
}
CoffeeDecorator::~CoffeeDecorator()
{
delete coffeeDecorator;
}
MilkDecorator::MilkDecorator(Coffee* coffee) : CoffeeDecorator(coffee)
{
}
std::string MilkDecorator::GetDescription()
{
return coffeeDecorator->GetDescription() + ", with milk";
}
double MilkDecorator::GetCost()
{
return coffeeDecorator->GetCost() + 2.0;
}
SugarDecorator::SugarDecorator(Coffee* coffee) : CoffeeDecorator(coffee)
{
}
std::string SugarDecorator::GetDescription()
{
return coffeeDecorator->GetDescription() + ", with sugar";
}
double SugarDecorator::GetCost()
{
return coffeeDecorator->GetCost() + 1.0;
}
3、调用
Coffee* coffee = new SimpleCoffee();
std::cout << "Cost: " << coffee->GetCost() << "; Description: " << coffee->GetDescription() << std::endl;
Coffee* milk = new MilkDecorator(coffee);
std::cout << "Cost: " << milk->GetCost() << ", Description: " << milk->GetDescription() << std::endl;
Coffee* sugarMilk = new SugarDecorator(milk);
std::cout << "Cost: " << sugarMilk->GetCost() << ", Description: " << sugarMilk->GetDescription() << std::endl;
delete sugarMilk;