What is the difference between Static class and Singleton instance?
– In c# a static class cannot implement an interface. When a single instance class needs to implement an interface for some business reason or IoC purposes, you can use the Singleton pattern without a static class.
– You can clone the object of Singleton but, you can not clone the static class object
– Singleton object stores in Heap but, static object stores in stack
– A singleton can be initialized lazily or asynchronously while a static class is generally initialized when it is first loaded
Static class和Singleton instance有什麼不同?
Singleton的意思就是程式中只能有一個實體。
- 在C#當中,static class無法實作interface。如果一個single instance class需要實做一個interface,或是需要控制反轉(IoC)的時候,你可以使用Singleton instance而不需要static class。
*控制反轉我覺得這篇文章(用超人的故事讲解 IoC(控制反转) 和 DI(依赖注入))講得蠻清楚的。
- 在Singleton instance中物件是可以被複製的,但是static class則不行。
- Singleton instance裡的物件是存在heap(堆積),而static class則是存在stack(堆疊)。
在Memory的管理中,物件內容會存放於Heap,而物件參考(指標)是存放於Stack。部分程式語言(像是比較早期的objective-C 或是C++)Heap是需要自己釋放記憶體空間的,而C#則是用了CLR來接管heap,加上GC原則上是不用自己去釋放,但是還是會有memory leak的可能,最明顯的例子就是office interop這種COM+ object,或是SharePoint的SPSite。(不知道SharePoint2016有沒有改善)
比方說我們可以從以下的code來看物件在heap中的生命週期:
Cat cat = new Cat(); Cat.Name = "Sumomo"; public void ChangeName(Cat c) { c.Name = "Sora"; }
在這邊ChangeName function傳入的變數c並不是Cat的值,而是point,所以當進入ChangeName的時候在heap中會有兩個point,都指向Cat。而修改值只是修改heap中的參考,當離開function之後就進入ChangeName function的物件就會被回收。
另外在C#當中Stack中存放參數(value),Heap存放物件(reference type)。比方說,int x = 42;這段語法會在stack中存放一個42的值。
如果我們再建立一個object指向x
object o = x;
這時候x轉換成o時是將x變數的值複製一份到o在Heap 裡的空間,這個作業稱為boxing。如果我們再把object o再轉一次放進另一個變數y
int y = (int)o;
這時就會再把o的值複製一份到stack中,這個動作稱之為unboxing
*String是例外,所有的string都是reference type。 - Singleton instance可以initialize lazily或是非同步執行,而static class則是會在第一次執行的時候被初始化。
Why singleton pattern is considered an Anti-pattern ?為什麼Singleton instance被認為是一種Anti-pattern?
– Singletons aren’t easy to handle with unit tests. You can’t control their instantiation and they may retain state across invocations.
– Memory allocated to an Singleton can’t be freed.
– In multithreaded environment, access to the singleton object may have to be guarded (e.g. via synchronization).
– Singletons promote tight coupling between classes, so it is hard to test
- Singleton instance不容易做unit test,因為你無法控制它的實作,又很容易殘留。
- 在 Singleton instance中allocate的記憶體無法被回收
- 在多執行緒的環境當中,如果用到Singleton物件可能會被鎖定,造成資源競爭。是可以加上同步的機制,但會造成效能低落。雖然可以透過Lazy Instantization,但這並不是thread-safe的寫法。
- Singleton instance會造成class之間的高度耦合,所以不容易測試。
結語
Singleton instance不是不能用,只是設計的時候要更小心,在對的地方使用。
1 則留言:
check this one...
http://net-informations.com/faq/default.htm
張貼留言