結構型模式
簡介:通過組合類和對象獲得更大的結構
模式:
1. 適配器(ADAPTER)
簡介:將某個類的接口轉換成客戶端期望的另一個接口表示,目的是消除由於接口不匹配所造成
的類的兼容性問題
用途:
> 1.系統需要使用現有的類,而此類的接口不符合系統的需要
> 2.想要建立一個可以重複使用的類,用於與一些彼此之間沒有太大關聯的一些類,包括一
些可能在將來引進的類一起工作,這些源類不一定有一致的接口
> 3.通過接口轉換,將一個類插入另一個類系中
示例:
```
//使用複合,對象模式
class Deque //雙端隊列,被適配類
{
public:
void push_back(int x)
{
cout << "Deque push_back:" << x << endl;
}
void push_front(int x)
{
cout << "Deque push_front:" << x << endl;
}
void pop_back()
{
cout << "Deque pop_back" << endl;
}
void pop_front()
{
cout << "Deque pop_front" << endl;
}
};
class Sequence //順序類,目標類
{
public:
virtual void push(int x) = 0;
virtual void pop() = 0;
};
class Stack:public Sequence //棧, 適配類
{
public:
void push(int x)
{
m_deque.push_back(x);
}
void pop()
{
m_deque.pop_back();
}
private:
Deque m_deque;
};
class Queue:public Sequence //隊列,適配類
{
public:
void push(int x)
{
m_deque.push_back(x);
}
void pop()
{
m_deque.pop_front();
}
private:
Deque m_deque;
};
//END
```
2. 橋接(BRIDGE)
簡介:將抽象部分與實現部分分離,使它們都可以獨立變換
用途:
> 1.解決需求較多且易變的情況下,類爆炸的問題
示例:
```
//將各種App、各種手機全部獨立分開,使其自由組合橋接
class App
{
public:
virtual ~App(){ cout << "~App()" << endl; }
virtual void run() = 0;
};
class GameApp:public App
{
public:
void run()
{
cout << "GameApp Running" << endl;
}
};
class TranslateApp:public App
{
public:
void run()
{
cout << "TranslateApp Running" << endl;
}
};
class MobilePhone
{
public:
virtual ~MobilePhone(){ cout << "~MobilePhone()" << endl;}
virtual void appRun(App* app) = 0; //實現App與手機的橋接
};
class XiaoMi:public MobilePhone
{
public:
void appRun(App* app)
{
cout << "XiaoMi: ";
app->run();
}
};
class HuaWei:public MobilePhone
{
public:
void appRun(App* app)
{
cout << "HuaWei: ";
app->run();
}
};
int main()
{
App* gameApp = new GameApp;
App* translateApp = new TranslateApp;
MobilePhone* mi = new XiaoMi;
MobilePhone* hua = new HuaWei;
mi->appRun(gameApp);
mi->appRun(translateApp);
hua->appRun(gameApp);
hua->appRun(translateApp);
delete hua;
delete mi;
delete gameApp;
delete translateApp;
return 0;
}
```
3. 組合(COMPOSITE)
簡介:將對象組合成樹形結構以表示“部分-整體”的層次結構,組合模式使得用戶對單個對象和
組合對象的使用具有一致性
用途:
> 1.解耦
示例:
```
class Company
{
public:
Company(string name):m_name(name)
{}
virtual ~Company(){}
virtual void add(Company* company) = 0;
virtual void remove(string name) = 0;
virtual void display(int depth) = 0;
string getName()
{
return m_name;
}
protected:
string m_name;
};
//具體的公司
class ConcreteCompany:public Company //樹枝
{
public:
ConcreteCompany(string name):Company(name)
{}
~ConcreteCompany()
{
cout << "~ConcreteCompany()" << endl;
}
void add(Company* company) override;
void remove(string name) override;
void display(int depth) override;
private:
list<shared_ptr<Company>> m_listCompany;
};
void ConcreteCompany::add(Company* company)
{
shared_ptr<Company> temp(company);
m_listCompany.push_back(temp);
}
void ConcreteCompany::remove(string name)
{
list<shared_ptr<Company>>::iterator iter = m_listCompany.begin();
for(; iter != m_listCompany.end(); iter++)
{
shared_ptr<Company> temp(*iter);
string strName = temp.get()->getName();
if(name == strName)
{
m_listCompany.erase(iter);
}
}
}
void ConcreteCompany::display(int depth)
{
for(int i = 0; i < depth; i++)
{
cout << "-";
}
cout << m_name.data() << endl;
list<shared_ptr<Company>>::iterator iter = m_listCompany.begin();
for(; iter != m_listCompany.end(); iter++)
{
shared_ptr<Company> temp(*iter);
temp.get()->display(depth + 2);
}
}
//公司下的部門
class FinanceDept:public Company //樹葉
{
public:
FinanceDept(string name):Company(name)
{}
~FinanceDept()
{
cout << "~FinanceDept()" << endl;
}
void add(Company* company) override;
void remove(string name) override;
void display(int depth) override;
};
void FinanceDept::add(Company* company)
{
cout << "FinanceDept add failed" << endl;
}
void FinanceDept::remove(string name)
{
cout << "FinanceDept remove failed" << endl;
}
void FinanceDept::display(int depth)
{
for(int i = 0; i < depth; i++)
{
cout << "-";
}
cout << m_name.data() << endl;
}
//公司下的部門
class HRDept:public Company //樹葉
{
public:
HRDept(string name):Company(name)
{}
~HRDept()
{
cout << "~HRDept()" << endl;
}
void add(Company* company) override;
void remove(string name) override;
void display(int depth) override;
};
void HRDept::add(Company* company)
{
cout << "HRDept add failed" << endl;
}
void HRDept::remove(string name)
{
cout << "HRDept remove failed" << endl;
}
void HRDept::display(int depth)
{
for(int i = 0; i < depth; i++)
{
cout << "-";
}
cout << m_name.data() << endl;
}
int main(int argc, char *argv[])
{
Company* root = new ConcreteCompany("zong");
Company* f1 = new FinanceDept("F1");
Company* h1 = new HRDept("H1");
root->add(f1);
root->add(h1);
Company* c1 = new ConcreteCompany("fen1");
Company* f2 = new FinanceDept("F2");
Company* h2 = new HRDept("H2");
c1->add(f2);
c1->add(h2);
root->add(c1);
root->display(0);
delete root;
return 0;
}
```
4. 裝飾(DECORATOR)
簡介:動態地給一個**對象**而不是**整個類**添加一些額外的功能
用途:
> 1.避免類爆炸問題
示例:
```
class Dumplings //抽象類 餃子
{
public:
virtual ~Dumplings(){}
virtual void showDressing() = 0;
};
class MeatDumplings:public Dumplings //現實類 肉餡餃子
{
public:
~MeatDumplings(){ cout << "~MeatDumplings()" << endl; }
void showDressing()
{
cout << "Add Meat" << endl;
}
};
class DecoratorDumpling:public Dumplings //裝飾類
{
public:
DecoratorDumpling(Dumplings* d):m_dumpling(d){}
virtual ~DecoratorDumpling(){ cout << "~DecoratorDumpling()" << endl; }
void showDressing()
{
m_dumpling->showDressing();
}
private:
Dumplings* m_dumpling;
};
class SaltDecorator:public DecoratorDumpling // 裝飾類 加鹽
{
public:
SaltDecorator(Dumplings* d):DecoratorDumpling(d){}
~SaltDecorator(){ cout << "~SaltDecorator()" << endl; }
void showDressing()
{
DecoratorDumpling::showDressing(); //注意點
addDressing();
}
private:
void addDressing()
{
cout << "Add Salt" << endl;
}
};
class OilDecorator:public DecoratorDumpling //裝飾類 加油
{
public:
OilDecorator(Dumplings* d):DecoratorDumpling(d){}
~OilDecorator(){ cout << "~OilDecorator()" << endl; }
void showDressing()
{
DecoratorDumpling::showDressing(); //注意點
addDressing();
}
private:
void addDressing()
{
cout << "Add Oil" << endl;
}
};
class CabbageDecorator:public DecoratorDumpling //裝飾類 加蔬菜
{
public:
CabbageDecorator(Dumplings* d):DecoratorDumpling(d){}
~CabbageDecorator(){ cout << "~CabbageDecorator()" << endl; }
void showDressing()
{
DecoratorDumpling::showDressing(); //注意點
addDressing();
}
private:
void addDressing()
{
cout << "Add Cabbage" << endl;
}
};
int main()
{
Dumplings* d = new MeatDumplings; //原始的肉餃子
Dumplings* d1 = new SaltDecorator(d); //加鹽後的餃子
Dumplings* d2 = new OilDecorator(d1); //加油後的餃子
Dumplings* d3 = new CabbageDecorator(d2); //加蔬菜後的餃子
d3->showDressing();
delete d;
delete d1;
delete d2;
delete d3;
return 0;
}
```
5. 外觀(FACADE)
簡介:爲子系統中的一組接口定義一個一致的界面,外觀模式提供了一個高層接口,這個接口使
得這一子系統更加容易被使用;對於複雜的系統,系統爲客戶提供一個簡單的接口,把複雜的實現過程封裝起來,
客戶不需要了解系統內部的細節
用途:
> 1.客戶不需要了解系統內部複雜的細節,只需要一個接口;系統入口
示例:
```
class Cpu
{
public:
void productCpu()
{
cout << "Product Cpu" << endl;
}
};
class Ram
{
public:
void productRam()
{
cout << "Product Ram" << endl;
}
};
class Graphics
{
public:
void productGraphics()
{
cout << "Product Graphics" << endl;
}
};
class Computer
{
public:
void productComputer()
{
Cpu cpu;
cpu.productCpu();
Ram ram;
ram.productRam();
Graphics graphics;
graphics.productGraphics();
}
};
int main()
{
//客戶直接調用computer生產函數,無需關心具體部件的生產過程。也可直接單獨生產部件
Computer computer;
computer.productComputer();
Cpu cpu;
cpu.productCpu();
return 0;
}
```
6. 享元(FLYWEIGHT)
簡介:運用共享技術有效地支持大量細粒度的對象,也就是對象共享
用途:
> 1.有大量對象時,對於相同的部分,抽取出來作爲共享內存
示例:
```
//以Money的類別作爲內部標識,面值作爲外部狀態。
enum MoneyCategory //類別,內在標識,作爲標識碼
{
Coin,
bankNote
};
enum FaceValue //面值,外部標識,需要存儲的對象
{
ValueOne = 1,
ValueTwo
};
class Money //抽象父類
{
public:
Money(MoneyCategory cate):m_mCate(cate){}
virtual ~Money(){ cout << "~Money() " << endl; }
virtual void save() = 0;
private:
MoneyCategory m_mCate;
};
class MoneyCoin:public Money //具體子類1
{
public:
MoneyCoin(MoneyCategory cate):Money(cate){}
~MoneyCoin(){ cout << "~MoneyCoin()" << endl; }
void save()
{
cout << "Save Coin" << endl;
}
};
class MoneyNote:public Money //具體子類2
{
public:
MoneyNote(MoneyCategory cate):Money(cate){}
~MoneyNote(){ cout << "~MoneyNote()" << endl; }
void save()
{
cout << "Save BankNote" << endl;
}
};
class Bank
{
public:
Bank():m_coin(nullptr),m_note(nullptr),m_count(0){}
~Bank()
{
if(m_coin != nullptr)
{
delete m_coin;
m_coin = nullptr;
}
if(m_note != nullptr)
{
delete m_note;
m_note = nullptr;
}
}
void saveMoney(MoneyCategory cate, FaceValue value)
{
switch(cate) //以類別作爲標識碼
{
case Coin:
{
if(m_coin == nullptr) //內存中存在標識碼所標識的對象,則直接調用,不再創建
{
m_coin = new MoneyCoin(Coin);
}
m_coin->save();
m_vector.push_back(value);
break;
}
case bankNote:
{
if(m_note == nullptr)
{
m_note = new MoneyNote(bankNote);
}
m_note->save();
m_vector.push_back(value);
break;
}
default:
break;
}
}
int sumSave()
{
auto iter = m_vector.begin();
for(; iter != m_vector.end(); iter++)
{
m_count += *iter;
}
return m_count;
}
private:
vector<FaceValue> m_vector;
Money* m_coin;
Money* m_note;
int m_count;
};
int main()
{
Bank b1;
b1.saveMoney(Coin, ValueOne);
b1.saveMoney(Coin, ValueTwo);
b1.saveMoney(Coin, ValueTwo);
b1.saveMoney(bankNote, ValueOne);
b1.saveMoney(bankNote, ValueTwo);
cout << b1.sumSave() << endl;
return 0;
}
```
7. 代理(PROXY)
簡介:爲其它對象提供一種代理以控制對這個對象的訪問
用途:
> 1.防止用戶直接訪問對象
示例:
```
class Gril
{
public:
Gril(string name = "gril"):m_string(name){}
string getName()
{
return m_string;
}
private:
string m_string;
};
class Profession
{
public:
virtual ~Profession(){}
virtual void profess() = 0;
};
class YoungMan:public Profession
{
public:
YoungMan(Gril gril):m_gril(gril){}
void profess()
{
cout << "Young man love " << m_gril.getName().data() << endl;
}
private:
Gril m_gril;
};
class ManProxy:public Profession
{
public:
ManProxy(Gril gril):m_man(new YoungMan(gril)){}
void profess()
{
cout << "I am Proxy" << endl;
m_man->profess();
}
private:
YoungMan* m_man;
};
int main(int argc, char *argv[])
{
Gril gril("hei");
Profession* proxy = new ManProxy(gril);
proxy->profess();
delete proxy;
return 0;
}
```
# 行爲模式
## 1. 職責鏈(CHAN OF RESPONSIBILITY)
## 2. 命令(COMMAND)
## 3. 解釋器(INTERPRETER)
## 4. 迭代器(ITERATOR)
## 5. 中介者(MEDIATOR)
## 6. 備忘錄(MEMENTO)
## 7. 觀察者(OBSERVER)
## 8. 狀態(STATE)
## 9. 策略(STRATEGY)
## 10. 模板方法(TEMPLATE METHOD)
## 11. 訪問者(VISITOR)