日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

【设计模式】五、单例模式(独一无二的对象)

發布時間:2023/12/9 asp.net 54 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【设计模式】五、单例模式(独一无二的对象) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、概述:

有一些對象我們只需要一個,比方說:線程池(threadpool)、緩存(cache)、對話框、處理偏好設置和注冊表對象、日志對象、充當打印機、顯卡等設備的驅動程序的對象。事實上這些對象只需要一個實例,如果制造出多個實例就會導致很多問題發生。(利用靜態類變量、靜態方法和適當的訪問修飾符的確也可以做到只存在一個實例。)

蘇格拉底誘導式回答:(參考《Head First 設計模式》)

如何創建一個對象?new MyObject()
萬一另外一個對象想創Myobject會怎樣?可以再次new MyObject嗎?是的,當然可以。
所以一旦有一個類,我們是否都能多次的實例化它?如果是公開的類 就可以
如果不是的話,會怎樣?

如果不是公開的類,只有同一個包內的類可以實例化它,但是仍可以實例化它很多次

可以這么做嗎?

public Myclass {private Myclass(){} }

?

?我沒想過,但是這是合法的定義,有一定的道理。
?怎么說呢??我認為含有私有的構造器類不能唄實例化。
?又可以使用私有的構造器對象嗎??恩,我想Myclass內的代碼是唯一能調用此構造器的代碼,但是這又不太合乎常理。
?WHY??因為只有Myclass的實例才能調用Myclass的構造器,但是因為沒有其他類能夠實例化Myclass,所以我們得不到這樣的實例。

?嘿,我有個想法。

你認為如何?

public Myclass {public static MyClass getInstance(){} }

MyClass有一個靜態方法,我們可以這樣調用這個方法:

MyClas.getInstance();

?
?為何調用的時候用MyCLass類名,而不是對象名。?因為getInstance是類方法,是一個靜態方法,你需要使用類名。

?有意思,假如把這些合在一起“是否”就可以初始化一個MyClass?

public MyClass {private MyClass(){}public static Myclass getInstance(){return new MyClass();} }

?

當然可以?
?好了,你能想出第二種實例化對象的方式嗎??MyClass.getInstance();
?你能夠完成代碼是MyClass只有一個實例被產生嗎??恩,大概可以吧。。。。

?

單例模式優點

  • 正如前面說的,單例模式在內存中只有一個實例,減少了內存開支。特別是一個對象需要頻繁的創建、銷毀時,而創建與銷毀的性能有無法優化,單例模式的優勢就非常明顯。
  • 單例模式只生成一個實例,減少了系統性能開銷,當一個對象的產生需要比較多的資源時,如讀取配置、產生其他依賴對象時,則可以通過在應用啟動時直接產生一個單例對象,然后永久駐留內存的方式來解決。
  • 單例模式可以避免對資源的多重占用。
  • 單例模式可以在系統設置全局的訪問點,優化和共享資源訪問。
  • 單例模式缺點

  • 單例模式一般沒有接口,擴展很困難,除了修改代碼基本上沒有第二種途徑實現。
  • 單例模式對測試是不利的。在并行開發環境中,如果單例模式沒有完成,是不能進行測試的。
  • 單例模式與單一職責原則有沖突。
  • 二、在IOS中的應用

    單例模式在iOS開發中的使用還是蠻多的,許多Foundation、Cocoa和UIKit中的類都實現了單例模式,比如應用程序本身UIApplication、文件操作類NSFileManager、消息中心NSNotificitonCenter等系統都已經給我們實現單例,我們只需要使用就好了。在iOS中使用單例模式要使用類方法,通過類方法返回該類的唯一對象。

    在ios中的應用主要有以下三種方式

    1、

    static Singleton *instance = nil;+ (Singleton *)sharedInstance {if (instance == nil) {instance = [[super allocWithZone:NULL] init];}return instance; }+ (id)allocWithZone:(NSZone *)zone {return [[self sharedInstance] retain]; }- (id)copyWithZone:(NSZone *)zone {return self; }- (id)retain {return self; }- (NSUInteger)retainCount {return NSUIntegerMax; //denotes an object that cannot be released }- (void)release {//do nothing }- (id)autorelease {return self; }

    可以看到這種方式,使用靜態成員維持了一個永久存在的對象,而且覆蓋了alloc方法(alloc方法會調用allocWithZone:方法),并且也覆蓋了所有與引用技術有關的方法,這都使這個對象不會被銷毀。這樣看上去基本實現了我們需要的,但是寫起來麻煩不說,還有很大的一個問題,那就是多線程問題,如果是在多線程中那么該種方法就不能保證只產生一個對象了。所以這種方式只是介紹一下,并不推薦使用。

    2、引入頭文件

    程序員都是偷懶的,現在流行使用一個宏定義來搞定這許多的事,而且考慮的更加周全。

    單例包含以下接口?

    + (MyClass*) sharedInstance;?
    + (void) purgeSharedInstance;

    調用sharedInstance會創建并返回單例

    調用purgeSharedInstance會銷毀單例

    手動調用alloc也可以保證是單例,你可以這樣調用

    [[MyClass alloc] initWithParam:firstParam secondParam:secondParam];

    只是要保證在sharedInstance之前調用,因為只有一次創建機會。

    下面是使用宏的寫法“?

    MyClass.h: ======================================== #import "SynthesizeSingleton.h" @interface MyClass: SomeSuperclass { ... } SYNTHESIZE_SINGLETON_FOR_CLASS_HEADER(MyClass); @end ======================================== MyClass.m: ======================================== #import "MyClass.h" @implementation MyClass SYNTHESIZE_SINGLETON_FOR_CLASS(MyClass); ... @end ========================================

    開源庫下載地址

    3、

    iOS在4.0以后推出了block和GCD,這兩個特性給iOS開發帶來的很大的便利,也使開發變得更加趣味話。那么如何通過GCD+block來實現單例模式呢,這主要歸功于dispatch_once(dispatch_once_t *predicate, ^(void)block)這個GCD的函數,他有兩個參數第一參數是一個指向dispatch_once_t類型結構體的指針,用來測試block是否執行完成,該指針所指向的結構體必須是全局的或者靜態的,第二個參數是一個返回值與參數均為空的block,在block體中進行對象的初始化即可。dispatch_once在程序的生命周期中保證只會被調用一次,所以在多線程中也不會有問題。 該種方法使用方法:

    ?

    + (Singleton *)sharedInstance {static Singleton *instance = nil;static dispatch_once_t onceToken;dispatch_once(&onceToken, ^{instance = [[Singleton alloc]init];});return instance; }

    dispatch_once的作用就是執行且在整個程序的聲明周期中,僅執行一次某一個block對象。簡直就是為單例而生的嘛。而且,有些我們需要在程序開頭初始化的動作,如果為了保證其,僅執行一次,也可以放到這個dispatch_once來執行。

    然后我們看到它需要一個斷言來確定這個代碼塊是否執行,這個斷言的指針要保存起來,相對于第一種方法而言,還需要多保存一個指針。

    ?

    方法簡介中就說的很清楚了:對于在應用中創建一個初始化一個全局的數據對象(單例模式),這個函數很有用。

    如果同時在多線程中調用它,這個函數將等待同步等待,直至該block調用結束。

    這個斷言的指針必須要全局化的保存,或者放在靜態區內。使用存放在自動分配區域或者動態區域的斷言,dispatch_once執行的結果是不可預知的。

    ?

    總結:1.這個方法可以在創建單例或者某些初始化動作時使用,以保證其唯一性。2.該方法是線程安全的,所以請放心大膽的在子線程中使用。(前提是你的dispatch_once_t?onceToken

    對象必須是全局或者靜態對象。這一點很重要,如果不能保證這一點,也就不能保證該方法只會被執行一次。)

    ?


    參考博客:

    水滴石穿 Keeping faith.??????--- wtlucky's Blog

    ?

    轉載于:https://www.cnblogs.com/ymonke/p/3513668.html

    總結

    以上是生活随笔為你收集整理的【设计模式】五、单例模式(独一无二的对象)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。