Какая реальная (то есть практическая) разница существует между статическим классом и одноэлементным шаблоном?
Оба могут быть вызваны без создания экземпляров, оба предоставляют только один «Экземпляр», и ни один из них не является поточно-ориентированным. Есть ли другая разница?
design-patterns
static
singleton
Хорхе Кордова
источник
источник
getInstance()
метода каждый раз, когда вы хотите его использовать (хотя, вероятно, в большинстве случаев это не имеет значения ).singleton
объект, гдеstatic
методы - это просто функции, не-OO-сущность.Ответы:
Что заставляет вас говорить, что одноэлементный или статический метод не безопасен для потоков? Обычно оба должны быть реализованы, чтобы быть потокобезопасными.
Большая разница между синглтоном и кучей статических методов заключается в том, что синглтоны могут реализовывать интерфейсы (или получать полезные базовые классы, хотя, по моему опыту, это менее распространено), так что вы можете обойти синглтон, как если бы он был «просто другим». " реализация.
источник
Foo
, и у вас есть метод, принимающийFoo
в качестве параметра. При такой настройке абоненты могут использовать синглтон в качестве реализации - или они могут использовать другую реализацию. Метод отделен от синглтона. Сравните это с ситуацией, когда у класса просто есть статические методы - каждый кусок кода, который хочет вызвать эти методы, тесно связан с классом, потому что ему нужно указать, какой класс содержит статические методы.Правильный ответ - Джон Скит, на другом форуме здесь .
источник
interface
класс с классом Singleton, но статические методы класса (или, например, C #static class
) не могут.источник
Шаблон Singleton имеет несколько преимуществ по сравнению со статическими классами. Во-первых, синглтон может расширять классы и реализовывать интерфейсы, в то время как статический класс не может (он может расширять классы, но он не наследует членов их экземпляров). Синглтон может быть инициализирован лениво или асинхронно, в то время как статический класс обычно инициализируется при первой загрузке, что приводит к потенциальным проблемам с загрузчиком классов. Однако самое важное преимущество заключается в том, что синглетами можно обрабатывать полиморфно, не заставляя пользователей предполагать, что существует только один экземпляр.
источник
static
занятия не для чего то нужного государства. Это полезно для объединения нескольких функций, т.е.Math
(илиUtils
в проектах). Таким образом, имя класса просто дает нам подсказку, где мы можем найти функции и ничего более.Singleton
это мой любимый шаблон, и я использую его для управления чем-то в одной точке. Он более гибкий, чемstatic
классы, и может поддерживать свое состояние. Он может реализовывать интерфейсы, наследовать от других классов и разрешать наследование.Мое правило выбора между
static
иsingleton
:Если есть множество функций, которые должны храниться вместе, то
static
это выбор. Все, что требует единого доступа к некоторым ресурсам, может быть реализовано какsingleton
.источник
State
комбинация различных свойств объекта, которые обычно меняются со временем. Вы можете Google для формального определения.Статический класс: -
Вы не можете создать экземпляр статического класса.
Загружается автоматически общеязыковой средой .NET Framework (CLR) при загрузке программы или пространства имен, содержащих класс.
Статический класс не может иметь конструктора.
Мы не можем передать статический класс методу.
Мы не можем наследовать статический класс другому статическому классу в C #.
Класс, имеющий все статические методы.
Лучшая производительность (статические методы связаны во время компиляции)
Singleton: -
Вы можете создать один экземпляр объекта и использовать его повторно.
Экземпляр Singleton создается впервые по запросу пользователя.
Класс Singleton может иметь конструктор.
Вы можете создать объект синглтон-класса и передать его методу.
Класс Singleton не говорит о каких-либо ограничениях наследования.
Мы можем располагать объекты одноэлементного класса, но не статического класса.
Методы могут быть переопределены.
Может быть лениво загружаться при необходимости (статические классы всегда загружаются).
Мы можем реализовать интерфейс (статический класс не может реализовать интерфейс).
источник
Статический класс - это класс, в котором есть только статические методы, для которых более подходящим словом будут «функции». Стиль дизайна, воплощенный в статическом классе, является чисто процедурным.
Синглтон, с другой стороны, является паттерном, характерным для ОО-дизайна. Это экземпляр объекта (со всеми присущими ему возможностями, такими как полиморфизм), с процедурой создания, которая гарантирует, что в течение всего времени существования существует только один экземпляр этой конкретной роли.
источник
В шаблоне синглтона вы можете создать синглтон как экземпляр производного типа, вы не можете сделать это со статическим классом.
Быстрый пример:
источник
Расширить ответ Джона Скита
С синглетами легче работать при модульном тестировании класса. Где бы вы ни передавали синглтоны в качестве параметра (конструкторы, сеттеры или методы), вы можете вместо этого заменять имитированную или заглушенную версию синглтона.
источник
MySingleton mockOfMySingleton = mock(MySingleton.class)
.new ClazzToTest(mockSingleton);
Вот хорошая статья: http://javarevisited.blogspot.com.au/2013/03/difference-between-singleton-pattern-vs-static-class-java.html
Статические классы
не может переопределить методы, но может использовать скрытие методов. ( Что такое метод, скрывающийся в Java? Даже объяснение JavaDoc сбивает с толку )
одиночка
Таким образом, я бы использовал статические классы только для хранения утилит, а для всего остального - синглтон.
Правки
статические классы также загружаются лениво. Спасибо @jmoreno ( Когда происходит инициализация статического класса? )
скрытие метода для статических классов. Спасибо @MaxPeng.
источник
Animal animal = new Cat();
тогдаanimal.foo();
что происходит?Еще одно преимущество одиночного файла заключается в том, что его можно легко сериализовать, что может потребоваться, если вам нужно сохранить его состояние на диске или отправить его куда-нибудь удаленно.
источник
Я не большой теоретик ОО, но из того, что я знаю, я думаю, что единственная особенность ОО, которой нет в статических классах по сравнению с синглетонами, это полиморфизм. Но если вам это не нужно, со статическим классом вы, конечно, можете иметь наследование (не уверенное в реализации интерфейса) и инкапсуляцию данных и функций.
Комментарий Морендила: «Стиль дизайна, воплощенный в статическом классе, является чисто процедурным» Я могу ошибаться, но я не согласен. В статических методах вы можете получить доступ к статическим элементам, которые будут точно такими же, как одноэлементные методы для доступа к их отдельным элементам экземпляра.
редактировать:
я на самом деле сейчас думаю, что еще одно отличие заключается в том, что экземпляр класса Static создается при запуске программы * и действует в течение всего жизненного цикла программы, в то время как синглтон создается в какой-то момент явно и может быть также уничтожен.
* или он может быть создан при первом использовании, я думаю, в зависимости от языка.
источник
Чтобы проиллюстрировать точку зрения Джона, то, что показано ниже, невозможно, если Logger был статическим классом. Класс
SomeClass
ожидает, что экземплярILogger
реализации будет передан в его конструктор.Класс Singleton важен для внедрения зависимости.
источник
Хорошо, синглтон - это просто нормальный класс, который создается, но только один раз и косвенно из клиентского кода. Статический класс не создан. Насколько я знаю, статические методы (статический класс должен иметь статические методы) работают быстрее, чем нестатические.
Редактировать:
Описание правила производительности FxCop: «Методы, которые не обращаются к данным экземпляра или методы экземпляра вызова, могут быть помечены как статические (Shared в VB). После этого компилятор будет генерировать не виртуальные сайты вызовов для этих членов, что предотвратит проверка во время выполнения для каждого вызова, который гарантирует, что текущий указатель объекта не равен нулю. Это может привести к ощутимому приросту производительности для чувствительного к производительности кода. В некоторых случаях невозможность доступа к текущему экземпляру объекта представляет проблему правильности ».
Я на самом деле не знаю, относится ли это также к статическим методам в статических классах.
источник
Одиночные экземпляры создаются, просто существует только один экземпляр, следовательно, единственный в Синглтоне.
Статический класс не может быть создан чем-либо, кроме самого себя.
источник
Основные отличия:
источник
Синглтон - лучший подход с точки зрения тестирования. В отличие от статических классов, singleton может реализовывать интерфейсы, и вы можете использовать макетный экземпляр и внедрить их.
В приведенном ниже примере я проиллюстрирую это. Предположим, у вас есть метод isGoodPrice (), который использует метод getPrice (), и вы реализуете getPrice () как метод в одиночном коде.
синглтон, обеспечивающий функциональность getPrice:
Использование getPrice:
Окончательная реализация Singleton:
тестовый класс:
В случае, если мы воспользуемся альтернативой использования статического метода для реализации getPrice (), было сложно смоделировать getPrice (). Вы можете издеваться над статическим электричеством, но не все продукты могут его использовать.
источник
Я согласен с этим определением:
Вы можете найти интересные другие отличия о: шаблон Singleton и статический класс
источник
Одним заметным отличием является различная реализация, которая идет с синглетонами.
Со статическими классами он создается CLR, и мы не можем его контролировать. с одиночными объектами объект создается в первом экземпляре, к которому пытаются получить доступ.
источник
Во многих случаях эти два не имеют практического различия, особенно если экземпляр синглтона никогда не изменяется или изменяется очень медленно, например, при хранении конфигураций.
Я бы сказал, что самая большая разница в том, что синглтон по-прежнему является обычным Java Bean-компонентом, а не специализированным классом Java, предназначенным только для статических вычислений. И из-за этого синглтон принимается во многих других ситуациях; на самом деле это стратегия реализации Spring Framework по умолчанию. Потребитель может знать, а может и не знать, что это передаваемый синглтон, он просто обращается с ним как с обычным Java-бином. Если требования изменяются, а синглтон должен стать вместо этого прототипом, как мы часто видим в Spring, это может быть сделано полностью без каких-либо изменений кода для потребителя.
Кто-то еще упоминал ранее, что статический класс должен быть чисто процедурным, например, java.lang.Math. На мой взгляд, такой класс никогда не должен передаваться, и они никогда не должны содержать ничего, кроме static final, в качестве атрибутов. Для всего остального используйте синглтон, так как он намного гибче и проще в обслуживании.
источник
У нас есть база БД, которая устанавливает соединения с Back-end. Чтобы избежать грязного чтения среди нескольких пользователей, мы использовали одноэлементный шаблон, чтобы обеспечить доступность одного экземпляра в любой момент времени.
В c # статический класс не может реализовать интерфейс. Когда одному классу экземпляра необходимо реализовать интерфейс для бизнес-контрактов или целей IoC, здесь я использую шаблон Singleton без статического класса.
Синглтон обеспечивает способ поддерживать состояние в сценариях без сохранения состояния
Надеюсь, что это поможет вам ..
источник
Отличие от статического класса
В JDK есть примеры как singleton, так и static, с одной стороны
java.lang.Math
, это финальный класс со статическими методами, с другойjava.lang.Runtime
- синглтон-класс.Преимущества синглтона
Если вам нужно поддерживать состояние, а не одноэлементный шаблон лучше, чем статический класс, потому что поддержание состояния в статическом классе приводит к ошибкам, особенно в параллельной среде, которые могут привести к условиям гонки без адекватной параллельной модификации синхронизации несколькими потоками.
Класс Singleton может быть загружен с отложенной загрузкой, если он тяжелый объект, но статический класс не имеет таких преимуществ и всегда загружен с нетерпением.
С помощью singleton вы можете использовать наследование и полиморфизм для расширения базового класса, реализации интерфейса и предоставления различных реализаций.
Поскольку статические методы в Java не могут быть переопределены, они ведут к негибкости. С другой стороны, вы можете переопределить методы, определенные в одноэлементном классе, расширив его.
Недостатки статического класса
Преимущества статического класса
Существует несколько реализаций синглтон-паттернов, каждый из которых имеет свои преимущества и недостатки.
Подробное описание каждого из них слишком многословно, поэтому я просто поместил ссылку на хорошую статью - Все, что вы хотите знать о Синглтоне
источник
источник
а. Сериализация - Статические члены принадлежат классу и, следовательно, не могут быть сериализованы.
б. Хотя мы сделали конструктор закрытым, статические переменные-члены все равно будут перенесены в подкласс.
с. Мы не можем выполнить отложенную инициализацию, поскольку все будет загружено только при загрузке класса.
источник
С точки зрения клиента, статическое поведение известно клиенту, но поведение Singleton может быть скрыто от клиента. Клиент может никогда не узнать, что есть только один экземпляр, с которым он играет снова и снова.
источник
Я прочитал следующее и думаю, что это тоже имеет смысл:
из книги «Объектно-ориентированный мыслительный процесс», 4-е изд.
источник
В статье, которую я написал, я описал свою точку зрения о том, почему синглтон намного лучше, чем статический класс:
источник
Мы можем создать объект синглтон-класса и передать его методу.
Класс Singleton не ограничивает наследование.
Мы не можем распоряжаться объектами статического класса, но можем использовать одноэлементный класс.
источник
Существует огромная разница между одним экземпляром статического класса (то есть единственным экземпляром класса, который является статической или глобальной переменной) и одним статическим указателем на экземпляр класса в куче:
Когда ваше приложение завершается, вызывается деструктор экземпляра статического класса. Это означает, что если вы использовали этот статический экземпляр как синглтон, ваш синглтон перестал работать правильно. Если все еще выполняется код, который использует этот синглтон, например, в другом потоке, этот код, скорее всего, потерпит крах.
источник
Разница в моей голове заключается в реализации объектно-ориентированного программирования (Singleton / Prototype) или функционального программирования (Static).
Мы слишком сосредоточены на количестве объектов, созданных с помощью одноэлементного шаблона, когда нам нужно сосредоточиться на том, чтобы в конце мы удерживали объект. Как уже говорили другие, он может быть расширен, передан в качестве параметра, но самое главное, он заполнен государством.
С другой стороны, static используется для реализации функционального программирования. Статические члены принадлежат классу. Они без гражданства.
Кстати, вы знали, что можете создавать одноэлементные статические классы :)
источник