Decorator装饰模式详解--设计模式(8)
来源:互联网 发布:伊藤润二漫画软件 编辑:程序博客网 时间:2024/06/06 12:29
Decorator装饰模式产生原因:
在OO设计和开发过程,可能会经常遇到以下的情况:我们需要为一个已经定义好的类添加新的职责(操作),通常的情况我们会给定义一个新类继承自定义好的类,这样会带来一个问题(将在本模式的讨论中给出)。通过继承的方式解决这样的情况还带来了系统的复杂性,因为继承的深度会变得很深。
Decorator装饰模式作用:
Decorator提供了一种给类增加职责的方法,不是通过继承实现的,而是通过组合。这样就大大降低了基类的复杂性!
Decorator装饰模式典型的UML结构图如图1所示:
在结构图中,ConcreteComponent和Decorator需要有同样的接口,因此ConcreteComponent和Decorator有着一个共同的父类。这里有人会问,让Decorator直接维护一个指向ConcreteComponent引用(指针)不就可以达到同样的效果,答案是肯定并且是否定的。肯定的是你可以通过这种方式实现,否定的是你不要用这种方式实现,因为通过这种方式你就只能为这个特定的ConcreteComponent提供修饰操作了,当有了一个新的ConcreteComponent你又要去新建一个Decorator来实现。但是通过结构图中的ConcreteComponent和Decorator有一个公共基类,就可以利用OO中多态的思想来实现只要是Component型别的对象都可以提供修饰操作的类,这种情况下你就算新建了100个Component型别的类ConcreteComponent,也都可以由Decorator一个类搞定。这也正是Decorator模式的关键和威力所在了。
当然如果你只用给Component型别类添加一种修饰,则Decorator这个基类就不是很必要了。
Decorator装饰模式典型的示例代码如下:
Decorator.h
#ifndef _DECORATOR_H_#define _DECORATOR_H_//Component抽象类,定义该类对象的接口class Component{public: virtual ~Component(); virtual void Operation()=0;protected: Component();};//ConcreteDecorator:具体的Component对象,可以给该对象动态 添加职责class ConcreteComponent:public Component{public: ConcreteComponent(); ~ConcreteComponent(); virtual void Operation();};//Decorator:装饰抽象类,继承自Componentclass Decorator:public Component{public: Decorator(Component* com); void SetComponent(Component* com); virtual ~Decorator(); virtual void Operation();protected: Component* _com;};//ConcreteDecorator就是具体的装饰对象之一,起到给Component添加职责的功能class ConcreteDecoratorA:public Decorator{public: ConcreteDecoratorA(Component* com); ~ConcreteDecoratorA(); virtual void Operation(); void AddBehavorA();};//ConcreteDecorator就是具体的装饰对象之二,起到给Component添加职责的功能class ConcreteDecoratorB:public Decorator{public: ConcreteDecoratorB(Component* com); ~ConcreteDecoratorB(); virtual void Operation(); void AddBehavorB();};//ConcreteDecorator就是具体的装饰对象之三,起到给Component添加职责的功能class ConcreteDecoratorC:public Decorator{public: ConcreteDecoratorC(Component* com); ~ConcreteDecoratorC(); virtual void Operation(); void AddBehavorC();};//只添加一种装饰,则不用抽象出装饰基类class DecoratorOnlyOne:public Component{public: DecoratorOnlyOne(Component* com); ~DecoratorOnlyOne(); virtual void Operation(); void AddBehavor();private: Component* _com;};//如果只有一个ConcreteComponent类而没有抽象的Component类,那么Decorator类可以是ConcreteComponent的一个子类。//略#endif
Decorator.cpp
#include "Decorator.h"#include <iostream>using namespace std;Component::Component(){}Component::~Component(){ cout << "~Component" << endl;}ConcreteComponent::ConcreteComponent(){}ConcreteComponent::~ConcreteComponent(){ cout << "~ConcreteComponent" << endl;}void ConcreteComponent::Operation(){ cout << "原职责:ConcreteComponent::Operation" << endl;}Decorator::Decorator(Component* com){ this->_com = com;}void Decorator::SetComponent(Component* com){ this->_com = com;}Decorator::~Decorator(){ cout << "~Decorator" << endl; delete this->_com; this->_com = NULL;}void Decorator::Operation(){}ConcreteDecoratorA::ConcreteDecoratorA(Component* com):Decorator(com){}ConcreteDecoratorA::~ConcreteDecoratorA(){ cout << "~ConcreteDecoratorA" << endl;}void ConcreteDecoratorA::Operation(){ this->_com->Operation(); //附加职责A this->AddBehavorA();}void ConcreteDecoratorA::AddBehavorA(){ cout << "附加职责A:ConcreteDecoratorA::AddBehavorA" << endl;}ConcreteDecoratorB::ConcreteDecoratorB(Component* com):Decorator(com){}ConcreteDecoratorB::~ConcreteDecoratorB(){ cout << "~ConcreteDecoratorB" << endl;}void ConcreteDecoratorB::Operation(){ this->_com->Operation(); //附加职责B this->AddBehavorB();}void ConcreteDecoratorB::AddBehavorB(){ cout << "附加职责B:ConcreteDecoratorB::AddBehavorB" << endl;}ConcreteDecoratorC::ConcreteDecoratorC(Component* com):Decorator(com){}ConcreteDecoratorC::~ConcreteDecoratorC(){ cout << "~ConcreteDecoratorC" << endl;}void ConcreteDecoratorC::Operation(){ this->_com->Operation(); //附加职责C this->AddBehavorC();}void ConcreteDecoratorC::AddBehavorC(){ cout << "附加职责C:ConcreteDecoratorC::AddBehavorC" << endl;}//**************只添加一种修饰******************DecoratorOnlyOne::DecoratorOnlyOne(Component* com):_com(com){}DecoratorOnlyOne::~DecoratorOnlyOne(){ cout << "~DecoratorOnlyOne" << endl; delete this->_com; this->_com = NULL;}void DecoratorOnlyOne::Operation(){ this->_com->Operation(); this->AddBehavor();}void DecoratorOnlyOne::AddBehavor(){ cout << "附加唯一职责:DecoratorOnlyOne::AddBehavor" << endl;}
main.cpp
#include "Decorator.h"#include <iostream>using namespace std;int main(){ Component* pCom = new ConcreteComponent(); //要装饰的对象 Decorator* pDec = NULL; pDec = new ConcreteDecoratorA(pCom); //给装饰对象附加职责A pDec = new ConcreteDecoratorB(pDec); //给装饰对象附加职责B pDec = new ConcreteDecoratorC(pDec); //给装饰对象附加职责C pDec->Operation(); cout << "-------------------------------" << endl; //只添加一种修饰 Component* pCom1 = new ConcreteComponent(); DecoratorOnlyOne* pDec1 = new DecoratorOnlyOne(pCom1); pDec1->Operation(); cout << "-------------------------------" << endl; delete pDec; cout << "-------------------------------" << endl; delete pDec1; return 0;}
Decorator模式使用总结:
Decorator模式和Proxy模式的相似的地方在于它们都拥有一个指向其他对象的引用(指针),即通过组合的方式来为对象提供更多操作(或者Decorator模式)间接性(Proxy模式)。但是他们的区别是,Proxy模式会提供使用其作为代理的对象一样接口,使用代理类将其操作都委托给Proxy直接进行。这里可以简单理解为组合和委托之间的微妙的区别了。
Decorator模式除了采用组合的方式取得了比采用继承方式更好的效果,Decorator模式还给设计带来一种“即用即付”的方式来添加职责。在OO设计和分析经常有这样一种情况:为了多态,通过父类指针指向其具体子类,但是这就带来另外一个问题,当具体子类要添加新的职责,就必须向其父类添加一个这个职责的抽象接口,否则是通过父类指针是调用不到这个方法了。这样处于高层的父类就承载了太多的特征(方法),并且继承自这个父类的所有子类都不可避免继承了父类的这些接口,但是可能这并不是这个具体子类所需要的。而在Decorator模式提供了一种较好的解决方法,当需要添加一个操作的时候就可以通过Decorator模式来解决,你可以一步步添加新的职责。
- Decorator装饰模式详解--设计模式(8)
- 设计模式 - 装饰 Decorator
- Decorator(装饰)设计模式
- 设计模式-装饰模式(Decorator Pattern)
- 设计模式---装饰模式(decorator)
- 设计模式 (十)装饰模式(Decorator)
- 设计模式 (十)装饰模式(Decorator)
- 设计模式 (十)装饰模式(Decorator)
- 【设计模式】之装饰模式(Decorator)
- 设计模式之装饰模式(Decorator)
- 设计模式之 装饰模式(Decorator)
- 设计模式之装饰模式(Decorator)
- Java设计模式---装饰模式(Decorator)
- 设计模式(五):装饰模式(Decorator)
- 设计模式(7)--Decorator 装饰模式
- 设计模式:装饰模式(Decorator)
- 设计模式之装饰(Decorator)模式
- 设计模式:装饰模式(Decorator )
- SQL SERVER 迭代查询
- 栈与队列--获取栈顶/队首数据(并出栈/队)
- JavaScript 有多灵活?
- android:scaleType属性
- SQLSERVER分页通用存储过程
- Decorator装饰模式详解--设计模式(8)
- 关于servlet与HttpServlet的学习心得
- html经典上中下三段的布局设计
- 企业网站建设的重要性和必要性
- 数据结构 稀疏矩阵 重写函数fast_transpose,使其不用两个数组而仅用一个数组存放row_terms和starting_pos
- 异常记录tableCellBlock
- 【网络安全】SSL通信证书生成及作用详解
- 网盘容量反面的技术秘密
- 有趣的机器学习概念纵览:从多元拟合,神经网络到深度学习,给每个感兴趣的人