在物件導向中,乙個類可以建立無數個物件,但有時候需要對類新增一種限制,即:這個類只能建立乙個物件。這初次聽起來感覺有點奇怪,但是仔細一想,還是有很多場景需要滿足這樣的需求的。如日誌類、狀態機類、引數配置類等等。如日誌類,它只可以建立乙個物件,每次使用時,就直接呼叫這個物件,將所有資訊均輸出到同乙個日誌中,而不是使用時,建立若干個日誌物件,將相關的資訊輸出到不同的日誌中。
乙個類只能建立乙個物件,這種模式就叫做單例模式。其定義是:」確保乙個類只有乙個例項,並提供乙個全域性訪問點「。其類圖如下所示,其建構函式變成了私有,也就意味著,不能通過建構函式來直接構造這個類的例項。而類中定義了乙個static函式getinstance()函式,這個函式的作用有:
如果第一次呼叫該函式,則該函式會呼叫類的建構函式來建立乙個類例項並將其賦值給靜態移動變數m_instance中;
如果不是第一次呼叫該函式,則該函式會將m_instance作為返回值返回給呼叫者,一旦呼叫者。
上述兩個作用保證了singleton類只能有乙個類例項,且通過靜態函式getinstance()可以令其他呼叫者方便地呼叫這個例項。
下述講述的是head first書中的巧克力鍋爐的例子,只是我用c++將其實現,並新增了執行緒安全的功能。其類圖如下所示:
此處我對書中的設計進行了更改,類中createinstance()方法類似於singleton中的getinstance(),只是前者僅僅是建立例項但不返回例項,如果想對該例項進行操作,可以直接通過類中對應的靜態函式來進行操作,而不是像書中那樣,直接獲取類例項並進行操作。
具體**如下:
chocolateboiler.h
chocolateboiler.cpp#if !defined(ea_00ca3d58_e76a_4557_8d52_adc3ecd1bbdc__included_)
#define ea_00ca3d58_e76a_4557_8d52_adc3ecd1bbdc__included_
#include
#include
#include
class
chocolateboiler
;#endif
// !defined(ea_00ca3d58_e76a_4557_8d52_adc3ecd1bbdc__included_)
main.cpp#include
"chocolateboiler.h"
std::unique_ptr chocolateboiler::m_chocolateboilerptr;
std::mutex chocolateboiler::m_mutexcreate;
chocolateboiler::
~chocolateboiler()
chocolateboiler::
chocolateboiler()
void chocolateboiler::
createinstance()
}}void chocolateboiler::
boil()
}void chocolateboiler::
drain()
}void chocolateboiler::
fill()
}bool chocolateboiler::
isboiled()
bool chocolateboiler::
isempty()
#include
#include
#include
"chocolateboiler.h"
intmain
(int argc,
char
const
*ar**)
);// boil the boiler in thread 2.
std::thread thread2([
]())
; thread1.
join()
; thread2.
join()
;// print the state of chocolate boiler.
std::cout <<
"chocolate boiler is "
<<
(chocolateboiler::
isempty()
?"empty."
:"not empty."
)<< std::endl;
std::cout <<
"chocolate boiler is "
<<
(chocolateboiler::
isboiled()
?"boiled."
:"not boiled."
)<< std::endl;
return0;
}
Head First設計模式之工廠模式
定義了乙個建立物件的介面,但由子類決定要例項化的類是哪乙個.工廠方法讓類把例項化推遲到子類 1 抽象工廠角色 這是工廠方法模式的核心,它與應用程式無關。是具體工廠角色必須實現的介面或者必須繼承的父類。2 具體工廠角色 它含有和具體業務邏輯有關的 由應用程式呼叫以建立對應的具體產品的物件。3 抽象產品...
《Head First設計模式》之命令模式
命令模式就是將方法呼叫 method invocation 封裝起來。通過封裝方法呼叫,我們可以把運算塊包裝成形,所以呼叫此運算的物件不需要關心事情是如何進行的,只要知道如何使用包裝成形的方法來完成它就可以了。通過封裝方法呼叫,可以用在以下場景 記錄日誌或者重複使用這些封裝來實現撤銷 undo 我對...
Head First設計模式之組合模式
將物件組合成樹形結構來表現 整體 部分 層次結構。組合能讓客戶以一致的方法處理個別物件以及組合物件。主要部分可以被一致對待問題.組合模式主要包含三個角色 2.composite 容器構件 容器節點包含子節點,其子節點可以是葉子節點,也可以是容器節點,它提供乙個集合用於儲存子節點,實現了在抽象構件中定...