23种设计模式(C++)之 装饰器(Decorator)模式
23种设计模式(C++)之 装饰器(Decorator)模式
意图
动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator模式相比生成子类更为灵活。
场景
比如一件上衣,它可以添加不同的装饰品,如口袋,拉链等。对于上衣来说,装饰品是多种多样的,如果采用继承的方式创建衣服类,衣服类会随着装饰品的增多而变得非常庞大且不易改动。因此,采用动态的方式给衣服对象添加删除装饰器是一种不错的思路。
角色
- Component
- 定义一个对象接口,可以给这些对象动态地添加职责。
- ConcreteComponent
- 定义一个对象接口,可以给这个对象添加一些职责。
- Decorator
- 维持一个指向Component对象的指针,并定义一个与Component接口一致的接口。
- ConcreteDecorator
- 向组件添加职责。
实例
以Car为例,车可以添加车衣,车座等装饰品。
- 创建Car抽象接口
class Car
{
public:
string description;
virtual void makeCar() = 0;
virtual void setDescription(string desc)
{
this->description = desc;
};
virtual string readDescription()
{
return this->description;
}
};
- 具体化为electric car和oil car
class ElectricCar : public Car
{
public:
void makeCar()
{
this->description = "Make electric car ";
//cout << this->description << endl;
}
};
class OilCar : public Car
{
public:
void makeCar()
{
this->description = "Make oil car ";
cout << this->description << endl;
}
};
- 创建装饰器接口
class CarDecorator : public Car
{
protected:
Car *car;
};
- 具体化装饰器
class CarCover : public CarDecorator
{
public:
void addDecorator()
{
setDescription(readDescription() + "with car cover ");
//cout << readDescription() << endl;
}
void setDescription(string desc)
{
this->car->setDescription(desc);
};
string readDescription()
{
//Don't use car->description
return this->car->readDescription();
}
CarCover(Car *car)
{
this->car = car;
}
void makeCar()
{
this->car->makeCar();
addDecorator();
}
};
class CarSaddle : public CarDecorator
{
public:
void addDecorator()
{
setDescription(readDescription() + "with car saddle ");
}
void setDescription(string desc)
{
this->car->setDescription(desc);
};
string readDescription()
{
return this->car->readDescription();
}
CarSaddle(Car *car)
{
//cout << car->readDescription() << endl;
this->car = car;
}
void makeCar()
{
this->car->makeCar();
addDecorator();
}
};
- 测试
int main()
{
Car *electricCar = new ElectricCar();
electricCar = new CarCover(electricCar);
electricCar = new CarSaddle(electricCar);
electricCar->makeCar();
cout << electricCar->readDescription() << endl;
}
- 结果
Make electric car with car cover with car saddle