Effective Java Madde 4: Nesne Yaratılmasını İstemediğiniz Sınıfları Private Yapıcı Metot İle Güçlendirin

Bazen sadece statik metotları ve değişkenleri bir arada tutmak için bir sınıf yazmak isteyebilirsiniz. Bu tür sınıflar, bazı geliştiriciler tarafından nesne bazlı düşünmekten kaçınmak için suistimal edildiklerinden ötürü kötü bir üne kavuşmuşlardır. Buna rağmen, geçerli kullanım alanları bulunmaktadır. İlkel türler veya diziler üzerinde işlem yapan, birbiriyle alakalı metotları gruplamak için kullanılabilirler. java.lang.Math ve java.util.Arrays bu kullanıma örnek gösterilebilir. Bunun yanında java.util.Collections örneğinde olduğu gibi, belli bir arayüzü gerçekleştiren nesneler için tasarlanmış statik metotları – statik fabrika metotları da dahil (Madde 1) – bir arada tutmak için de kullanılabilirler. (Java 8 ile birlikte artık bu metotları arayüz içerisine de yazabilirsiniz, tabi arayüze erişiminiz varsa.) Son olarak, bu sınıflar final bir sınıf içerisindeki metotları gruplamak için de kullanılabilir, çünkü bunlar bir çocuk sınıfta tanımlanamaz.

Bu tarz yardımcı sınıflardan (utility class) nesne oluşturulması istenmez. Ancak herhangi bir yapıcı metot tanımlanmadığı zaman, Java derleyicisi otomatik olarak parametre almayan public bir varsayılan yapıcı metot (default constructor) tanımlayacaktır. Bir istemci açısından bu varsayılan yapıcı metodun, açıkça tanımlanmış diğer yapıcı metotlardan hiçbir farkı yoktur. Bu sebeple, birçok API içerisinde istemeden de olsa nesne yaratılabilen sınıflar bulunmaktadır.

Bunu engellemek için bir sınıfı abstract tanımlamak işe yaramaz. Bu sınıf katılılarak çocuk sınıftan bir nesne yaratılabilir. Dahası, kullanıcı bu sınıfın kalıtım amaçlı tasarlandığı yanılgısına kapılabilir. (Madde 19) Aslında bir sınıftan nesne yaratılmasını engellemek için çok basit bir yöntem vardır, private bir yapıcı metot tanımlamak. Biz açıkça bir yapıcı metot tanımladığımız zaman, derleyici varsayılan public yapıcı metodu tanımlamaz.

// Nesne yaratılamayan yardımcı sınıf
public class UtilityClass {
    // Varsayılan yapıcı metodu engelle
    private UtilityClass() {
        throw new AssertionError();
    }
    
    ...  // diğer kısımlar çıkartılmıştır
}

Tanımladığımız yapıcı metot private olduğu için sınıfın dışından görülebilmesi veya çalıştırılabilmesi mümkün değildir. Fırlatılan AssertionError ise yapıcı metodun sınıfın içerisinden yanlışlıkla çağırılması ihtimaline karşı önlem almak içindir. Böylece bu sınıftan asla bir nesne oluşturulamayacağını garanti etmiş oluruz.

Bir yan etki olarak, bu private yapıcı metot aynı zamanda sınıfın kalıtılmasını da engeller. Bütün yapıcı metotlar ilk önce kalıttıkları ata sınıfın (açıkça belirtilen bir kalıtım yoksa Object sınıfının) yapıcı metodunu çağırmak zorundadır, ata sınıftaki yapıcı metot açıkça tanımlanmış veya derleyici tarafından eklenen varsayılan yapıcı metot olabilir. Biz yukarıdaki yardımcı sınıfta hem varsayılan yapıcı metodun tanımlanmasını engellediğimiz için hem de kendi yapıcı metodumuzu private tanımladığımız için, bu sınıfı kalıtacak bir çocuk sınıfın çağırabileceği bir yapıcı metot bulunmamaktadır.

Share

Bir Cevap Yazın