Enum singleton ile ilgili bazı sorunlar:
Bir uygulama stratejisi taahhüdü
Tipik olarak, "singleton" bir API spesifikasyonu değil, bir uygulama stratejisini belirtir. Foo1.getInstance()
Her zaman aynı örneği döndüreceğini açıkça bildirmek çok nadirdir . Gerekirse, Foo1.getInstance()
örneğin iş parçacığı başına bir örnek döndürmek için evrimi gelişebilir.
İle Foo2.INSTANCE
biz bunu genel olarak örnek olduğunu beyan örneği ve bunu değiştirmek için hiçbir şansı yoktur. Tek bir örneğe sahip olma uygulama stratejisi açık ve taahhüt edilmiştir.
Bu sorun sakat değil. Örneğin, etkili bir iş parçacığı örneği için sahip bir Foo2.INSTANCE.doo()
iş parçacığı yerel yardımcı nesnesine güvenebilirsiniz .
Enum sınıfını genişletme
Foo2
bir süper sınıfı genişletir Enum<Foo2>
. Genellikle süper sınıflardan kaçınmak isteriz; özellikle bu durumda, zorlanan süper sınıfın Foo2
olması gerekenle hiçbir ilgisi yoktur Foo2
. Bu, uygulamamızın tür hiyerarşisine bir kirlilik. Gerçekten bir süper sınıf istiyorsak, genellikle bir uygulama sınıfıdır, ancak yapamayız, Foo2
'süper sınıfı sabittir.
Foo2
kullanıcılarına name(), cardinal(), compareTo(Foo2)
kafa karıştırıcı olan bazı komik örnek yöntemlerini devralır Foo2
. bu yöntem arayüzünde istense bile Foo2
kendi name()
yöntemine sahip olamaz Foo2
.
Foo2
ayrıca bazı komik statik yöntemler içerir
public static Foo2[] values() { ... }
public static Foo2 valueOf(String name) { ... }
public static <T extends Enum<T>> T valueOf(Class<T> enumType, String name)
kullanıcılara saçma geliyor. Bir tekil genellikle zaten pulbic statik yöntemlerini olmamalıdır (dışındaki getInstance()
)
serilerştirilebirlik
Singletonların durum bilgisi olması çok yaygındır. Bu singletons genellikle gerektiğini değil seri hale edilebilir. Durumsal bir singletonu bir VM'den başka bir VM'ye taşımanın mantıklı olduğu gerçekçi bir örnek düşünemiyorum; singleton, "evrende benzersiz" değil, "sanal makine içinde benzersiz" anlamına gelir.
Serileştirme durumsal bir singleton için gerçekten anlamlıysa, singleton, aynı türden bir singletonun zaten mevcut olabileceği başka bir VM'de bir singletonun serileştirilmesinin ne anlama geldiğini açıkça ve kesin olarak belirtmelidir.
Foo2
otomatik olarak basit bir serileştirme / serileştirme stratejisi uygular. Bu sadece gerçekleşmeyi bekleyen bir kazadır. Kavramsal Foo2
olarak t1'de VM1'de bir durum değişkenine başvuran bir veri ağacımız varsa , serileştirme / serileştirme yoluyla değer farklı bir değer olur - Foo2
t2'deki VM2'de aynı değişkenin değeri, algılanması zor bir hata oluşturur. Bu hata, serileştirilemez olana Foo1
sessizce gerçekleşmeyecek.
Kodlama kısıtlamaları
Normal sınıflarda yapılabilecek, ancak enum
sınıflarda yasak olan şeyler vardır . Örneğin, yapıcıdaki statik bir alana erişim. Özel bir sınıfta çalıştığı için programcı daha dikkatli olmalıdır.
Sonuç
Numaralandırmada piggybacking yaparak 2 satır kod kaydediyoruz; ama fiyat çok yüksek, biz tüm bavullar ve numaralandırma kısıtlamaları taşımak zorunda, biz yanlışlıkla sonuçların enum "özellikleri" miras. İddia edilen tek avantaj - otomatik serileştirilebilirlik - bir dezavantaj olduğu ortaya çıkıyor.