Tasarım Kalıpları: Singleton (Tek Nesne) – IV – Değerlendirme
Şu ana kadar Singleton tasarım kalıbının mekanizmaları üzerinde durduk. Bu yazıda Singleton kalıbının kullanımları üzerine bir değerlendirme yapalım.
Singletonı bir kalıp yerine ters-kalıp (anti-pattern) görme eğilimi vardır. Bunun en temel sebebi ise tek olan nesnenin, erişim kolaylığından dolayı global bir değişkene dönüşebilmesidir.
Global değişkenler, görünürlük alanları açısından (scope) herhangi bir kısıtlamaya sahip olmayan, dolayısıyla yazılımın her yerinden erişen değişkenlerdir. Bu yüzden global değişkenler, yazılımın farklı soyutlamaları arasındaki ortak olarak kullanılırlar. Bu durum ise yazılımın farklı parçalarının birbirlerine daha bağımlı olmasına sebep olur. Öte yandan ortak yapılar, yazılımdaki soyutlamaların odaklanmasını da engelleyici mahiyettedir. Bu yüzden örneğin ben, özellikle C gibi global değişkenlere izin veren dillerin kültüründen gelen kişilerin bulunduğu eğitim ortamlarında sıklıkla “Java’da global değişken yoktur!” diye vurgularım.
Nesne-merkezli yapıların, prosedürel yapılara en temel üstünlüğü, soyutlama mekanizması olarak fonksiyon yerine nesneyi koymuş olması ve bu sayede daha yetkin yerel bir ifade yapısı elde etmiş olmasıdır. Hem ifade gücü hem de değişim yönetimi açısından nesnelerin fonksiyonlara göre çok daha yetenekli olması, fonksiyonların sağlayamadığı yerelliği, nesnelerin sağlamasından kaynaklanmaktadır. (Bu konuyu burada ve burada ele almıştık.) Bu yaklaşımda bahsettiğimiz yerellik ve globallik, sorumluluklar açısından anlamlı kavramlardır. Bu açıdan bakıldığında, nesne-merkezli programlama bir yerelleştirme, çapı küçültme, yani modülerleştirme dolayısıyla da globallikten uzaklaşma felsefesi barındırmasına rağmen, Singleton kalıbıyla bunun tam tersi yönde bir mekanizma sağlaması çelişkili bir durum olarak görülebilir.
Bu noktada Kent Beck ve Ward Cunningham’ın şu sözlerine kulak vermekte fayda vardır:
“The most difficult problem in teaching object-oriented programming is getting the learner to give up the global knowledge of control that is possible with procedural programs, and rely on the local knowledge of objects to accomplish their tasks. Novice designs are littered with regressions to global thinking: gratuitous global variables, unnecessary pointers, and inappropriate reliance on the implementation of other objects.
Because learning about objects requires such a shift in overall approach, teaching objects reduces to teaching the design of objects. We focus on design whether we are teaching basic concepts to novices or the subtleties of a complicated design to experienced object programmers.”
Singleton kalıbıyla hem durumu (state) hem de davranışı (behavior) global yapma imkanımız var. Bu ise Singleton üzerinde ciddi bir bağımlılık (coupling) oluşturmaktadır. Yani Singleton olan nesne, hem uygulamanın her tarafından erişilebilir hem de muhtemelen uygulama boyunca bellekte kalmaya devam eder. Bu durum ise, aksi halde aralarında hiç bir bağımlılık olmayacak uygulama parçalarının singleton ile ciddi bir bağımlılığa sahip olmalarına sebep olur. Dolayısıyla singleton kullanımının bizi nesne-merkezli programlamadan prosedürel programlama götürdüğü, bu yüzden ters-kalıp olduğu iddia edilmektedir.
Singleton hakkında bir başka nokta ise hakikatten Singleton nesneye ihtiyacın olup olmadığı durumdur. Yani projenizde bir noktada işin kolayına kaçarak bir nesneyi singleton yaparsanız, ileride o nesnenin Singleton olmasından kaynaklanan sıkıntılar yaşayabilirsiniz. Örneğin, performans ve ölçeklenirlik gerekliliklerinden dolayı birden fazla JVM i grup (clustered) olarak kullanmak istediğinizde ya da sisteminizde faklı sınıf yükleyiciler (class loaders) olduğunda, Singleton nesnelerinin artık gerçekten Singleton olmadığını görebilirsiniz. Ben, Singleton’un çok çekici tabiatından dolayı, pek çok şeyin çözümüymüş gibi, olur-olmadık yerlerde kullanıldığına şahit oldum. Singleton’un tasarım kalıplarını yeni öğrenmeye başlayan programcının zihnindeki durumu, “Elinde çekiç olan kişi her şeyi çivi olarak görür” atasözünü hatırlatır 🙂
Singleton2un bu kullanımlarından dolayı ters-kalıp (anti-pattern) haline gelmiş olduğunu, bizzat GoF da buradaki “Design Patterns 15 Years Later” başlıklı görüşmede ifade ederler.
Böyle bir durumun statik değişkenler ve metotlar yoluyla da oluşturulduğu iddia edilebilir. Statik özelliklerin global yapılar oluşturduğu bir gerçektir fakat statik özellikleri, hakikatten global olmasında fayda olan, hatta global olarak kullanımı, tersi düşünülemeyecek kadar tabi ve gerekli olduğu durumlarda kullandığımız için bu durum singletonlar kadar büyük bir problem görülmez. (Bu konuyu burada ve burada daha detaylı olarak ele almıştık.)
Singleton eleştirileriyle ilgili şu sayfaları paylaşabilirim:
- Dangers of singleton design pattern
- Singleton considerations
- Singleton considered stupid
- Global state and Singletons
- Singletons are Pathological Liars
- Singleton is an anti-pattern
- Why singletons are evil
- What is so bad about singletons?
- Singleton Design Pattern – An introspection and best practices
- c2.com singleton linkleri
- Use singletons wisely
- Do I really need a singleton?
- Flaw: Brittle Global State & Singletons
- When is a singleton not a singleton?
Ben şöyle düşünüyorum: Singleton, evet bir tasarım kalıbıdır ama hem gerekliliği hem de teknik kısıtları ya da muhtemel sıkıntıları üzerine ciddi kafa yormadan, işin kolayına kaçarak sıklıkla olur-olmadık yerde kullanılması bence bir istismardır. Singleton güzel ve şıktır ama gelişi güzel ve alışkanlıkla kullanılmayacak kadar da tehlikeli bir çözümdür.
Toplam görüntülenme sayısı: 1321