[设计模式]结构模式-装饰器模式(C++描述)
[设计模式]结构模式-装饰器模式(c++描述)
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 总结
装饰模式,降低了的耦合度,可以动态的增加或删除对象的职责,并使得需要装饰的具体构建类和具体装饰类可以独立变化,以便增加新的具体构建类和具体装饰类。