Реализация шаблона синглтона в Java

Может ли кто-нибудь привести пример шаблона синглтона и объяснить, почему он необходим?

6 ответов

Решение

Прежде чем идти по одиночному маршруту, пересмотрите. Тебе действительно нужен синглтон? Если вы спрашиваете о сценариях, когда вам нужно реализовать синглтоны, это потому, что потребность в них на самом деле не выражалась. Вам лучше не вводить синглтоны в вашу кодовую базу только потому, что это здорово - следовать шаблонам проектирования.

Чистые переговоры по коду - глобальное государство и одиночные игры

Раз не достаточно

Performant Singletons

Однако, что действительно стоит знать, так это инъекция зависимостей.

Теперь, если вы действительно хотите реализовать синглтоны в Java, я бы порекомендовал Джошуа Блоху "эффективную Java" способ их реализации:

public class Singleton
{
  public static Singleton getInstance() {
    return SingletonHolder.instance;
  }

  private Singleton() {}

  private static final class SingletonHolder {
    static final Singleton instance = new Singleton();    
  }
}

JLS гарантирует, что JVM не будет инициализировать экземпляр, пока кто-то не вызовет getInstance();

Последнее замечание: шаблон блокировки с двойной проверкой нарушен в Java до Java 5. Модель памяти Java 5 делает поток шаблона DCL безопасным, но делает его медленнее, чем SingletonHolder Метод класса в то время как первоначальная цель была оптимизация производительности.

РЕДАКТИРОВАТЬ: Как @Luno указал, начиная со второго издания книги, предпочтительным способом является:

Начиная с версии 1.5, существует третий подход к реализации синглетонов. Просто создайте тип enum с одним элементом:

// Enum singleton - the preferred approach
public enum Elvis {
    INSTANCE;

    public void leaveTheBuilding() { ... }
}

Этот подход функционально эквивалентен общедоступному полевому подходу, за исключением того, что он более лаконичен, предоставляет механизм сериализации бесплатно и обеспечивает железную гарантию от множественных реализаций, даже перед сложными атаками сериализации или отражения. Хотя этот подход еще не получил широкого распространения, одноэлементный тип перечисления является лучшим способом реализации синглтона.

По сути, в Java вы реализуете singleton, предоставляя классу частный конструктор без аргументов (private MyClass()) и статическая (или ленивая) инициализация одного экземпляра класса, который возвращается статическим MyClass getInstance() метод.

Вы можете использовать это, если хотите, чтобы во всем приложении было не более одного экземпляра вашего класса.

Данбен имеет довольно хорошее резюме того, что такое синглтон, поэтому я не буду перефразировать его.

Что касается использования, синглтоны часто представляют собой тонко завуалированные реализации глобальных переменных (что является плохой идеей). Они могут быть полезны для таких вещей, как маршрутизаторы сообщений или классы менеджера (среди прочего).

Часто недооцениваемое место, где синглтоны хороши, это когда вы хотите абстрагироваться от существования состояния. Примером является генератор случайных чисел. На уровне абстракции, он просто генерирует случайные числа и не имеет состояния, о котором вызывающий должен заботиться. На уровне реализации, однако, государство вовлечено. Другой случай, когда функция кэширует результаты или промежуточные вычисления, но вы хотите скрыть эту деталь от вызывающей стороны.

Здесь есть существенный компромисс. Если вы делаете такие вещи, как эти синглтоны, вы уменьшаете количество деталей реализации, о которых должен заботиться вызывающий вашей функции, тем самым уменьшая связь в этом направлении. Однако в то же время вы сильно привязываете свою функцию к одноэлементному объекту, что усложняет тестирование и т. Д. Решение о том, следует ли использовать одноэлементный объект, должно приниматься в зависимости от того, в каком направлении вас больше интересует уменьшение связи.

Предположим, у вас есть только один принтер в офисе, и вам нужно убедиться, что у класса принтера есть только один экземпляр

printer{
private static printer instance =null;
private printer(){}
public static printer getinst(){
if( instance==null){
instant = new printer();

}
return instance;


}


}

в основном

printer v=printer.geti();

" Просто синглтон" в JavaWorld

И если вы действительно хотите попасть в окопы, начните читать о "статические против синглтонов" в группах, или Google его. Всегда горячая тема по меньшей мере!

Другие вопросы по тегам