單例模式:保證一個(gè)類只有一個(gè)實(shí)例,并提供一個(gè)訪問它的全局訪問點(diǎn)。
單例模式幾乎是設(shè)計(jì)模式的最簡單形式了。這一模式的意圖是使得類的一個(gè)對(duì)象成為系統(tǒng)中的唯一實(shí)例。要實(shí)現(xiàn)這一點(diǎn),可以從客戶端對(duì)其進(jìn)行實(shí)例化開始。因此需要用一種只允許生成對(duì)象類的唯一實(shí)例的機(jī)制,“阻止”所有想要生成對(duì)象的訪問。我們可以用工廠方法來限制實(shí)例化過程。這個(gè)方法應(yīng)該是個(gè)靜態(tài)方法(類方法),因?yàn)樽岊惖膶?shí)例去生成另一個(gè)唯一實(shí)例毫無意義。下圖顯示了簡單單例模式的類結(jié)構(gòu)。

在以下情形,應(yīng)該考慮使用單例模式:
1)類只能有一個(gè)實(shí)例,而且必須從一個(gè)為人熟知的訪問點(diǎn)對(duì)其進(jìn)行訪問,比如工廠方法。
2)這個(gè)唯一的實(shí)例只能通過子類化進(jìn)行擴(kuò)展,而且擴(kuò)展的對(duì)象不會(huì)破壞客戶端代碼。
單例模式提供了一個(gè)為人熟知的訪問點(diǎn),供客戶類為共享資源生成唯一實(shí)例,井通過它對(duì)共享資源進(jìn)行訪問。雖然靜態(tài)的全局對(duì)象引用或類方法也可以提供全局訪問點(diǎn),但是全局對(duì)象無法防止類被實(shí)例化一次以上,而且類方法也缺少消除耦合的靈活性。
靜態(tài)全局變量保持著對(duì)類的實(shí)例的唯一引用,那些訪問這個(gè)全局變量的類或方法,實(shí)際上是在和使用這個(gè)變量的其他類或方法共享著同一份副本。這聽起來好像是我們在單例模式中想要的。如果在整個(gè)應(yīng)用程序中都只使用同一個(gè)全局變量,那么似曾萬事大吉,好做實(shí)際上井不需要單例模式。可是,要是團(tuán)隊(duì)中的某位老兄或者哪個(gè)顧問也定義了相同類型的靜態(tài)變量,都會(huì)怎么樣呢?那樣在同一個(gè)應(yīng)用程序中就會(huì)有兩個(gè)相同的全局對(duì)象類型——因此全局變量并不真正解決問題。
類方法提供了共享的服務(wù),不用創(chuàng)建其對(duì)象就可以訪問。資源的唯一實(shí)例可在類方法中維護(hù)。然而,如果類需要被子類化以提供更好的服務(wù),這一方式就不夠靈活。
單例類提供創(chuàng)建與訪問類的唯一對(duì)象的訪問點(diǎn),井保證它唯一、一致而且為人熟知。這一模式提供了靈活性,使其任何子類可以重載實(shí)例方法并且完全控制自身的對(duì)象創(chuàng)建,而不必修改客戶端的代碼。更好的是,父類中的實(shí)例實(shí)現(xiàn)可以處理動(dòng)態(tài)對(duì)象創(chuàng)建。類的實(shí)際類型可以在運(yùn)行時(shí)決定,以保證創(chuàng)建正確的對(duì)象。
單例模式有個(gè)變通版本,其中的一個(gè)工廠方法總是返回同一實(shí)例,但可以分配并初始化額外的實(shí)例。
單例的寫法常用的有兩種方式:
static SingleCase *manager = nil;
+ (SingleCase *)defaultManager {
if (!manager){
SingleCase = [[self alloc] init];
return manager;
}
}
+ (SingleCase *)sharedManager
{
static SingleCase *ManagerInstance = nil;
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
ManagerInstance = [[self alloc] init];
});
return ManagerInstance;
}
發(fā)表評(píng)論 取消回復(fù)