Шаблон Singleton: использование версии Enum
Я не понимаю, как реализовать версию Enum
шаблона Singleton
. Ниже приведен пример реализации "традиционного" подхода с использованием шаблона Singleton. Я хотел бы изменить его, чтобы использовать версию Enum, но я не уверен, как это сделать.
public class WirelessSensorFactory implements ISensorFactory{
private static WirelessSensorFactory wirelessSensorFactory;
//Private Const
private WirelessSensorFactory(){
System.out.println("WIRELESS SENSOR FACTORY");
}
public static WirelessSensorFactory getWirelessFactory(){
if(wirelessSensorFactory==null){
wirelessSensorFactory= new WirelessSensorFactory();
}
return wirelessSensorFactory;
}
}
Ответы
Ответ 1
public enum WirelessSensorFactory {
INSTANCE;
// all the methods you want
}
Здесь ваш синглтон: перечисление только с одним экземпляром.
Обратите внимание, что этот синглтон является потокобезопасным, в то время как у вас нет: два потока могут входить в состояние гонки или проблему видимости, и оба создают свой собственный экземпляр вашего синглтона.
Ответ 2
Стандартная модель заключается в том, чтобы ваш enum реализовал интерфейс - таким образом вам не нужно раскрывать больше функций за кулисами, чем вам нужно.
// Define what the singleton must do.
public interface MySingleton {
public void doSomething();
}
private enum Singleton implements MySingleton {
/**
* The one and only instance of the singleton.
*
* By definition as an enum there MUST be only one of these and it is inherently thread-safe.
*/
INSTANCE {
@Override
public void doSomething() {
// What it does.
}
};
}
public static MySingleton getInstance() {
return Singleton.INSTANCE;
}
Ответ 3
Онлайн-ссылка главы "Эффективная Java" здесь.
public enum WirelessSensorFactory implements ISensorFactory { // change CLASS to ENUM here
INSTANCE; //declare INSTANCE of the Enum
//private static WirelessSensorFactory wirelessSensorFactory;
// Remove the private construct - it Enum,
// so you don't need to protect instantiations of the class
//private WirelessSensorFactory(){
// System.out.println("WIRELESS SENSOR FACTORY");
//}
// You don't need to check if instance is already created,
// because it Enum, hence you don't need the static var
//public WirelessSensorFactory getWirelessFactory(){
// if(wirelessSensorFactory==null){
// wirelessSensorFactory= new WirelessSensorFactory();
// }
// return wirelessSensorFactory;
//}
/*
* All other methods you need and
* implementation of all the Factory methods from your interface
*/
}
Применение:
WirelessSensorFactory.INSTANCE.<any public method>
Ответ 4
Здесь объясняется:
http://javarevisited.blogspot.sk/2012/07/why-enum-singleton-are-better-in-java.html
Таким образом, это можно сделать следующим образом:
public enum EasySingleton{
INSTANCE;
}
а также с использованием абстрактного шаблона проектирования factory:
public class Singleton{
//initailzed during class loading
private static final Singleton INSTANCE = new Singleton();
//to prevent creating another instance of Singleton
private Singleton(){}
public static Singleton getSingleton(){
return INSTANCE;
}
}
Ответ 5
Это намного проще, чем вся другая версия создания Singleton: -
public enum WirelessSensorFactory {
INSTANCE;
//private static WirelessSensorFactory wirelessSensorFactory;
//Private Const
//private WirelessSensorFactory(){
//System.out.println("WIRELESS SENSOR FACTORY");
// }
// public static WirelessSensorFactory getWirelessFactory(){
//if(wirelessSensorFactory==null){
// wirelessSensorFactory= new WirelessSensorFactory();
// }
// return wirelessSensorFactory;
// }
}
Ответ 6
Ниже приведен образец одного класса,
public class SingletonClass {
private static SingletonClass singletonInstance = null;
private SingletonClass() {
}
public static SingletonClass getSingletonInstance() {
if(singletonInstance == null) {
synchronized (SingletonClass.class) {
if(singletonInstance == null) {
singletonInstance = new SingletonClass();
}
}
}
return singletonInstance;
}
}
Этот фрагмент будет работать в многопоточной среде, так как он применяет блокировку для класса.