Yakın zamanda singleton tasarım modelini , bunun Java'da nasıl uygulanacağını ve ne işe yaradığını araştırdınız . Peki ya size Java'nın kendi singleton'uyla kutudan çıktığını söylersem? İlginizi mi çekti? O zaman dalalım.

Muhtemelen Enum sınıfını zaten biliyorsunuzdur . Bilmeniz gereken özel bir özelliği vardır. Enum , özellikle tekil tasarım modelini uygular. Bu seçenek, genel bir alanı içeren tekil yaklaşımla hemen hemen aynıdır .

Enum olarak Singleton:


public enum Device {   
    PRINTER	
} 
    

Genel değişken olarak Singleton:


public class Printer {   
    public static final Printer PRINTER = new Printer();   
    private Printer() {
    }
//…
}
    

Enum yaklaşımı, kendi uygulamamızı yazmamız gerekmediğinden, genel alan yaklaşımından daha derli topludur . En önemlisi, numaralandırmaların serileştirme ile ilgili sorunları yoktur.

Numaralandırmaların serileştirilmesi, sıradan nesneler için olduğundan farklı çalışır: yalnızca numaralandırma adının değeri serileştirilir. Seri durumdan çıkarma sırasında yöntem, bir örnek almak için seri durumundan çıkarılan adla birlikte kullanılır. Ek olarak, enum sizi yansıma saldırılarına karşı koruyabilir .

Yansıma API'sini keşfedeceğimiz ikinci modüldeki derslerde yansıtma hakkında daha fazla bilgi edineceksiniz .

Java, örnek numaralandırmaları yasaklar; bu, Constructor sınıfının newInstance yönteminin uygulanmasında kullanılan ve genellikle yansıma yoluyla nesneler oluşturulurken çağrılan bir sınırlamadır.

Constructor.newInstance'tan kod alıntısı . Bir enum oluşturmak için kullanılır :


if ((clazz.getModifiers() & Modifier.ENUM) != 0)
    throw new IllegalArgumentException("Cannot reflectively create enum objects");
    

Bir singleton oluşturmak için bir enum kullanmanın dezavantajları şunları içerir:

  • Nesne hemen oluşturulduğundan ve başlatma geciktirilemeyeceğinden, tembel başlatma eksikliği.

  • Diğer sınıflar genişletilemez. Yani, başka bir sınıfı miras almanız gereken durumlarda, bir numaralandırmayı tekil olarak kullanmak işe yaramaz . Bu gibi durumlarda, zaten aşina olduğumuz diğer uygulama seçeneklerine başvurmamız gerekir: statik bir yöntem veya genel bir değişken.

  • Numaralandırmayı tekil olarak kullanırken, yalnızca bir numaralandırma alanı kullanabilirsiniz .


public enum Device extends Electricity { 
    PRINTER 
}
    

Bu kod bize bir derleme hatası verecektir:

Enum için hiçbir extension yan tümcesine izin verilmez

Ancak, bir arabirim uygulamamız gerekirse, enum arabirimleri uygulayabileceğinden sorun yoktur :


public enum Device implements Electricity { 
    PRINTER 
}
    

Kalıtım kullanmanız gerekmiyorsa, enum yoluyla tekil kalıbı uygulamak en iyisidir . Bunu tavsiye eden yalnız biz değiliz - Joshua Bloch'un kendisi de öyle .

Bu uygulama yaklaşımı size kolaylık, kompaktlık, kullanıma hazır serileştirme, yansıma saldırılarına karşı koruma ve benzersizlik - iyi bir singleton'ın ihtiyaç duyduğu her şeyi sağlar!