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:
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!