Почему использование одиночный элемент вместо статических методов?

Я никогда не находил хорошие ответы на эти простые вопросы о классах помощника/утилиты:

Почему я создал бы одиночный элемент (не сохраняющий состояние) вместо того, чтобы использовать статические методы?

Почему экземпляр объекта был бы необходим, если объект не имеет никакого состояния?

89
задан Aequitas 19 May 2015 в 05:57
поделиться

4 ответа

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

Однако есть несколько угловых случаев, когда даже синглтон без состояния может быть полезен:

  • Вы ожидаете расширить его с состоянием в обозримом будущем.
  • Вам нужен экземпляр объекта по какой-то технической причине.
    Пример: Объекты синхронизации для C# lock или Java synchronized statement.
  • Вам необходимо наследование, т.е. вы хотите иметь возможность легко заменить ваш синглтон на другой, использующий тот же интерфейс, но другую реализацию.
    Пример: Метод Toolkit.getDefaultToolkit() в Java возвращает синглтон, точный тип которого зависит от системы.
  • Вам нужно ссылочное равенство для опорного значения.
    Пример: DBNull.Value в C#.
78
ответ дан 24 November 2019 в 07:19
поделиться

Я мог бы увидеть случай использования синглтона без статических методов вместо класса со статическими методами, а именно для Dependency Injection.

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

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

37
ответ дан 24 November 2019 в 07:19
поделиться

В большинстве языков программирования классы в значительной степени ускользают от системы типов. Хотя класс с его статическими методами и переменными является объектом, он очень часто не может реализовать интерфейс или расширить другие классы. По этой причине его нельзя использовать полиморфным образом, поскольку он не может быть подтипом другого типа. Например, если у вас есть интерфейс IFooable, который требуется несколькими сигнатурами методов других классов, объект класса StaticFoo не может быть использован вместо IFooable, тогда как FooSingleton.getInstance() может (при условии, что FooSingleton реализует IFooable).

Обратите внимание, что, как я прокомментировал ответ Хайнци, синглтон - это паттерн для контроля инстанцирования. Он заменяет new Class() на Class.getInstance(), что дает автору Class больше контроля над экземплярами, который он может использовать для предотвращения создания ненужных экземпляров. Синглтон - это лишь частный случай фабричного паттерна, и относиться к нему следует именно так. Обычное использование делает его скорее частным случаем глобальных реестров, что часто заканчивается плохо, потому что глобальные реестры не должны использоваться просто так.

Если вы планируете предоставлять глобальные вспомогательные функции, то статические методы будут работать просто отлично. Класс не будет действовать как класс, а скорее просто как пространство имен. Я советую вам сохранять высокую связность, иначе вы можете столкнуться со странными проблемами сопряжения.

greetz
back2dos

6
ответ дан 24 November 2019 в 07:19
поделиться

Синглтон не не имеет состояния, он хранит глобальное состояние.

Некоторые причины, которые я могу придумать для использования синглтона:

  • Чтобы избежать утечек памяти
  • Чтобы обеспечить одинаковое состояние для всех модулей в приложении, например, соединение с базой данных
1
ответ дан 24 November 2019 в 07:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: