Statik Metotlu Sınıf mı Yoksa Singleton mı? – I
Nesne-merkezli dillerde çok tartışılan konulardan birisi de hiç nesne oluşturmaya gerek bırakmadan kod yazmamızı sağlayan statik özellikler ve metotlar mı yoksa sadece bir tane nesne oluştuğundan emin olup, bu tek nesne üzerinde çağıracağımız nesne özellikleri ve metotları mı? Bu probleme kısaca statik-singleton (static vs. singleton) de denir çünkü tasarım kalıplarında, bir sınıftan sadece bir nesne oluşturmaya “singleton” yani “tekil” denir.
Bence statik kullanımı, tabi özellikle statik metot kullanımı, nesne-merkezli dillerin, yanlış kullanıma en fazla konu olanı ya da bir başka deyişle suistimale uğrayan alanı. Malum, loglama vb. utility metotlarını, üzerinde bulunduğu sınıfın nesnesini oluşturmadan hızlıca kullanmak isteriz. Örneğin aşağıda üzerindeki metotları statik olarak tanımlanmış ve bu yüzden de bu metotları kullanmak için nesnesine ihtiyaç duymayacağımız bir Log sınıfı vardır:
public class Log{ public static void logInfo(String infoString){...} public static void logError(String errorString){...} ... }
Bu sınıfın kullanım örneği de şöyle olabilir:
public class Client{ public void doThis(){ ... ... if(...) Log.logInfo("..."); else Log.logError("..."); } }
Statik metotlara sahip böyle bir sınıfı kullanmanın kolaylığı çok açıktır: Sınıfın kendisini nesne gibi kullanmak. Dahası o tek nesneyi herhangi bir yere geçmenize bile gerek yok, doğrudan sınıfın üzerinden statik alanlara ve metotlara ulaşabilirsiniz.
Eğer yukarıdaki Log sınıfının metotlarını statik yapmak istemezsek ve bu sınıfın sadece bir tane nesnesinin olacağını planlıyorsak bu durumda Log sınıfını singleton olarak şöyle kodlardık:
public class LogSingleton{ private static LogSingleton logger = new LogSingleton(); private LogSingleton(){...} public static LogSingleton getInstance(){ return logger; } public void logInfo(String infoString){...} public void logError(String errorString){...} }
Bu durumda da yukarıdaki Client sınıfı şu şekilde değişirdi:
public class Client{ private LogSingleton logger; public Client(){ logger = LogSingleton.getInstance(); } public void doThis(){ ... ... if(...) logger.logInfo("..."); else logger.logError("..."); } }
Şimdi soru şu: Hangi yöntemi kullanmalıyız?
Bazı diller bu ikilemi baştan çözmüşler ve yapılarına statik özellikler almamışlar. Örneğin Scala’da statik metotlu sınıf tanımlamanız mümkün değil, bunun yerine “object” anahtar kelimesiyle nesne tanımlıyorsunuz. Olan biten şey, Scala size doğrudan bir nesnesi olan sınıf tanımlamanızı sağlıyor. Güzel bir çözüm. Java, C#, C++ gibi dillerde ise statik kullanımı söz konusu olduğundan bu tartışma da geçerlidir. Bu durumda sizce hangi kullanımı tercih etmeliyiz ya da siz hangisini tercih ediyorsunuz? Statik metotlar mı yoksa singleton nesne mi?
Toplam görüntülenme sayısı: 3345
Selman
26 Aralık 2014 @ 17:07
Singleton bir sınıfı bir başka sınıftan türebiliriz , ayrıca singleton nesne bir arayüzü de gerçekleyebilir. Bunlar nesne yönelimli programlama açısından önemli kavramlar. He bir de tabi unutmadan Singleton nesne “lazy load” ile yapılandırılabilir. Bu da bir avantar. Static metotlardan oluşan sınıfları sadece hakikaten fayda/utility özellikli durumlar için kullanmak gerek. Diye düşünüyorum
Akin
26 Aralık 2014 @ 23:40
Doğru Selman beyciğim, aradaki farklar dedikleriniz. Ikınci yazıda yazacagım ayrıntılı. Tesekkur ederim.
Yasin
01 Ocak 2015 @ 19:03
Multithreading ya da concurrent uygulamaların çok ciddi bir şekilde patlama yaptığını gördüğüm şu dönemde static metodların bizim uygulamalarımızda ciddi anlamda sorun çıkardığını görüyorum. Aynı anda birden fazla metoddan bu static metod çağrılıyor ve sonuçta işler karışıyor. Bunun için (işler karışmasın diye) synchronized keyword’ünü kullanıyoruz ama bu kez de concurrency’nin faydasını göremiyoruz çünkü synchronized çalışan static bir metod var elimizde ve aynı anda birden fazla iş yapmıyor. Bu durumun sıkıntısını çözmek adına birkaç ay önce bir yere kadar yaptığım araştırmanın sonucunda static ve singleton nesne kullanımlarının gerçekten gerekli olup olmadığı konusunun tartışıldığını gördüm. Bence Singleton ya da static kullanımı gerçekten gerektiğini düşündüğünüz anlarda mantıklı olabiliyor. Diğer yandan çoğu kez “hızlı kod geliştirme” adına uygulanan bu yöntem performans anlamında uygulamanıza bir yavaşlık meydana gelmesine sebep oluyor diye düşünüyorum. O yüzden utility, log vs bile olsa mümkün olduğunca bu tip yönelimlerden uzak durmak gerektiği kanısına vardım. Bilmiyorum belki yanlış düşünüyorumdur. Siz bu konuda ne düşünüyorsunuz Akın hocam? Static/singleton hiç kullanmasak ne olur, ne kaybederiz yani?… 🙂
Akin
01 Ocak 2015 @ 23:36
Satitic metotlar için soyeldiginiz thread safety olmama problemi singletonun metotları için de geçerli. D
Tayfun Yaşar
02 Ocak 2015 @ 10:31
Madem ortada bir soru var, cevapsız bırakmak olmaz. Biz nesne olarak kullanıyoruz.
public static final Logger logger = LoggerFactory.getLogger(Util.readPropertyValueByKey(“LOGGER_NAME”));
..
logger.error(“getFilterForTransferListJS method”, t);
Akin
02 Ocak 2015 @ 13:33
Evet siz Logger’ı static metotlar yerine nesne olarak kullanıyorsunuz ama bu nesnenin singleton olup olmadıgını bilmiyoruz. Kullanma şeklnizden aslıdna singleton olmadığı daha akla yakın.
Teşekkür ederim cevabınız ve katkınız için 🙂
Tolga
05 Ocak 2015 @ 15:30
Static metotlarda ki bir diger problem de unit test yazarken mock objelerde ortaya cikiyor.
Bu yüzden bende static metotlarin ufak utility class larinda yazilmasindan yanayim.
Akin
05 Ocak 2015 @ 18:17
Haklısınız. Bu durum singleton kullanmanın lehine arguman oalrak kullanılır.
Tesekkür ederim.