[设计模式]结构模式-装饰器模式(C++描述)
[设计模式]结构模式-装饰器模式(C++描述)
second60 20180429
1. 什么是装饰器
当我们为一个现有类A添加新的职责时,我们可能会定义新类B继承现有类,再添加新的操作。但是通过继承会使问题变得越来越复杂,如果类B又有新操作时,是否又在定义个类C来继承B呢?这样加深了继承的复杂度和深度,代码也越来越难维护。
装饰器就是为了解决新加类职责,继承实现的弊端,而是通过组合来实现。
2. 装饰器结构图
Component: 抽象构件角色,功能类和装饰器的基类。(真实对象和装饰对象有相同接口)
ConcreteComponent: 构件实现类。
Decorator: 装饰类,持有一个抽象构件的引用。接受客户端的请求。
ConcreteDecorator: 装饰实现类,负责对构件对象新加操作。
代码:
// 抽象构件基类
class Component
{
public:
virtual ~Component(){}
virtual void operation(){}
};
// 构件实现类
ConcreteComponent: public Component
{
public:
virtual void operation(){cout << “ConcreteComponent::operation” << endl;}
};
//装饰器
Decorator: public Component
{
public:
Decorator(Component *component){ _component=component; }
virtual void operation(){cout << “Decorator::operation”<< endl;}
private:
Component *_component;
};
// 具体装饰器
ConcreteDecorator: public Decorator
{
public:
ConcreteDecorator(Component* component):Decorator(component){}
void operation(){cout << “ConcreteDecorator::operation” endl;}
void new_operation(){cout << “ConcreteDecorator::new_operation” endl;}
}
3 例子
现有一类汽车,汽车可以跑,但现在需求增加,要求汽车,可以有水里游的功能,也有汽车可以飞行的功能。
分析:
1. 这里的水里游和飞的汽车,是在原有的汽车上的装饰,所以可以用装饰模式来实现。
2. 水里流和飞的汽车,有一个抽象类汽车类,可以扩展汽车的原有功能。
代码:
// 汽车抽象类
class CarComponent
{
public:
virtual ~CarComponent(){}
virtual void move();
};
// 普通汽车
class CommonCar: public CarComponent
{
public:
void move(){cout << “CommonCar::move” << endl;}
};
// 汽车装饰类
class DecoratorCar: public CarComponent
{
public:
DecoratorCar(CarComponent *carComponent){_carComponent = carComponent;}
virtual void move(){_carComponent->move();}
private:
CarComponent *_carComponent;
};
// 会游水的车
class SwimCar: public DecoratorCar
{
public:
SwimCar(CarComponent *carComponent): DecoratorCar(carComponent){}
void move()
{
DecoratorCar::move();
swim();
}
void swim(){cout << “swim” << endl;}
}
//会飞的车
class FlyCar: public DecoratorCar
{
public:
FlyCar(CarComponent *carComponent): DecoratorCar(carComponent){}
void move()
{
DecoratorCar::move();
fly();
}
void fly(){cout << “fly” << endl;}
}
// 使用
int main()
{
// 普通汽车
CommonCar *commonCar = new CommonCar();
commonCar->move();
// 装饰让汽车能游
SwimCar *swimCar = new SwimCar(car);
swimCar->move();
//装饰让汽车会飞
FlyCar *flyCar = new FlyCar(car);
flyCar->move();
return 0;
}
分析:
现有的普通汽车,只需加装饰,即可添加不同的功能,同时,如果需要添加更多的操作,只需新加装饰子类即可。
4 优点
a) 扩展对象功能,用组合的方式实现,减少类的个数
b) 可以对一个对象多次装饰,创造出不同行为的组合,得到功能更强大的对象
c) 具体构建类和具体装饰类,可以独立变化,可根据需求增加子类
5 缺点
a) 装饰模式复杂理解难,排查问题麻烦
6 装饰模式和桥接模式
相同点:
a) 桥接模式是多个可变维度,通过组合,减少类的方法(类维度扩展)
b) 装饰模式是为现有类添加职责,通过组合,减少类的方法(类操作扩展)
7 总结
装饰模式,降低了系统的耦合度,可以动态的增加或删除对象的职责,并使得需要装饰的具体构建类和具体装饰类可以独立变化,以便增加新的具体构建类和具体装饰类。