1.單件模式
1.1使用動機
必須保證一些特殊的類在系統(tǒng)中只有一個實例岭妖,以確保邏輯的正確性和效率函喉。比如數(shù)據(jù)層,網(wǎng)絡(luò)層锭汛。
繞過常規(guī)的構(gòu)造器笨奠,提供一種機制來保證一個類只有一個實例,以解決性能問題唤殴。(工廠模式繞過構(gòu)造器是要解決緊耦合的問題般婆。)
有必要只提供一個唯一的實例,不讓有“能生成多個實例”的機會朵逝。模式定義
保證一個類僅有一個實例蔚袍,并提供一個該實例的全局訪問點。--《設(shè)計模式》GoF結(jié)構(gòu)
單件模式
1.2要點總結(jié)
單件模式中的實例構(gòu)造器可以設(shè)置為protected以允許子類派生配名。
單件模式一般不要支持拷貝構(gòu)造函數(shù)和Clone接口啤咽,因為這有可能導(dǎo)致出現(xiàn)多個對象實例而有悖初衷
注意多線程環(huán)境下安全的單件模式,注意對雙檢查鎖的正確實現(xiàn)渠脉。
1.3 實現(xiàn)方法
class singleton
{
public:
~singleton()
{//析構(gòu)時使用
}
static singleton* getInstance()
{
if(_instance == NULL)
{
_instance = new singleton();
}
return _instance;
}
private:
static singleton *_instance;
private:
//最好將所有此類的實例化的進(jìn)口全部堵死
singleton()
{
}
singleton(const singleton&)
{
}
singleton& operator=(const singleton &)
{
}
};
singleton *singleton::_instance = NULL;
2.享元模式
2.1 定義
(英語:Flyweight Pattern)是一種軟件設(shè)計模式宇整。它使用共享物件,用來盡可能減少內(nèi)存使用量以及分享資訊給盡可能多的相似物件芋膘;它適合用于只是因重復(fù)而導(dǎo)致使用無法令人接受的大量內(nèi)存的大量物件鳞青。通常物件中的部分狀態(tài)是可以分享霸饲。常見做法是把它們放在外部數(shù)據(jù)結(jié)構(gòu),當(dāng)需要使用時再將它們傳遞給享元臂拓。
2.2 使用場景
如果一個應(yīng)用程序使用了大量的對象厚脉,而這些對象造成了很大的存儲開銷的時候就可以考慮是否可以使用享元模式。
例如,如果發(fā)現(xiàn)某個對象的生成了大量的實例埃儿,并且這些實例除了幾個參數(shù)外基本是相同的器仗,如果把那些共享參數(shù)移到類外面,在方法調(diào)用時將他們傳遞進(jìn)來童番,就可以通過共享大幅度單個實例的數(shù)目精钮。
2.3 實現(xiàn)
class FontFactory{
private:
map<string,Font* > fontPool;
public:
Font* GetFont(const string& key){
map<string,Font*>::iterator item=fontPool.find(key);
if(item!=footPool.end()){
return fontPool[key];
}
else{
Font* font = new Font(key);
fontPool[key]= font;
return font;
}
}
void clear(){
//...
}
};
3.狀態(tài)模式
3.1 定義
當(dāng)一個對象的內(nèi)在狀態(tài)改變時允許改變其行為,這個對象看起來像是改變了其類剃斧。
狀態(tài)模式主要解決的是當(dāng)控制一個對象狀態(tài)的條件表達(dá)式過于復(fù)雜時的情況轨香。把狀態(tài)的判斷邏輯轉(zhuǎn)移到表示不同狀態(tài)的一系列類中,可以把復(fù)雜的判斷邏輯簡化幼东。
3.2 適用 場景
1.一個對象的行為取決于它的狀態(tài)臂容,并且它必須在運行時刻根據(jù)狀態(tài)改變它的行為。
2.一個操作中含有龐大的多分支結(jié)構(gòu)根蟹,并且這些分支決定于對象的狀態(tài)脓杉。
3.3 實現(xiàn)
class NetworkState{
public:
NetworkState* pNext;
virtual void Operation1()=0;
virtual void Operation2()=0;
virtual void Operation3()=0;
virtual ~NetworkState(){}
};
class OpenState :public NetworkState{
static NetworkState* m_instance;
public:
static NetworkState* getInstance(){
if (m_instance == nullptr) {
m_instance = new OpenState();
}
return m_instance;
}
void Operation1(){
//**********
pNext = CloseState::getInstance();
}
void Operation2(){
//..........
pNext = ConnectState::getInstance();
}
void Operation3(){
//$$$$$$$$$$
pNext = OpenState::getInstance();
}
};
class CloseState:public NetworkState{ }
//...
class NetworkProcessor{
NetworkState* pState;
public:
NetworkProcessor(NetworkState* pState){
this->pState = pState;
}
void Operation1(){
//...
pState->Operation1();
pState = pState->pNext;
//...
}
void Operation2(){
//...
pState->Operation2();
pState = pState->pNext;
//...
}
void Operation3(){
//...
pState->Operation3();
pState = pState->pNext;
//...
}
};
4.組合模式
4.1 定義
將對象組合成樹形結(jié)構(gòu)以表示“部分整體”的層次結(jié)構(gòu)。組合模式使得用戶對單個對象和組合對象的使用具有一致性简逮。
4.2 適用場景
以下情況下適用Composite模式:
1.你想表示對象的部分-整體層次結(jié)構(gòu)
2.你希望用戶忽略組合對象與單個對象的不同球散,用戶將統(tǒng)一地使用組合結(jié)構(gòu)中的所有對象。
4.3 實現(xiàn)
#include <iostream>
#include <list>
#include <string>
#include <algorithm>
using namespace std;
class Component
{
public:
virtual void process() = 0;
virtual ~Component(){}
};
class Composite : public Component{
string name;
list<Component*> elements;
public:
Composite(const string & s) : name(s) {}
void add(Component* element) {
elements.push_back(element);
}
void remove(Component* element){
elements.remove(element);
}
void process(){
//1. process current node
//2. process leaf nodes
for (auto &e : elements)
e->process();
}
};
class Leaf : public Component{
string name;
public:
Leaf(string s) : name(s) {}
void process(){
//process current node
}
};
void Invoke(Component & c){
//...
c.process();
//...
}
int main()
{
Composite root("root");
Composite treeNode1("treeNode1");
Composite treeNode2("treeNode2");
Composite treeNode3("treeNode3");
Composite treeNode4("treeNode4");
Leaf leat1("left1");
Leaf leat2("left2");
root.add(&treeNode1);
treeNode1.add(&treeNode2);
treeNode2.add(&leaf1);
root.add(&treeNode3);
treeNode3.add(&treeNode4);
treeNode4.add(&leaf2);
process(root);
process(leaf2);
process(treeNode3);
}