Время для третьей главы нашего эффективного обзора Java. Сегодняшний – довольно простой. Сегодня мы говорим об одноэлементном шаблоне. Одноэлементный шаблон довольно хорошо известен и в основном сводится к объекту, который позволяет создавать экземпляры только один раз.
Итак, какие преимущества дает нам синглтон?
- Можно избежать многократного создания дорогостоящих объектов.
- Если есть причина, по которой у нас не должно быть неограниченного количества объектов, мы можем владеть управлением экземплярами.
А как насчет некоторых минусов:
- Их чрезвычайно сложно протестировать (наличие вашего одноэлементного интерфейса может немного помочь в этом)
- Они в основном служат глобальным состоянием, которое может быть сложным и вызывать ошибки.
Таким образом, синглтон определенно не обходится без затрат, но, допустим, мы определили, что нам действительно нужен синглтон, каковы наши варианты реализации шаблона? Хорошо эффективная Java использует три метода, включая скрытие конструктора объекта тем или иным способом.
Вариант 1: поле общедоступной константы
Первый вариант, который описан, довольно прост. Первым шагом является создание частного конструктора. После этого вы просто создаете общедоступное статическое конечное поле, в котором создается экземпляр используемого объекта. Давайте рассмотрим пример:
public class CEO { public static final INSTANCE = new CEO(); private CEO() { } public void fire(Employee slacker) { ... } }
Итак, в этом примере мы хотим убедиться, что у нас не будет более одного генерального директора, и поэтому мы создаем синглтон из класса. Затем, когда пользователь хочет получить доступ к генеральному директору, он просто звонит ГЕНЕРАЛЬНОМУ директору.ЭКЗЕМПЛЯР
. Этот метод, безусловно, очень прост в написании и очень прост в использовании. Недостатками является то, что пользователи могут обойти защиту одного экземпляра, используя некоторые навыки отражения. Это также не дает такого большого контроля над созданием экземпляра и возвращением к одноэлементному выбору.
Вариант 2: Получить экземпляр заводской метод
Второй вариант – это то, с чем я больше всего знаком. Этот метод основан на наличии статической фабрики getInstance
заводской метод метод, предоставляющий единственный экземпляр класса. Пример времени:
public class CEO { private static final INSTANCE = new CEO(); private CEO() { } public static CEO getInstance() { return INSTANCE; } public void fire(Employee slacker) { ... } }
Итак, какие преимущества мы здесь получаем? Ну, во-первых, он очень узнаваем как синглтон, поэтому пользователь может легко видеть, с чем они взаимодействуют. Это также позволяет нам больше контролировать создание наших экземпляров. Например, мы можем отложить создание экземпляра объекта до тех пор, пока он не понадобится в первую очередь.
public CEO { private static final INSTANCE; public static synchronized CEO getInstance() { if(INSTANCE == null) { INSTANCE = new CEO(); } return INSTANCE; } }
С таким шаблоном, как этот, вам нужно быть осторожным с условиями гонки. Следует отметить, что этот шаблон все еще подвержен атакам отражения. Эффективная Java также описывает, как обрабатывать сериализацию, поскольку она относится к синглетонам и не является чрезвычайно простой. Мне никогда не приходилось иметь с этим дело, поэтому я не буду заниматься этим здесь но если вам нужно пойти и посмотреть его.
Вариант 3: Перечисление Одного Элемента
Последний вариант – создать перечисление одного элемента. Это был не тот вариант, который я когда-либо видел, и он все еще кажется мне немного неестественным. Итак, давайте рассмотрим пример:
public enum CEO { INSTANCE; public void fire(Employee slacker) { ... } }
Так что же это нам дает? Ну, это просто написать. Вероятно, это наименьший код из трех вариантов. Это также очень безопасно. Это не оставляет возможности для отражения атак. Он также обрабатывает сложности сериализации, которые я пропустил выше. Это делает так, что вы не можете выходить из класса но вы все равно можете реализовать интерфейсы. Эффективная Java показывает, что это вариант, который должно выбрать большинство людей. Учитывая, что я никогда лично не видел, чтобы кто-то использовал этот метод, мне очень интересно, что он представлен как вариант, который большинство должно выбрать.
А как насчет тебя? Вы когда-нибудь видели, как используется этот метод?
Оригинал: “https://dev.to/kylec32/effective-java-tuesday-singletons-3adg”