
Java'da bir singleton nedir?
Singleton, sınıf düzeyindeki en basit tasarım modellerinden biridir. Bazen insanlar "bu sınıf tekildir" der, bu da sınıfın tekil tasarım modelini uyguladığı anlamına gelir. Bazen örneklemeyi tek bir nesneyle sınırladığımız bir sınıf yazmak gerekir. Singleton tasarım deseni, bunu nasıl başarabileceğimizi açıklar. Singleton, iki şey yapan bir tasarım desenidir:-
Sınıfın yalnızca bir örneğinin olacağını garanti eder.
-
Bu örneğe tek bir küresel erişim noktası sağlar.
-
Özel bir inşaatçı. Bu, sınıfın nesnelerini sınıfın dışında yaratma yeteneğini sınırlar.
-
Sınıfın örneğini döndüren genel bir statik yöntem. Bu yönteme getInstance denir . Bu, sınıf örneğine küresel erişim noktasıdır.
Uygulama seçenekleri
Singleton tasarım deseni çeşitli şekillerde uygulanır. Her seçenek kendi yolunda iyi ve kötüdür. Her zaman olduğu gibi, burada mükemmel bir seçenek yok ama bir tane için çabalamalıyız. Her şeyden önce, iyi ve kötüyü neyin oluşturduğuna ve tasarım modelinin çeşitli uygulamalarını nasıl değerlendirdiğimizi hangi ölçütlerin etkilediğine karar verelim. İyi ile başlayalım. Bir uygulamayı daha sulu ve çekici kılan faktörler şunlardır:-
Tembel başlatma: ihtiyaç duyulana kadar örnek oluşturulmaz.
-
Basit ve şeffaf kod: Bu ölçüm elbette özneldir, ancak önemlidir.
-
İş parçacığı güvenliği: çok iş parçacıklı bir ortamda doğru çalışma.
-
Çok iş parçacıklı bir ortamda yüksek performans: bir kaynağı paylaşırken çok az iş parçacığı engelleme veya hiç engelleme yok.
-
Tembel başlatma yok: sınıf yüklendiğinde, gerekip gerekmediğine bakılmaksızın uygulama başladığında (paradoksal olarak, BT dünyasında tembel olmak daha iyidir)
-
Karmaşık ve okunması zor kod. Bu ölçüm aynı zamanda sübjektiftir. Gözleriniz kanamaya başlarsa, uygulamanın en iyi olmadığını varsayarız.
-
İplik güvenliği eksikliği. Başka bir deyişle, "iplik tehlikesi". Çok iş parçacıklı bir ortamda yanlış işlem.
-
Çok iş parçacıklı bir ortamda düşük performans: iş parçacıkları, bir kaynağı paylaşırken her zaman veya sıklıkla birbirini engeller.
kod
Artık çeşitli uygulama seçeneklerini değerlendirmeye ve artıları ve eksileri belirtmeye hazırız:Basit
public class Singleton {
private static final Singleton INSTANCE = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return INSTANCE;
}
}
En basit uygulama. Artıları:
-
Basit ve şeffaf kod
-
İplik güvenliği
-
Çok iş parçacıklı bir ortamda yüksek performans
- Tembel başlatma yok.
Tembel başlatma
public class Singleton {
private static final Singleton INSTANCE;
private Singleton() {}
public static Singleton getInstance() {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
return INSTANCE;
}
}
Artıları:
-
Tembel başlatma.
-
İş parçacığı güvenli değil
senkronize erişim
public class Singleton {
private static final Singleton INSTANCE;
private Singleton() {
}
public static synchronized Singleton getInstance() {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
return INSTANCE;
}
}
Artıları:
-
Tembel başlatma.
-
İplik güvenliği
-
Kötü çok iş parçacıklı performans
İki kez kontrol edilen kilitleme
public class Singleton {
private static final Singleton INSTANCE;
private Singleton() {
}
public static Singleton getInstance() {
if (INSTANCE == null) {
synchronized (Singleton.class) {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
}
}
return INSTANCE;
}
}
Artıları:
-
Tembel başlatma.
-
İplik güvenliği
-
Çok iş parçacıklı bir ortamda yüksek performans
-
1.5'in altındaki önceki Java sürümlerinde desteklenmez (volatile anahtar sözcüğünün kullanımı 1.5 sürümünden beri sabittir)
sınıf sahibi
public class Singleton {
private Singleton() {
}
private static class SingletonHolder {
public static final Singleton HOLDER_INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.HOLDER_INSTANCE;
}
}
Artıları:
-
Tembel başlatma.
-
İplik güvenliği.
-
Çok iş parçacıklı bir ortamda yüksek performans.
-
Doğru işlem, tekil nesnenin hatasız olarak başlatıldığının garantisini gerektirir . Aksi takdirde, getInstance yöntemine yapılan ilk çağrı bir ExceptionInInitializerError ile sonuçlanacak ve sonraki tüm çağrılar bir NoClassDefFoundError üretecektir .
uygulama | Tembel başlatma | İplik güvenliği | Çok iş parçacıklı performans | Ne zaman kullanılır? |
---|---|---|---|---|
Basit | - | + | Hızlı | Asla. Veya muhtemelen tembel başlatma önemli olmadığında. Ama asla daha iyi olmaz. |
Tembel başlatma | + | - | Uygulanamaz | Her zaman çoklu iş parçacığı gerekmediğinde |
senkronize erişim | + | + | Yavaş | Asla. Veya muhtemelen çok iş parçacıklı performans önemli olmadığında. Ama asla daha iyi olmaz. |
İki kez kontrol edilen kilitleme | + | + | Hızlı | Singleton oluştururken istisnaları işlemeniz gereken nadir durumlarda (sınıf sahibi singleton geçerli olmadığında) |
sınıf sahibi | + | + | Hızlı | Çoklu iş parçacığı gerektiğinde ve tekil nesnenin sorunsuz bir şekilde oluşturulacağının garantisi vardır. |
Singleton modelinin artıları ve eksileri
Genel olarak, bir singleton tam olarak kendisinden bekleneni yapar:-
Sınıfın yalnızca bir örneğinin olacağını garanti eder.
-
Bu örneğe tek bir küresel erişim noktası sağlar.
-
Bir singleton, tek sorumluluk ilkesini ihlal eder: doğrudan görevlerine ek olarak, singleton sınıfı ayrıca örnek sayısını da kontrol eder.
-
Sıradan bir sınıfın bir singleton'a bağımlılığı, sınıfın kamu sözleşmesinde görünmez.
-
Küresel değişkenler kötü. Nihayetinde, bir singleton, ağır bir küresel değişkene dönüşür.
-
Bir singleton'ın varlığı, uygulamanın bir bütün olarak ve özellikle singleton kullanan sınıfların test edilebilirliğini azaltır.
GO TO FULL VERSION