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!