例子改编自《设计者模式解析(第二版)》214页,人民邮电出版社
意图:动态的给一个对象添加职责;即提供了“即插即用”方法,不用重新编译已有部分。
问题:要使用的对象将执行所需的基本功能。但是,可能需要为这个对像添加某些功能,这些附加的功能可能发生在对象的基本功能之前或之后。
解决方案:可以无需创建子类而扩展一个对象的功能
优点:类的层次结构大小和复杂度有了很大程度的降低
缺点:
1)如果装饰者本身是被装饰的,那么访问装饰模式中引进的特性将是非常困难的甚至是危险的。
2)系统对装饰者的使用顺序是敏感的。
附:显然,如果要更改被装饰者的基本功能的情况是不能用装饰者模式的。
参考文献:
[1]《设计者模式解析(第二版)》,人民邮电出版社,Alan Shalloway等著,徐言生译
[2]《设计模式初学者指南》,机械工业出版社,Allen Holub著,徐迎晓译
对示例的描述:
1)具体组件SalesTicket(即被装饰者)实现基本功能(即打印票据正文),需要给它加个表头和表尾,于是用两个具体装饰类Header和Footer完成附加功能。
2)例子改编自参考文献[1],不明白可以看。
3)使用编译器vc6.0通过。
view plaincopy to clipboardprint?
#include <iostream>
using namespace std;
//=================================================
class Component //抽象组件,即对象的接口
{
public:
virtual void prtTicket() = 0;
};
//=================================================
//具体组件,即被装饰者
class SalesTicket: public Component
{
public:
//SalesTicket()
//{
// cout<<"构造具体组件SalesTicket/n"<<endl;
//}
void prtTicket()
{
cout<<"具体组件SalesTicket打印票据正文/n"<<endl;
}
};
//=================================================
//装饰者(也是抽象组件的子类)
class TicketDecorator: public Component
{
private:
Component* pMyTrailer;//抽象组件作为成员变量
public:
TicketDecorator(Component& myComponent)//实际使用时,传入构造函数的是具体组件(即被装饰者)
{
//cout<<"构造装饰者TicketDecorator/n"<<endl;
pMyTrailer = NULL;
pMyTrailer = &myComponent;
}
void callTrailer()
{
if(pMyTrailer != NULL)
pMyTrailer->prtTicket();
}
//是否需要释放pMyTrailer??????
//如果遵循“谁申请,谁释放”的原则,则不需要
};
//=================================================
//具体装饰者Header(是装饰者的子类)
//功能:打印表头
class Header: public TicketDecorator
{
public:
Header(Component& myComponent):TicketDecorator(myComponent)
{
//cout<<"构造具体装饰者Header/n"<<endl;
}
void prtTicket()
{
//功能:在表的前面加个头部
//注意这行代码的位置,在callTrailer()之前
//这是装饰者添加的功能
cout<<"具体装饰者Header打印表头/n"<<endl;
TicketDecorator::callTrailer();
}
};
//具体装饰者Footer(是装饰者的子类)
//功能:打印表尾
class Footer: public TicketDecorator
{
public:
Footer(Component& myComponent):TicketDecorator(myComponent)
{
//cout<<"构造具体装饰者Footer/n"<<endl;
}
void prtTicket()
{
//功能:在表的后面加个尾部
TicketDecorator::callTrailer();
//注意这行代码的位置,在callTrailer()之后
//这是装饰者添加的功能
cout<<"具体装饰者Footer打印表尾/n"<<endl;
}
};
//=================================================
class Factory//工厂
{
public:
Component* m_pMyComponent;
Component* m_pMyFooter;
Component* m_pMyHeader;
Factory()
{
Component* m_pMyComponent = NULL;
Component* m_pMyFooter = NULL;
Component* m_pMyHeader = NULL;
}
Component* getComponent()
{
m_pMyComponent = new SalesTicket();
m_pMyFooter = new Footer(*m_pMyComponent);
m_pMyHeader = new Header(*m_pMyFooter);
return m_pMyHeader;//返回最后一个指针
}
~Factory()//别忘了释放空间
{
delete m_pMyComponent;
delete m_pMyFooter;
delete m_pMyHeader;
}
};
//=================================================
int main(int argc, char* argv[])
{
//使用
Factory myFactory;
Component* pMyComponent = myFactory.getComponent();
pMyComponent->prtTicket();//打印
return 0;
}
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/hityct1/archive/2007/11/30/1909564.aspx