Наскоро се задълбочихте в шаблона за проектиране на singleton , How да го внедрите в Java и за Howво служи. Но Howво ще стане, ако ви кажа, че Java идва със собствен сингълтон веднага след като е готов? Заинтригуван? Тогава нека се потопим.
Вероятно вече знаете за класа Enum . Има специална функция, която трябва да знаете. По-конкретно, Enum имплементира модела на единичния дизайн. Тази опция е почти същата като единичния подход, включващ публично поле.
Singleton като enum:
public enum Device {
PRINTER
}
Singleton като публична променлива:
public class Printer {
public static final Printer PRINTER = new Printer();
private Printer() {
}
//…
}
Подходът enum е по-компактен от подхода на публичното поле, тъй като не е необходимо да пишем наша собствена реализация. Най-важното е, че enum-ите нямат проблеми със сериализацията.
Сериализацията на enum работи по различен начин в сравнение с обикновените обекти: само стойността на името на enum се сериализира. По време на десериализацията методът се използва с десериализираното име за получаване на екземпляр. Освен това enum може да ви предпази от атаки с отражение .
Ще научите повече за отражението в уроците във втория модул, където ще изследваме API за отражение . |
Java забранява инстанцирането на enums — ограничение, заложено в изпълнението на метода newInstance на класа Constructor , който често се извиква при създаване на обекти чрез отражение.
Извадка от code от Constructor.newInstance . Използва се за създаване на enum :
if ((clazz.getModifiers() & Modifier.ENUM) != 0)
throw new IllegalArgumentException("Cannot reflectively create enum objects");
Недостатъците на използването на enum за създаване на сингълтън включват:
-
Липса на мързелива инициализация, тъй като обектът се създава незабавно и инициализацията не може да бъде отложена.
-
Други класове не могат да бъдат удължавани. Тоест, в случаите, когато трябва да наследите друг клас, няма да работи да използвате enum като singleton. В такива случаи трябва да се обърнем към другите опции за внедряване, които вече са ни познати: статичен метод or публична променлива.
-
Когато използвате enum като сингълтън, можете да използвате само едно поле enum .
public enum Device extends Electricity {
PRINTER
}
Този code ще ни даде грешка при компorране:
Но ако трябва да внедрим интерфейс, няма проблем, тъй като enum може да реализира интерфейси:
public enum Device implements Electricity {
PRINTER
}
Ако не е необходимо да използвате наследяване, най-добре е да приложите единичния модел чрез enum . Ние не сме сами в препоръчването на това – самият Джошуа Блок също го прави .
Този подход за внедряване ви дава удобство, компактност, сериализация извън кутията, защита от атаки на отражение и уникалност — всичко, от което се нуждае един добър сингълтън!
GO TO FULL VERSION