资深工程师为何否定这种单例模式
生活随笔
收集整理的這篇文章主要介紹了
资深工程师为何否定这种单例模式
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
本人在?橫刀天笑 的一篇談論單例模式的文章http://www.cnblogs.com/yuyijq/archive/2007/10/07/915941.html
里面有兩種寫單例的例子.有一種方法得到資深工程師的否定.事實證明他的想法是錯誤的。
?
?? 第一種:
??? public?class?Singleton
?2{
?3????private?static?Singleton?_instance?=?null;
?4????private?static?readonly?object?lockHelper?=?new?object();
?5????private?Singleton()
?6????{
?7????}
?8????public?static?Singleton?CreateInstance()
?9????{
10????????//這樣lock以及lock塊內的代碼只會在第一次調用CreateInstance方法的時候執行,
11????????//第一次調用該方法后_instance就不再為null了,if塊內的代碼就無須執行了
12????????if(_instance?==?null)
13????????{
14????????????lock(lockHelper)
15????????????{
16????????????????if(_instance?==?null)
17????????????????????_instance?=?new?Singleton();
18????????????}
19????????}
20????????return?_instance;
21????}
22}
????? 這種方法也是大家公認的能夠在多線程下面正常工作的一種方法.
????? 原文中還提到了一種方法:
?2{
?3????//先實例化出一個實例再說
?4????private?static?Singleton?_instance?=?new?Singleton();
?5????????private?Singleton(){}
?6????public?static?Singleton?CreateInstance()
?7????{
?8????????return?_instance;
?9????}
10}
??? 博主說這兩種方法都可以,我自己也不太清楚它們之間的區別,但是本人記憶力好,記下了.
??? 一次在中軟面試中,有一個題讓你寫一個單例模式例子出來,我想都沒想就把上面第二種方法寫出來了,當然我忘了寫私有構造函數.這個也不影響思路.但是他們的技術人員說這不是單例模式,因為每次初始化類的時候就會new一次.
private static Singleton _instance = new Singleton();他可能是說這個.
?? 之后我親自測試了下博主說的第二種方法,說明是可行的,并非多線程.起碼單線程是可以的.
???
?? 我想他的意思應該是這樣的:
?? public?class?Singleton2
????{
????????//先實例化出一個實例再說
????????private?static?Singleton2?_instance?=?null?;
????????private?DateTime?_stime;
????????public?DateTime?sTime
????????{
????????????get?{?return?this._stime;?}
????????????set?{?this._stime?=?value;?}
????????}
????????private?Singleton2()
????????{
????????????this.sTime?=?DateTime.Now;
????????}
????????public?static?Singleton?CreateInstance()
????????{
????????????if?(_instance?==?null)
????????????{
????????????????return?new?Singleton2();
????????????}
????????????else
????????????{
????????????????return?_instance;
????????????
????????????}
????????????
????????}
????} ?????
???? 經過我的測試,第三種代碼是不正確的.
???? 我在MSDN上查了關于static的解釋:
???? static
??? 修飾符指明成員屬于類本身而不屬于類的實例。即使創建了類的多個實例,給定應用程序中只存在 static 成員的一個副本。您只能通過對類的引用(而不是對實例的引用)來訪問 static 成員。但是,在類成員聲明中,可以通過 this 對象來訪問 static 成員。
??? 類的成員可以使用 static 修飾符來標記。類、接口和接口的成員不能采用 static 修飾符。不能將 static 修飾符與任何繼承修飾符(abstract 和 final)或版本安全修飾符(hide 和 override)組合。
???? 這就說明了博主的說法是正確的,無論初始化多少次類,但是只會存在靜態成員的一個副本.
???? 據說那個面試官是特別資深的工程師,他應該也有他的理由說那不是單例,我想讓大家給說說第二種代碼是否是真正的單例模式.?
???? 謝謝大家對的幫助,今天回家看了下《HEAD FIRST 設計模式》在P181中明確的說明了上文中的第二種方法是可行的,也是真正的單例模式:
???? 原文是這樣的:
???? 2。使用“急切”創建實例,頁不用延遲實例化的做法
???? 如果應用程序總是創建并使用單件實例,或者在創建和運行時方面的負擔不太繁重,你可能想要急切(eagerly)創建此單件,如下所示:
???? 代碼和上文中第二種方法是一模一樣的。還特意對:private static Singleton _instance = new Singleton();這條語句進行說明:
???? 在靜態初始化器中創建單件,這段代碼保證了線程安全。
???? 本文中第一種創建單件的方法屬于延遲實例化的做法,只有當第一次調用的時候才會實例化類,沒有用到時則不進行任何實例化操作。所有說當類實例化不是特別復雜,對服務器開銷不大的時候這兩種方法在最終作用上和效果上是一樣的,沒有本質區別。所以最后本人認為我面試中的面試官的觀點是錯誤的。如果有理解錯誤的地方還望指點。
里面有兩種寫單例的例子.有一種方法得到資深工程師的否定.事實證明他的想法是錯誤的。
?
?? 第一種:
??? public?class?Singleton
?2{
?3????private?static?Singleton?_instance?=?null;
?4????private?static?readonly?object?lockHelper?=?new?object();
?5????private?Singleton()
?6????{
?7????}
?8????public?static?Singleton?CreateInstance()
?9????{
10????????//這樣lock以及lock塊內的代碼只會在第一次調用CreateInstance方法的時候執行,
11????????//第一次調用該方法后_instance就不再為null了,if塊內的代碼就無須執行了
12????????if(_instance?==?null)
13????????{
14????????????lock(lockHelper)
15????????????{
16????????????????if(_instance?==?null)
17????????????????????_instance?=?new?Singleton();
18????????????}
19????????}
20????????return?_instance;
21????}
22}
????? 這種方法也是大家公認的能夠在多線程下面正常工作的一種方法.
????? 原文中還提到了一種方法:
???? 實際上在很多地方我們可以采用另外一種初始化的方式,特別對于哪些實時系統或者哪些系統隨時都會用的類(比如系統配置類),我們用另外一種實現方法就不需要考慮線程安全的問題了,它們的線程安全由.net運行時為我們作保證。
?
?1public?class?Singleton
?2{
?3????//先實例化出一個實例再說
?4????private?static?Singleton?_instance?=?new?Singleton();
?5????????private?Singleton(){}
?6????public?static?Singleton?CreateInstance()
?7????{
?8????????return?_instance;
?9????}
10}
??? 博主說這兩種方法都可以,我自己也不太清楚它們之間的區別,但是本人記憶力好,記下了.
??? 一次在中軟面試中,有一個題讓你寫一個單例模式例子出來,我想都沒想就把上面第二種方法寫出來了,當然我忘了寫私有構造函數.這個也不影響思路.但是他們的技術人員說這不是單例模式,因為每次初始化類的時候就會new一次.
private static Singleton _instance = new Singleton();他可能是說這個.
?? 之后我親自測試了下博主說的第二種方法,說明是可行的,并非多線程.起碼單線程是可以的.
???
?? 我想他的意思應該是這樣的:
?? public?class?Singleton2
????{
????????//先實例化出一個實例再說
????????private?static?Singleton2?_instance?=?null?;
????????private?DateTime?_stime;
????????public?DateTime?sTime
????????{
????????????get?{?return?this._stime;?}
????????????set?{?this._stime?=?value;?}
????????}
????????private?Singleton2()
????????{
????????????this.sTime?=?DateTime.Now;
????????}
????????public?static?Singleton?CreateInstance()
????????{
????????????if?(_instance?==?null)
????????????{
????????????????return?new?Singleton2();
????????????}
????????????else
????????????{
????????????????return?_instance;
????????????
????????????}
????????????
????????}
????} ?????
???? 經過我的測試,第三種代碼是不正確的.
???? 我在MSDN上查了關于static的解釋:
???? static
??? 修飾符指明成員屬于類本身而不屬于類的實例。即使創建了類的多個實例,給定應用程序中只存在 static 成員的一個副本。您只能通過對類的引用(而不是對實例的引用)來訪問 static 成員。但是,在類成員聲明中,可以通過 this 對象來訪問 static 成員。
??? 類的成員可以使用 static 修飾符來標記。類、接口和接口的成員不能采用 static 修飾符。不能將 static 修飾符與任何繼承修飾符(abstract 和 final)或版本安全修飾符(hide 和 override)組合。
???? 這就說明了博主的說法是正確的,無論初始化多少次類,但是只會存在靜態成員的一個副本.
???? 據說那個面試官是特別資深的工程師,他應該也有他的理由說那不是單例,我想讓大家給說說第二種代碼是否是真正的單例模式.?
???? 謝謝大家對的幫助,今天回家看了下《HEAD FIRST 設計模式》在P181中明確的說明了上文中的第二種方法是可行的,也是真正的單例模式:
???? 原文是這樣的:
???? 2。使用“急切”創建實例,頁不用延遲實例化的做法
???? 如果應用程序總是創建并使用單件實例,或者在創建和運行時方面的負擔不太繁重,你可能想要急切(eagerly)創建此單件,如下所示:
???? 代碼和上文中第二種方法是一模一樣的。還特意對:private static Singleton _instance = new Singleton();這條語句進行說明:
???? 在靜態初始化器中創建單件,這段代碼保證了線程安全。
???? 本文中第一種創建單件的方法屬于延遲實例化的做法,只有當第一次調用的時候才會實例化類,沒有用到時則不進行任何實例化操作。所有說當類實例化不是特別復雜,對服務器開銷不大的時候這兩種方法在最終作用上和效果上是一樣的,沒有本質區別。所以最后本人認為我面試中的面試官的觀點是錯誤的。如果有理解錯誤的地方還望指點。
總結
以上是生活随笔為你收集整理的资深工程师为何否定这种单例模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 梦到小学同学是什么意思
- 下一篇: 谈CRM产品设计的指导思想