Ana içeriğe atla

Singleton Tasarım Deseni ve Java'da gerçekleştirimi

Singleton tasarım deseni, sınıftan örnek oluşturma ("instantiation") işlemini kısıtlayan, ve sınıftan çalıştırma süresince uygulama genelinde sadece bir örneğin oluşturulmasını sağlayan bir yöntemdir. Bir sınıfın uygulama çapında tek bir örneğinin çalışmasını istiyorsanız ve bu örneğin oluşturulmasını sınırlamak istiyorsanız bu tasarım desenini kullanmanız gerekir.

Bu tasarım deseni gerçekleştirilirken yapılması gereken, sınıfın herhangi bir örneği ("instance") yoksa bu örneği yaratmaktır. Bunu sağlayabilmek için bu yaratma işlemini kontrol altına almak gereklidir. Bu nedenle yapıcıların dışarıdan erişime kapatılması (Java'da private olarak tanımlama) ve yaratma işlemi için ayrı bir erişilebilir metotun tanımlanması gerekir. Bu tanımlanan metot içerisinde statik olarak saklanan örneğin daha önce yaratılıp yaratılmadığı kontrol edilerek, gerekiyorsa yaratılarak isteyen sınıf döndürülmesi gerekir.

Aşağıdaki resimde bir Singleton nesnesinin sınıf diagramı olarak gösterimini görebilirsiniz:

Genel Kullanım Alanları
  • Abstract Factory, Builder ve Prototype tasarım desenlerinin gerçekleştiriminde
  • Façade nesnelerinin gerçekleştiriminde, çünkü bu nesnelerin tek bir örneğinin olması gereklidir
  • Durum nesneleri genellikle Singleton'dır.
  • Global değişkenlerin yerine tercih edilir, çünkü;
    • Global isim uzayını gereksiz değişkenlerle kirletmezler
    • Tembel tahsis ("lazy allocation") ve ilklemeyi ("initialization") desteklerler, çoğu dilde global değişkenler her zaman kaynak tüketirler.
  • Singleton'lar sanal makinenin yaşam döngüsüne bağlı olarak farklı davranışlar sergilerler. Mesela bir yazılım geliştirme ortamında her çalıştırma için yeni bir sanal makine oluşturulduğu ve böylece her seferinde yeni bir singleton nesne oluşturulduğu halde, uygulama sunucusu içerisinde sanal makine sürekli çalışacağı için singleton nesnesi yaşamına devam eder.
Java Örnek Gerçekleştirimi

Klasik Çözüm:
public class TekBicim {
private final static TekBicim INSTANCE = new TekBicim();

public static TekBicim getInstance() {
return INSTANCE;
}

/**
* Asagida deniyoruz
*
* @param args
*/
public static void main(final String[] args) {
TekBicim.getInstance().yazdir();
TekBicim.getInstance().yazdir();
TekBicim.getInstance().yazdir();
TekBicim.getInstance().yazdir();
}

/*
* her taraftan erisilebilir (public) varsayilan yapicinin kullanilmamasi
* icin kendi ozel (private) yapicimizi yaziyoruz
*/
private TekBicim() {
System.out.println("ornek yaratildi");
}

public void yazdir() {
System.out.println("Yaziyorum");
}
}

Thread-safe çözüm:
/**
* Bu sinif Bill Pugh tarafindan onerilen ve is parcacigi guvenli (thread-safe)
* tembel yuklenebilen (lazy loading), talepte ilkleme tutucu (initialization on demand holder)
* olarak bilinen cozumdur
* @author emre
*
*/
public class TekBicim {
/**
* TekBicimTutucu TekBicim.getInstance() metodu ilk cagrildiginda veya
* TekBicimTutucu.INSTANCE ilk defa erisildiginde yukleniyor, daha once
* yuklenmiyor
*/
private static class TekBicimTutucu {
private final static TekBicim INSTANCE = new TekBicim();
}

public static TekBicim getInstance() {
return TekBicimTutucu.INSTANCE;
}

/**
* Asagida deniyoruz
*
* @param args
*/
public static void main(final String[] args) {
TekBicim.getInstance().yazdir();
TekBicim.getInstance().yazdir();
TekBicim.getInstance().yazdir();
TekBicim.getInstance().yazdir();
}

/*
* her taraftan erisilebilir (public) varsayilan yapicinin kullanilmamasi
* icin kendi ozel (private) yapicimizi yaziyoruz
*/
private TekBicim() {
System.out.println("ornek yaratildi");
}

public void yazdir() {
System.out.println("Yaziyorum");
}
}

Kaynak: http://en.wikipedia.org/wiki/Singleton_pattern
Bağlantılar:
Ekşisözlük Singleton
'Singleton' Tasarım Deseni
Singleton Tasarım Deseni

Yorumlar