Одиночка (шаблон проектирования)

Одиночка
Singleton
Тип порождающий
Плюсы организует API; неявно загружает нужные модули в нужном порядке; оставляет место для второго похожего объекта
Минусы усложняет тестирование, многопоточность и отслеживание задержек; одиночки не должны неявно зависеть друг от друга
Описан в Design Patterns Да

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

Цель

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

Глобальный «одинокий» объект — именно объект (log().put("Test");), а не набор процедур, не привязанных ни к какому объекту (logPut("Test");) — бывает нужен, если:

  • Используется существующая объектно-ориентированная библиотека и ей нужен объект, унаследованный от определённого класса/интерфейса.
  • Есть шансы, что один объект когда-нибудь превратится в несколько[1].
  • Дополнительные факторы, исполнимые в обеих концепциях, но хорошо сочетающиеся с методикой ООП:
    • Интерфейс объекта (например, игрового мира) слишком сложен, и объект/префикс log служит для организации API.
    • В зависимости от каких-нибудь условий и настроек, создаётся один из нескольких объектов. Например, в зависимости от того, ведётся лог или нет, создаётся настоящий объект, пишущий в файл, или «заглушка», ничего не делающая.
    • Создание объекта занимает время, и для красоты объект можно создавать, когда на экране уже что-то видно.

Такие объекты можно создавать и при инициализации программы. Это может приводить к следующим трудностям:

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

Одиночка может принадлежать и не глобальному пространству имён, а какому-то объекту — например, главной форме Qt.

Плюсы

  • Наведение порядка в глобальном пространстве имён.
  • Ускорение начального запуска программы, если есть множество одиночек, которые не нужны для запуска. Особенно удачно выходит, если создание всех «одиночек» даёт ощутимую задержку, а создание каждого отдельного — практически незаметно.
    • Ускоряется и неуправляемая инициализация программы (до тела): будут запущены только те модули, которые действительно там нужны. А когда тело получит управление, можно хотя бы нарисовать заставку.
  • Упрощение кода инициализации — система автоматически неявно отделит нужные компоненты от ненужных и проведёт топологическую сортировку.
  • Одиночку можно в дальнейшем превратить в шаблон-стратегию или несколько таких объектов[1].
    • Пример шаблона-стратегии: запись журнала действий в файл или в никуда.
    • Пример нескольких объектов: размножив классы Player и Renderer, можно сделать игру вдвоём на одной машине.

Минусы

  • Усложняется контроль за межпоточными гонками и задержками.
    • Многопоточного «одиночку» сложно писать «из головы»[1][2]: доступ к давно построенному одиночке в идеале не должен открывать мьютекс. Лучше проверенные решения. Как пример см. преамбулу к статье Модель памяти Java.
    • Конфликт двух потоков за недостроенного одиночку приведёт к задержке.
    • Если объект создаётся долго, задержка может мешать пользователю или ещё как-то нарушать реальное время. В таком случае его создание лучше перенести в старт программы.
    • Если программа стартует долго, сложнее становится сделать строку прогресса.
  • Сам факт, что две далёкие друг от друга функции неявно полагаются на одного одиночку, может оказаться плохой архитектурой[2].
  • Требуются особые функции для модульного тестирования, чтобы физически изолировать тесты[3] — например, сделать менеджер одиночек не единственным[3]. Впрочем, одиночками часто являются модули общения с аппаратурой, объектами ОС[1], программным окружением и пользователем, которые модульному тестированию поддаются плохо.
  • Требуется особая тактика тестирования готовой программы, ведь пропадает даже понятие «простейшая запускаемость» — запускаемость зависит от конфигурации.
  • Маленький объект без данных — чистый шаблон-стратегию или null object — обычно держат в сегменте данных, а не в динамической памяти, и превращают в одиночку в особых случаях.
  • Сами по себе одиночки никак не заведуют порядком выгрузки. Возможна даже ситуация «сборщик мусора уничтожил одиночку, клиент создал нового»[1]. Некоторые языки (Паскаль) гарантируют порядок уничтожения модулей, а если нет — можно его обеспечить сторонними средствами, или при выходе явно прекратить всю подозрительную деятельность.
  • Компоненты не должны иметь неявных связей между собой, иначе небольшое изменение — в программном коде, файле настроек, сценарии пользования — может спутать порядок и вызвать трудноуловимую ошибку. Пример: одиночка А использует COM, но полагается на CoInitialize, вызванный одиночкой Б, и без него работать не может. Решение: сделать одиночку CoInit, который явно используется и А, и Б.
    • Одиночки требуют особого внимания, если один из компонентов заведомо ненадёжен и для адекватной работы требует особых условий («разглючек»): библиотека, которая иногда портит память; сеть, которая разрывает соединение, если слишком долго ждать; типографский движок, способный загрузить шрифты в одном порядке и не способный наоборот… Тогда, в зависимости от порядка инициализации, компонент может сработать адекватно или нет.

Применение

  • должен быть ровно один экземпляр некоторого класса, легко доступный всем клиентам;
  • единственный экземпляр должен расширяться путём порождения подклассов, и клиентам нужно иметь возможность работать с расширенным экземпляром без модификации своего кода.

Возможные замены

  • Просто создать объект при запуске[2]. Если объект гарантированно нужен всегда, можно и не делать его одиночкой.
  • Внедрение зависимости — создать объект, а потом как-то передать его всем, кто им пользуется[2][4].

Примеры использования

  • Ведение отладочного файла для приложения.
  • В любом приложении для iOS существует класс AppDelegate, реагирующий на системные события.

Примеры реализации

Java 1.6

Java

Java 1.5

Python

Из PEP 0318 Архивная копия от 3 июня 2020 на Wayback Machine:

Из PEP 0318 Архивная копия от 3 июня 2020 на Wayback Machine[нет в источнике]:

C++

Ниже приведена одна из возможных реализаций паттерна Одиночка на C++ (известная как синглтон Майерса), где одиночка представляет собой статический локальный объект. Важным моментом является то, что конструктор класса объявлен как private, что позволяет предотвратить создание экземпляров класса за пределами его реализации. Помимо этого, закрытыми также объявлены конструктор копирования и оператор присваивания. Последние следует объявлять, но не определять, так как это позволяет в случае их случайного вызова из кода получить легко обнаруживаемую ошибку компоновки. Отметим также, что приведенный пример не является потокобезопасным в C++03, для работы с классом из нескольких потоков нужно защитить переменную theSingleInstance от одновременного доступа, например, с помощью мьютекса или критической секции. Впрочем, в C++11 синглтон Майерса является потокобезопасным и без всяких блокировок.

Ещё один пример реализации одиночки на C++ с возможностью наследования для создания интерфейса, каркасом которого послужит, собственно, одиночка. Временем «жизни» единственного объекта удобно управлять, используя механизм подсчета ссылок.

C#

PHP 4

PHP 5

PHP 5.4

Delphi

Для Delphi 2005 и выше подходит следующий пример (не потоко-безопасный):

Для более ранних версий следует переместить код класса в отдельный модуль, а объявление Instance заменить объявлением глобальной переменной в его секции implementation (до Delphi 7 включительно секции class var и strict private отсутствовали).

Dart

Io

Ruby

Common Lisp

VB.NET

Perl

ActionScript 3

CoffeeScript

JavaScript

Objective-C

Swift

Scala, Kotlin

См. также

Литература

  • Алан Шаллоуей, Джеймс Р. Тротт Шаблоны проектирования. Новый подход к объектно-ориентированному анализу и проектированию = Design Patterns Explained: A New Perspective on Object-Oriented Design. — М.: «Вильямс», 2002. — С. 288. — ISBN 0-201-71594-5.
  • Эрик Фримен, Элизабет Фримен. Паттерны проектирования = Head First Design Patterns. — СПб.: Питер, 2011. — 656 с. — ISBN 978-5-459-00435-9.

Ссылки

Примечания

  1. 1 2 3 4 5 Источник. Дата обращения: 21 ноября 2023. Архивировано 21 ноября 2023 года.
  2. 1 2 3 4 Drawbacks of the Singleton Design Pattern | Baeldung
  3. 1 2 How to write unit tests for a singleton class | Technical Feeder. Дата обращения: 21 ноября 2023. Архивировано 21 ноября 2023 года.
  4. https://medium.com/@shashidj206/the-singleton-design-pattern-best-practices-and-pitfalls-58f9d1c17ab7

Read other articles:

Educational year group 4th Grade redirects here. For the South Park episode, see 4th Grade (South Park). This article needs additional citations for verification. Please help improve this article by adding citations to reliable sources. Unsourced material may be challenged and removed.Find sources: Fourth grade – news · newspapers · books · scholar · JSTOR (August 2019) (Learn how and when to remove this template message) 4th grade class at Acorn Woodl...

 

 

History of China Storia della Cina Preistoria Paleolitico c. 500 000 anni fa – c. 8500 a.C. Neolitico c. 8500 – c. 2070 a.C. Antica Dinastia Xia c. 2100-c. 1600 a.C. Dinastia Shang c. 1600-c. 1046 a.C. Dinastia Zhou c. 1045-256 a.C.  Dinastia Zhou occidentale  Dinastia Zhou orientale    Periodo delle primavere e degli autunni    Periodo degli Stati Combattenti Imperiale Dinastia Qin 221-206 a.C. Dinastia Han 206 a.C.-220 d.C.   Dinastia Han occ...

 

 

Ne doit pas être confondu avec Nombre réel, Nombre surréel, Nombre superréel ou Nombre pseudo-réel. Représentation des infinitésimaux (ε) et infinis (ω) sur la droite des nombres hyperréels (1/ε = ω) En mathématiques, le corps ordonné des nombres hyperréels constitue une extension, notée *ℝ, des nombres réels usuels, permettant de donner un sens rigoureux aux notions de quantité infiniment petite ou infiniment grande. On peut éviter alors l'emploi des passages à la limit...

Garda Nasional UdaraAir National GuardLambang Garda Nasional Udara Amerika SerikatAktif18 September 1947–sekarangNegara Amerika SerikatAliansiFederal (10 U.S.C. § E)Negara bagian dan teritori (32 U.S.C.)Cabang Angkatan Udara Amerika SerikatPeranMendukung Angkatan Udara dengan pasuka udara cadangan siap tempur (Titel 10) serta melindungi dan mendukung masing-masing negara bagian (Titel 32)Jumlah personel107.414 penerbang1.080 pesawatBagian dari Garda Nasional Biro Garda NasionalMarkasT...

 

 

Довнар Геннадій СтаніславовичНародився 8 липня 1925(1925-07-08)село Брияльове Березинський район, Мінська область, БілорусьПомер 18 грудня 2009(2009-12-18) (84 роки)ЛуганськПоховання ЛуганськКраїна  СРСР УкраїнаДіяльність Письменник, публіцистСфера роботи творче і професіональ...

 

 

هذه مقالة غير مراجعة. ينبغي أن يزال هذا القالب بعد أن يراجعها محرر مغاير للذي أنشأها؛ إذا لزم الأمر فيجب أن توسم المقالة بقوالب الصيانة المناسبة. يمكن أيضاً تقديم طلب لمراجعة المقالة في الصفحة المخصصة لذلك. (مايو 2019) الرجل في القمرThe Man in the Moon (بالإنجليزية) معلومات عامةالصنف ...

Koordinat: 39°26′26.26″N 44°14′04.26″E / 39.4406278°N 44.2345167°E / 39.4406278; 44.2345167 Foto situs Durupınar pada tahun 2007. Durupinar (dalam ejaan bahasa Turki: Durupınar) adalah nama situs atau tempat ditemukannya suatu struktur tanah unik di Gunung Tendürek, daerah Turki sebelah timur. Tempat ini terletak 3 kilometer (2 mi) di sebelah utara perbatasan Turki dengan Iran, 16 km (10 mi) di sebelah tenggara kota Doğubeyazıt, di provi...

 

 

Si ce bandeau n'est plus pertinent, retirez-le. Cliquez ici pour en savoir plus. Cet article ne cite pas suffisamment ses sources (juillet 2020). Si vous disposez d'ouvrages ou d'articles de référence ou si vous connaissez des sites web de qualité traitant du thème abordé ici, merci de compléter l'article en donnant les références utiles à sa vérifiabilité et en les liant à la section « Notes et références » En pratique : Quelles sources sont attendues ? Co...

 

 

Human settlement in EnglandWhetstoneBarnet House: previously Barnet council offices, originally the Ever-Ready building, dominates the centre of Whetstone.WhetstoneLocation within Greater LondonOS grid referenceTQ265935London boroughBarnetCeremonial countyGreater LondonRegionLondonCountryEnglandSovereign stateUnited KingdomPost townLONDONPostcode districtN20Dialling code020PoliceMetropolitanFireLondonAmbulanceLondon UK ParliamentChipping BarnetLondon...

Estadio José María MinellaNama lengkapEstadio José María MinellaLokasiMar del Plata, ArgentinaKoordinat38°01′04.6″S 57°34′56.4″W / 38.017944°S 57.582333°W / -38.017944; -57.582333Koordinat: 38°01′04.6″S 57°34′56.4″W / 38.017944°S 57.582333°W / -38.017944; -57.582333PemilikMunisipalitas General PueyrredónKapasitas35.354[1]Ukuran lapangan105 x 70 mKonstruksiDidirikan1976–1978Dibuka21 Mei 1978PemakaiClub Atlé...

 

 

  关于与「鍾晴 (藝人)」標題相近或相同的条目,請見「鍾晴」。 鍾晴2020年擔任婚紗模特兒女艺人本名鍾艾彌[1]罗马拼音Chung Ching英文名Phoebe(前名)Karlie昵称翻版薛凱琪[2]、精靈小花国籍 中华人民共和国(香港)民族漢族出生 (1992-04-05) 1992年4月5日(31歲) 英屬香港职业模特兒、演員、節目主持语言粵語、普通話、英語、日語[3]教育程度大專...

 

 

Libertarian political philosophy This article is about the libertarian political philosophy within the socialist movement. For the branch of anarchism emphasizing social equality, see Social anarchism. For the type of libertarianism stressing both individual freedom and social equality, see Left-libertarianism. For the political philosophy that incorporates liberal principles to socialism, see Liberal socialism. For the variety of liberalism that endorses a regulated market economy and the ex...

Resort and casino near Temecula, California Pechanga Resort Casino Address 45000 Pechanga Parkway, Temecula, CA 92592Opening dateJune 24, 2002ThemeNative American CasinoNo. of rooms1,100Total gaming space200,000 sq ft (19,000 m2)Notable restaurantsGreat Oak SteakhousePaisano'sBamboo1882 CantinaCasino typeLand-basedOwnerPechanga Band of Luiseño IndiansRenovated in2004, 2015-2018WebsitePechanga Resort Casino home page The Pechanga Resort Casino is a Native American casino o...

 

 

Popular science book by Martin Gardner The Ambidextrous Universe Cover of the first editionAuthorMartin GardnerIllustratorJohn MackeyCover artistGermano FacettiCountryUnited StatesLanguageEnglishSubjectsSymmetry, Science, MathematicsPublisherPenguin BooksPublication date1964Media typePrint (Paperback)Pages276 (1st edition) 401 (3rd edition)ISBN978-0-486-44244-0OCLC57373717Dewey Decimal539.7/2 22LC ClassQC793.3.S9 G37 2005 The Ambidextrous Universe is a popular science book by M...

 

 

Seismic risk map of Colombia Aviso del Terremoto, 1785 The subduction of the Malpelo Plate (left) below the North Andes Plate (right) causes most of the earthquakes in Colombia. This is a list of earthquakes in Colombia. Colombia is a seismically active country and has a large seismic risk in many areas of its territory due to its location at the boundaries of the Malpelo, Panama, Caribbean, North Andes (where most earthquakes occurred) and South American Plates along the Pacific Ring of Fire...

Konflik Nagorno-KarabakhSituasi militer saat ini di Nagorno-KarabakhTanggal1994–sekarang (29 tahun, 9 bulan, 1 minggu dan 1 hari)Fase Utama 1991–1994LokasiPerbatasan negara Armenia–Azerbaijan dan garis kontak Nagorno-Karabakh–Azerbaijan, Kaukasus SelatanStatus Masih berlangsungPihak terlibat  Armenia Nagorno-KarabakhPemasok persenjataan:  Russia  Belarus  Azerbaijan Dukungan:  Turki[1][2][3]  Pakistan[4...

 

 

1977 single by Billy JoelJust the Way You AreSide-A label of U.S. vinyl singleSingle by Billy Joelfrom the album The Stranger B-sideGet It Right the First Time/ViennaReleasedSeptember 1977Recorded1976GenreSoft rock, smooth jazz[1][2]Length4:47 (Album version)3:36 (Single version)LabelColumbiaSongwriter(s)Billy JoelProducer(s)Phil RamoneBilly Joel singles chronology The Entertainer (1974) Just the Way You Are (1977) Movin' Out (Anthony's Song) (1977) AudioBilly Joel - Just the ...

 

 

Entertainment venue located in United Kingdom The Alcazar with a poster for The Battle of Waterloo The Alcazar, also known as the Alcazar Cinematograph Theatre, was an entertainment venue in Fore Street, Edmonton in London. The building was destroyed during World War II.[1] The Alcazar opened in 1913 with the film The Battle of Waterloo. In addition to being a cinema, the Alcazar hosted concerts, roller skating, boxing, and wrestling. It could seat 1,700 people and had a separate danc...

超級機器人大戰α/超級機器人大戰αfor Dreamcastスーパーロボット大戦α/スーパーロボット大戦αfor Dreamcast「超級機械人大戰α」PS版的遊戲封面类型战略角色扮演(SRPG)平台PlayStationDreamcastGame Archives开发商PS:萬普DC:萬普Smilebit Corporation发行商萬普总监寺田貴信制作人寺田貴信じっぱひとからげ系列超級機械人大戰系列模式单人发行日PS(通常版、限定版):2000年5月25日DC:2001年8月30...

 

 

1988 film by Jim O'Brien This article is about the British 1988 film. For the Australian film from 2015, see The Dressmaker (2015 film). The DressmakerDirected byJim O'BrienWritten byJohn McGrathBased onThe Dressmaker by Beryl BainbridgeProduced by Steve Clark-Hall John McGrath Ronald Shedlo Starring Joan Plowright Billie Whitelaw Jane Horrocks CinematographyMichael CoulterEdited byWilliam DiverMusic byGeorge FentonProductioncompanies British Screen Productions Channel Four Films Distributed ...

 

 

Strategi Solo vs Squad di Free Fire: Cara Menang Mudah!