Decorator装饰模式——对象结构模式
1.意图
动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator模式相比生成子类更为灵活
2.适用性
- 在不影响其他对象的情况下,以动态、透明的方法给单个对象添加职责
- 处理那些可以撤销的职责
- 当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类
3.结构
4.参与者
- Component
—— 定义一个对象接口,可以给这些对象动态地添加职责
- ConcreteComponent
—— 维持一个指向Component对象的指针,并定义一个与Component接口一致的接口
- ConcreteDecorator
—— 向组件添加职责
5.效果
优点:
1)比静态继承更灵活,提供了更加灵活的向对象添加职责的方式。
2)避免在层次结构高层的类有太多的特征,可以定义一个简单的类并用Decorator类逐渐添加功能,可以用简单的部件组合出复杂的功能。
缺点:
3)Decorator与它的Component不一样Decorator是一个透明的包装
4)有许多小对象
6.相关模式
Adapter模式:Decorator模式不同于Adapter模式,因为装饰仅改变对象的职责而不改变它的接口;而适配器将给对象一个全新的接口
Composite模式:可以将装饰视为一个退化的、仅有一个组件的组合。然而,装饰仅给对象添加一些额外的职责——它的目的不在于对象聚集
Strategy模式:用一个装饰你可以改变对象的外表;而Strategy模式使得你可以改变对象的内核。这是改变对象的两种途径
7.例子
编辑器功能
#include <iostream>
#include <windows.h>
using namespace std;
class CView
{
public:
virtual void Draw(void) {}
};
//抽象装饰类
class CDecorate :public CView
{
public:
CDecorate(CView* pView) :m_pView(pView) {}
virtual void Draw(void) { m_pView->Draw(); }
private:
CView* m_pView;
};
class CScrollBars :public CDecorate
{
public:
CScrollBars(CView* pView) :CDecorate(pView) {}
protected:
//绘制滚动条
void DrawScrollBars() { cout << ">绘制了一个滚动条" << endl; }
public:
virtual void Draw()
{
CDecorate::Draw();
DrawScrollBars();
}
};
class CBorder :public CDecorate
{
public:
CBorder(CView* pView) :CDecorate(pView) {}
protected:
//绘制滚动条
void DrawBorder() { cout << ">绘制了一个边框" << endl; }
public:
virtual void Draw()
{
CDecorate::Draw();
DrawBorder();
}
};
//context->主要的被装饰对象
class CTextView :public CView
{
public:
CTextView(const char* s) { SetWindowText(s); }
protected:
virtual void DrawTextView() { cout << ">绘制了一个文本视图,文本的内容为" << m_Text; }
protected:
char m_Text[MAX_PATH];
public:
virtual void Draw()
{
CView::Draw();
DrawTextView();
}
void SetWindowText(const char* s) { strcpy_s(m_Text, _countof(m_Text), s); }
char* GetWindowText() { return m_Text; }
};
class CWindows
{
public:
CWindows() { ZeroMemory(m_arrWindow, sizeof(CView*) * 10); }
void Draw()
{
for (int i = 0; i < 10; i++)
{
if (m_arrWindow[i] != NULL)
{
m_arrWindow[i]->Draw();
}
}
}
void AddControl(CView * pView)
{
for (int i = 0; i < 10; i++)
{
if (m_arrWindow[i] == NULL)
{
m_arrWindow[i] = pView;
break;
}
}
}
void RemoveControl(CView * pView)
{
for (int i = 0; i < 10; i++)
{
if (m_arrWindow[i] == pView)
{
m_arrWindow[i] = NULL;
break;
}
}
}
protected:
CView* m_arrWindow[10];
};
int main(void)
{
//定义一个窗口对象
CWindows windowsObj;
//定义一个普通的文本视图
CTextView TextView("我是一个文本视图");
windowsObj.AddControl(&TextView);
windowsObj.Draw();
cout << "*****************" << endl;
windowsObj.RemoveControl(&TextView);
CScrollBars* pScroll = new CScrollBars(&TextView);
windowsObj.AddControl(pScroll);
windowsObj.Draw();
cout << "*****************" << endl;
windowsObj.RemoveControl(pScroll);
CBorder* pBorder = new CBorder(&TextView);
windowsObj.AddControl(pBorder);
windowsObj.Draw();
system("pause");
return 0;
}
设计模式系列 https://blog.youkuaiyun.com/nie2314550441/article/details/105849726