Dyskusja:Kody źródłowe/Singleton (wzorzec projektowy)
Java
edytujRozwiązanie 2 - nie thread safe. Skoro nie jest thread safe to po co ta synchronizacja? Double check nie ma sensu. Jeśli godzimy się na brak wielowątkowości to nie prościej napisać
public final class Singleton {
private static volatile Singleton instance = null;
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
private Singleton() {
}
}
Kod Singletona w Pythonie
edytujTaka dość ważna uwaga: zaprezentowany sposób prowadzi do wycieku pamięci w momencie, gdy niszczymy (jawnie) stworzone obiekty. Spójrzmy na efekty działania programu:
class Singleton(object):
def __new__(type):
if not '_instancja' in type.__dict__:
type._instancja = object.__new__(type)
return type._instancja
a = Singleton()
a.toto = 1234
b = Singleton()
print b.toto
b.toto = 4321
print a.toto
print id(a), id(b)
del a, b
print Singleton._instancja
Po wykonaniu ostatniej linii kodu okazuje się, że klasa Singleton nadal przechowuje referencję na obiekt przez co nie zostaje on zwolniony. Proponuję poprawną wersję:
class Singleton(object):
import weakref
_instance = weakref.WeakValueDictionary()
def __new__(cls):
obj = cls._instance.get(cls)
if not obj:
obj = super(Singleton, cls).__new__(cls)
cls._instance[cls] = obj
return obj
Ten kod korzysta z WeakValueDictionary, co powoduje, że w momencie zniknięcia ostatniego "silnego" odwołania do instancji naszego Singletona Singleton._instance automatycznie się opróżni.