Создание перечисления с одним экземпляром
enum Singleton {
INSTANCE;
private Field field = VALUE;
public Value method(Arg arg) { /* some code */ }
}
// You can use
Value v = Singleton.INSTANCE.method(arg);
РЕДАКТИРОВАТЬ: Учебник по перечислению Java показывает, как добавить поля и методы в перечисление.
Кстати: часто, когда вы можете использовать Singleton, он вам на самом деле не нужен, поскольку служебный класс будет делать то же самое.Еще более короткая версия - просто
enum Utility {;
private static Field field = VALUE;
public static Value method(Arg arg) { /* some code */ }
}
// You can use
Value v = Utility.method(arg);
. Где Singletons полезны, когда они реализуют интерфейс.Это особенно полезно для тестирования при использовании инъекции зависимости.(Один из недостатков использования замещения Singleton или служебного класса в модульных тестах)
например
interface TimeService {
public long currentTimeMS();
}
// used when running the program in production.
enum VanillaTimeService implements TimeService {
INSTANCE;
public long currentTimeMS() { return System.currentTimeMS(); }
}
// used in testing.
class FixedTimeService implements TimeService {
private long currentTimeMS = 0;
public void currentTimeMS(long currentTimeMS) { this.currentTimeMS = currentTimeMS; }
public long currentTimeMS() { return currentTimeMS; }
}
Как вы можете видеть, если ваш код везде использует TimeService, вы можете внедрить либоVanillaTimeService.INSTANCE
или new FixedTimeService()
, где вы можете контролировать время извне, т. Е. Ваши отметки времени будут одинаковыми при каждом запуске теста.
Короче говоря, если вам не нужен синглтон для реализацииинтерфейс, все, что вам может понадобиться, это служебный класс.