Что такое паттерн синглтон и когда его использовать.

Шаблоны проектирования в целом позволяют разработчикам использовать заранее определенные и проверенные шаблоны для структурирования логического решения того или иного типа проблемы.

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

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

Что такое паттерн Синглтон?

Одноэлементный шаблон - это способ структурировать ваш код таким образом, чтобы у вас никогда не могло быть более одного экземпляра вашей логики.

Если это еще не было очевидно, эти шаблоны предназначены для парадигмы объектно-ориентированного программирования. Это означает, что приведенное выше предложение можно перевести на:

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

Как вы скоро увидите, в Typescript есть все необходимые инструменты, чтобы мы действительно могли гарантировать, что приведенное выше утверждение на 100% верно.

Реализация синглтона на TypeScript

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

Решение состоит из двух частей:

  1. С одной стороны, нам нужно предоставить новый способ создания экземпляра нашего класса. Таким образом, мы можем контролировать, как и когда это произойдет.
  2. С другой стороны, нам также нужно удерживать разработчиков от использования ключевого слова new в отношении нас.

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

А второй части можно добиться, «спрятав» конструктор нашего класса, сделав его private. При этом вы не сможете создать новый экземпляр, поскольку метод конструктора, который неявно вызывается при использовании ключевого слова new, не будет доступен для вас извне.

Давайте посмотрим на небольшой пример:

Обратите внимание, как я сказал «извне класса», поскольку конструктор является частным, его можно использовать изнутри (внутри метода getIntance).

Если вы попытаетесь создать экземпляр этого класса, вы получите следующую ошибку:

Однако вы можете использовать его так:

Результатом будет:

constructor called!
my logic!

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

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

Инструменты OSS, такие как Bit, предлагают отличные возможности разработчика для создания независимых компонентов и составления приложений. Многие команды начинают с создания своих дизайн-систем или микро-интерфейсов с помощью независимых компонентов.
Попробуйте →

Какие проблемы решает Синглтон?

Какая польза от класса, который можно создать только один раз? На самом деле, если честно, это звучит как антипаттерн, но это не так!

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

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

То же самое касается синглтонов, только вместо того, чтобы иметь дело с примитивным значением, мы имеем дело с потенциально сложным объектом, который может предоставить разработчикам надежный и простой в использовании API, не беспокоясь о побочных эффектах. -эффекты.

Итак, позвольте мне снова спросить вас, что именно мы решаем, реализуя эту прославленную глобальную переменную?

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

  • Если вы пытаетесь контролировать использование ресурсов. Централизовав поток информации в одном экземпляре, вы можете полностью контролировать объем данных, поступающих и исходящих из внешнего ресурса. Будь то отдельный файл, соединение с базой данных или катушка принтера. Во всех случаях наличие единственного экземпляра интерфейса к ресурсу дает вам полный контроль над ним.
  • Ведение журнала. Мы все это сделали, добавление журналов по всему коду обычно необходимо, особенно для больших проектов. Включение, отключение их и даже изменение их уровня по умолчанию может быть проблемой, если вы не централизуете код в одном объекте, то есть в «регистраторе». Если ваш регистратор будет синглтоном, вы гарантируете, что только один его экземпляр в памяти будет записывать ваши данные (вместо того, чтобы случайно создать несколько экземпляров одновременно и заставить их отправлять повторяющиеся сообщения).
  • Кеширование. Кэш в памяти может быть реализован с помощью синглтона. Если подумать, он подходит: вы не хотите иметь несколько экземпляров, вам нужен централизованный и простой способ доступа к нему. Это определенно жизнеспособный вариант использования.

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

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

Почему бы вам избежать синглтонов?

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

И Синглтон не исключение. Так что же не так с шаблоном Singleton?

  • Это нарушает принцип единой ответственности. Ничего страшного, если, конечно, вы не придерживаетесь принципов. По сути, SRP говорит, что каждый класс должен заботиться только об одном и только одном, а синглтон заботится о двух вещах: обеспечение наличия только одного самого себя и фактическая логика, для которой он был разработан.
  • Плохое управление памятью. Да ладно, кому все равно нужна память, если вы используете Firefox, маленький синглтон не имеет значения! По правде говоря, синглтоны живут в вашей памяти в значительной степени… ну, навсегда, или пока ваш код все равно не умрет. Это плохо? Это определенно зависит от обстоятельств, мы буквально говорим об одном экземпляре класса. Насколько велик ваш класс, чтобы превратить это в проблему? Или позвольте мне задать вам противоположный вопрос: насколько мала ваша память, что вы беспокоитесь об одном экземпляре класса? Вероятно, существует несколько сценариев, в которых это может быть проблемой, но браузер не входит в их число.
  • Используя синглтоны, ваши классы скрывают зависимости. Большим системам с множеством зависимостей и огромным набором тестов может не понравиться то, как синглтоны могут играть против них. Помните, как я сказал, что синглтоны - это, по сути, прославленная глобальная переменная? Что ж, если вы используете их таким образом в своих классах, тогда, когда вам нужно протестировать свой код, вы буквально скрываете внешнюю зависимость, которую вы не сможете легко перезаписать.
  • Вы не можете расширить Singleton. Я имею в виду, зачем тебе? Это главный вопрос. Синглтон должен быть уникальным, а не расширенным - и тот факт, что мы используем статические методы и частный конструктор, значительно усложняет работу в этом отделе -. Но предположим, что вам нужен способ превратить класс в синглтон, что ж, в этом случае ваш единственный шанс - это интерфейс, который, к счастью для вас, поддерживает TypeScript. Таким образом, в тот момент, когда вы заявляете, что ваш класс должен реализовывать интерфейс Singleton, вы будете вынуждены предоставить правильные методы.

Я уверен, что вы можете придумать еще парочку, но вы понимаете, что не существует идеального образца, как и идеального вкуса мороженого - кроме лимона, но это уже другая тема.

Синглтон - лучший паттерн? Не с большой долей вероятности. Это худшее? Неа! определенно есть несколько очень подходящих вариантов использования этого шаблона, и при осторожном использовании он может принести большую пользу.

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

А вы? Вы за или против синглтона? Оставьте комментарий ниже и поделитесь своими мыслями об этом шаблоне.

Учить больше