設計模式通常被認為是更高階的主題,因此對於ios或os x開發的新手來說,它們會被忽略或忽視。 但是,從一開始,每個有抱負的ios或os x開發人員都會面臨許多設計模式。 單例模式就是這樣一種模式。
在開始研究在swift和objective-c中實現單例模式的技術之前,我想花一點時間來理解單例模式,包括其優缺點。
單例模式與物件導向的程式設計密不可分。 單例模式的定義很簡單,只能建立乙個單例類例項,或者在任何時候都可以執行。
但是, 布倫特·西蒙斯 ( brent simmons)通過區分真實單身人士和功能性單身人士來細化此定義。 brent將真正的單例定義為始終返回自身相同例項的類。 不能建立乙個以上的類例項。 功能單例僅建立一次,並在多個地方使用。
我確定許多開發人員不會將功能單例歸類為單例,但是我喜歡布倫特所做的區分。 功能性單例通常沒有真正的單例所具有的缺點。 我們將在本文後面部分討論這些缺點。
輔助功能
#import @inte***ce viewcontroller : uiviewcontroller
@end
#import "viewcontroller.h"
@implementation viewcontroller
#pragma mark -
#pragma mark view life cycle
- (void)viewdidload
@end
控制與行為
就是說,重要的是要理解單身人士是實現控制和行為的一種手段。 防禦性編碼技術可以為您帶來相同的結果,而不會造成單例模式的精神負擔。
全球狀態
通過建立單例,您實際上是在建立全域性狀態。 知道這一點很重要。 幾年前,miškohevery寫了一篇有關單例模式的出色文章 ,其中他解釋了為什麼應避免使用該模式。 miško強調,單身人士有害的主要原因是全域性狀態。
雖然有例外。 例如,不可變的單例幾乎沒有害處。 您仍在建立全域性狀態,但是該狀態是不可變的。 miško還提到記錄器是單例模式的某種可接受的應用程式,因為狀態是從應用程式進入記錄器的乙個方向。
緊耦合大多數物件導向的程式語言都認為模組緊密耦合是一種不好的做法。 換句話說,建議盡可能將模組解耦。 這使單例模式處於不利位置,因此,許多受尊敬的程式設計師都認為單例是不好的做法。 一些開發人員甚至認為它是應該避免的反模式 。
可重用性
緊密耦合通常與可重用性緊密相關。 緊密耦合的物件圖通常很難在不重構的情況下重用。 可重用性有時是不可避免的,但是在開發軟體時,一定要牢記這一點。
在objective-c中建立單例非常容易。 在以下**片段中,我們建立並實現了乙個日誌記錄類logger
。 我們通過sharedlogger
類方法訪問單例物件。
#import @inte***ce logger : nsobject
#pragma mark -
#pragma mark class methods
+ (logger *)sharedlogger;
@end
實現很簡單。 我們宣告乙個靜態變數_sharedinstance
,它將儲存對單例物件的引用。 我們呼叫grand central dispatch函式dispatch_once
,並傳入乙個用於初始化logger
類例項的塊。 我們將對例項的引用儲存在_sharedinstance
。
#import "logger.h"
@implementation logger
#pragma mark -
#pragma mark class methods
+ (logger *)sharedlogger );
return _sharedinstance;
}@end
dispatch_once
函式可確保我們通過的塊在應用程式的生命週期內執行一次。 這非常重要,因為我們只想初始化logger
類的乙個例項。
dispatch_once
函式使用作為dispatch_once
函式的第乙個引數傳遞的oncepredicate
變數,以確保該塊僅執行一次。
sharedlogger
類方法通過返回儲存在_sharedinstance
的引用來返回logger
例項。sharedlogger
,sharedlogger
的實現可能會讓人望而生畏,但是我相信您同意這個想法非常簡單。
為了在swift中實現單例模式,我們使用了swift 1.2中引入的類常量。 如果您在以下**段中遇到問題,請確保您使用的是xcode 6.3+。
class logger
讓我logger
介紹一下logger
類的簡短實現。 我們首先宣告乙個名為logger
的類。 為了實現單例模式,我們宣告了logger
型別的型別屬性sharedinstance
。
通過使用static
關鍵字,將sharedinstance
常量繫結到logger
類而不是該類的例項。 由於sharedinstance
常量與型別(即logger
類)相關聯,因此將其稱為型別屬性 。 我們通過logger
類訪問單例物件。
logger.sharedinstance
實現單例模式的另一種常見方法是利用巢狀型別。 在下面的示例中,我們宣告乙個logger
型別的計算型別屬性sharedinstance
。 在計算型別屬性的關閉中,我們宣告乙個名為singleton
的結構。 該結構定義了型別為logger
的常量型別屬性(instance
。
class logger
return singleton.instance
}}
兩種策略訪問單例物件都是相同的。 如果您使用的是swift 1.2,則我建議使用第一種方法以使其簡潔明瞭。
如果您僅有的工具是錘子,我想把所有東西都當作釘子來對待是很誘人的。當我第一次聽說單例模式時,我為它在下乙個專案中的實用**到興奮。 使用似乎可以解決許多問題的工具非常誘人。 乍一看,單例模式可能看起來像銀子彈或金錘 ,但這並不是單例模式。— 亞伯拉罕·馬斯洛
單例可能非常有用,但是許多經驗豐富的程式設計師都將它們視為反模式。 他們中的大多數人對得出這一結論的模式都缺乏經驗。 從他們的錯誤中學習並謹慎使用它們。
我不認為單例模式是反模式,但應謹慎使用該模式。 如果您很想將物件變成單例,請問自己乙個問題,是否還有其他方法可以解決問題。 在大多數情況下,單例模式不是唯一可用的解決方案。 替代解決方案可能需要更多的工作或一些開銷,但從長遠來看可能會更好。
布倫特·西蒙斯 ( brent simmons)所指的功能單例通常是真正單例的完美有效替代方案。 建立乙個類的例項並將其傳遞給需要它的物件沒有錯。 下次您要建立另乙個單例時,請考慮使用此方法。
單例模式既簡單又強大,但應謹慎使用。 您的一些同事可能會建議您不要這樣做,但是我認為重要的是要考慮使用它並自己判斷是否認為它對您的工具箱有用。
翻譯自:
單例設計模式(餓漢單例設計模式 懶漢單例設計模式)
1.什麼是單例 單例的意思是乙個類永遠只存在乙個物件,不能建立多個物件。2.為什麼要用單例 開發中有很多的物件我們只需要乙個,例如虛擬機器物件,任務管理器物件 物件越多越佔記憶體,有時候只需要乙個物件就可以實現業務,單例可以節省記憶體空間。3.如何實現單例 單例的實現方式有 餓漢單例設計模式 通過類...
設計模式 單例設計模式
歷史 最早是建築學領域的模式,然後gof四人由其引申到編碼方面,總結了23種設計模式 設計模式 解決某一類事情最行之有效的方法 2.1 體現 餓漢式,保證物件的唯一性 class singleton 私有化建構函式禁止該類建立物件 private static singleton st new si...
設計模式 單例設計模式
單例模式,是一種常用的軟體設計模式。在它的核心結構中只包含乙個被稱為單例的特殊類。通過單例模式可以保證系統中乙個類只有乙個例項。即乙個類只有乙個物件例項 單例模式的要點有三個 一是某個類只能有乙個例項 二是它必須自行建立這個例項 三是它必須自行向整個系統提供這個例項。單例設計模式 解決的問題 可以保...