裝飾模式: 動態的給一個對象添加額外的職責,就增加功能來說,裝飾模式比生成子類更加靈活。
特點:
1. 裝飾對象包含一個真實對象的引用,Decorator有一個Component的引用或者指針
2. 裝飾對象和真實對象擁有相同的接口,這樣客戶端對象就可以和真實對象一樣和裝飾對象交互
使用場景:
需要動態的給一個類添加功能,這些功能還可以撤銷
增加一些由基本功能的排列組合組成的大量的功能,繼承關係不那麼現實了,設計師可以創造出不同行爲的組合
結構圖:
component:定義一個對象接口,可以給這些對象動態添加職責
ConcreteComponent:具體的對象,也可以給這個對象添加職責
Decorator:核心類,裝飾抽象類,繼承了Component,對於Component來說無需知道Decorator的存在
ConcreteDecorator:具體的裝飾對象,對Component添加職責的功能
好處:
有效的把類的核心職責和裝飾功能區分開了,而且還可以去除相關類中重複的裝飾邏輯。
裝飾對象的實現就和如何使用這個對象分離開了,每個裝飾對象只關心自己的功能,不需要關心如何添加到對象鏈中。
具體應用實例:Avatar系統,一種在網絡遊戲或者論壇上中應用很廣泛的紙娃娃系統
一個例子:穿衣服打扮自己
#include<iostream>
#include<string>
#include<cstdlib>
using namespace std;
/*
服飾搭配問題
*/
/*component class*/
class person
{
private:
string name;
public:
person()
{ }
person(string name)
{
this->name = name;
}
virtual void show()
{
cout <<"name is "<<name<< endl;
}
};
/*decorator class*/
class clothes: public person
{
protected:
person *man;
public:
void decorate(person *man)
{
this->man = man;
}
void show() //override
{
if(man != NULL)
{
man->show();
}
}
};
/*concrete decorate class */
class T_shirt: public clothes
{
public:
void show()
{
man->show();
add_behavior();
}
void add_behavior()
{
cout <<" T-shirt "<< endl;
}
};
class Big_trouser: public clothes
{
public:
void show()
{
man->show();
add_behavior();
}
void add_behavior()
{
cout <<" Big-trouser "<< endl;
}
};
class Big_shoe: public clothes
{
public:
void show()
{
man->show();
add_behavior();
}
void add_behavior()
{
cout <<" Big-shoe "<< endl;
}
};
class red_cat: public clothes
{
public:
void show() //core part
{
man->show();
add_behavior();
}
void add_behavior()
{
cout <<" red-cat "<< endl;
}
};
class glovers: public clothes
{
public:
void show()
{
man->show();
add_behavior();
}
void add_behavior()
{
cout <<" glovers "<< endl;
}
};
class black_bag: public clothes
{
public:
void show()
{
man->show();
add_behavior();
}
void add_behavior()
{
cout <<" black-bag "<< endl;
}
};
int main()
{ string name("xiaoming");
person *xp = new person(name);
T_shirt *Ts = new T_shirt();
black_bag *bb = new black_bag();
glovers *gl = new glovers();
red_cat *rc = new red_cat();
Ts->decorate(xp);
bb->decorate(Ts);
gl->decorate(bb);
rc->decorate(gl);
rc->show();
system("pause");
return 0;
}
/*
name is xiaoming
T-shirt
black-bag
glovers
red-cat
*/