Зачем использовать синглтон вместо статических методов? - PullRequest
84 голосов
/ 04 мая 2010

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

Зачем мне создавать синглтон (без сохранения состояния) вместо использования статических методов?

Зачем нужен экземпляр объекта, если у объекта нет состояния?

Ответы [ 7 ]

76 голосов
/ 04 мая 2010

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

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

  • Вы ожидаете, что в обозримом будущем расширитесь с указанием штата.
  • Вам необходим экземпляр объекта для некоторой конкретной технической причины.
    Пример: объекты синхронизации для оператора C # lock или оператора Java synchronized.
  • Вам необходимо наследование, т. Е. Вы хотите иметь возможность легко заменить ваш синглтон другим с использованием того же интерфейса, но с другой реализацией.
    Пример: метод Toolkit.getDefaultToolkit() в Java вернет синглтон, точный тип зависит от системы.
  • Требуется ссылочное равенство для часового значения .
    Пример: DBNull.Value в C #.
37 голосов
/ 04 мая 2010

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

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

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

15 голосов
/ 25 февраля 2011

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

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

6 голосов
/ 04 мая 2010

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

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

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

Greetz
back2dos

4 голосов
/ 22 февраля 2014

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

Рассмотрим пример: java.lang.Runtime - это одноэлементный класс в Java. Этот класс допускает разные реализации для каждой JVM. Реализация является единственной для JVM. Если бы этот класс был статическим, мы не можем передавать различные реализации на основе JVM.

Я нашел эту ссылку действительно полезной: http://javarevisited.blogspot.com/2013/03/difference-between-singleton-pattern-vs-static-class-java.html?

Надеюсь, это поможет !!

2 голосов
/ 10 октября 2016

Для меня «Требуется, чтобы Состояние объекта использовало Singleton, Функция Хотите использовать статический метод»

Это зависит от того, что вы хотите. Всякий раз, когда вам нужно состояние объекта (например, полиморфизм, такой как состояние Null вместо null или состояние по умолчанию), вам подходит синглтон, в то время как статический метод используется, когда вам нужна функция (получение входных данных, а затем возвращение выходных данных). *

Я рекомендую для одноэлементного случая, это должно быть всегда одно и то же состояние после его создания. Он не должен быть ни клонируемым, ни получать какое-либо значение для установки (кроме статической конфигурации из файла, например, properties file in java).

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

1 голос
/ 04 мая 2010

Синглтон не без гражданства, он содержит глобальное состояние.

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

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