В объектно-ориентированном программировании шаблон синглтон — это шаблон проектирования программного обеспечения , который ограничивает создание экземпляра класса единственным экземпляром. Это один из известных шаблонов проектирования «Банды четырех» , которые описывают, как решать повторяющиеся проблемы в объектно-ориентированном программном обеспечении. [1] Шаблон полезен, когда для координации действий в системе требуется ровно один объект.
Более конкретно, шаблон Singleton позволяет классам: [2]
Термин происходит от математической концепции синглтона .
Синглтоны часто предпочитают глобальным переменным, потому что они не загрязняют глобальное пространство имен (или их содержащее пространство имен). Кроме того, они допускают ленивое выделение и инициализацию, тогда как глобальные переменные во многих языках всегда будут потреблять ресурсы. [1] [3]
Шаблон синглтон также может быть использован в качестве основы для других шаблонов проектирования, таких как шаблоны abstract factory , factory method , builder и prototype . Объекты фасада также часто являются синглтонами, поскольку требуется только один объект фасада.
Ведение журнала — это распространенный реальный пример использования одиночных объектов, поскольку все объекты, желающие регистрировать сообщения, требуют единой точки доступа и концептуально записывают данные в один источник. [4]
Реализации шаблона Singleton гарантируют, что когда-либо будет существовать только один экземпляр класса Singleton, и обычно предоставляют глобальный доступ к этому экземпляру.
Обычно это достигается следующим образом:
Экземпляр обычно хранится как частная статическая переменная ; экземпляр создается при инициализации переменной в какой-то момент до первого вызова статического метода.
Эта реализация C++11 основана на реализации до C++98, изложенной в книге [ требуется ссылка ] .
#include <iostream> class Singleton { public : // определяет операцию класса, которая позволяет клиентам получать доступ к его уникальному экземпляру. static Singleton & get () { // может отвечать за создание своего собственного уникального экземпляра. if ( nullptr == instance ) instance = new Singleton ; return * instance ; } Singleton ( const Singleton & ) = delete ; // правило трех Singleton & Operator = ( const Singleton & ) = delete ; static void destruct () { delete instance ; instance = nullptr ; } // существующий интерфейс указывается здесь int getValue () { return value ; } void setValue ( int value_ ) { value = value_ ; } private : Singleton () = default ; // нет открытого конструктора ~ Singleton () = default ; // нет открытого деструктора static Singleton * instance ; // объявление переменной класса int value ; }; Singleton * Singleton :: instance = nullptr ; // определение переменной класса int main () { Singleton :: get (). setValue ( 42 ); std :: cout << "value=" << Singleton :: get (). getValue () << '\n' ; Singleton :: destruct (); }
Вывод программы:
значение = 42
Это реализация синглтона Мейерса [5] в C++11. У синглтона Мейерса нет метода destruct. Вывод программы такой же, как и выше.
#include <iostream> class Singleton { public : static Singleton & get () { static Singleton instance ; return instance ; } int getValue () { return value ; } void setValue ( int value_ ) { value = value_ ; } private : Singleton () = default ; ~ Singleton () = default ; int value ; }; int main () { Singleton :: get (). setValue ( 42 ); std :: cout << "value=" << Singleton :: get (). getValue () << '\n' ; }
Реализация singleton может использовать ленивую инициализацию , при которой экземпляр создается при первом вызове статического метода. В многопоточных программах это может вызвать состояние гонки , которое приводит к созданию нескольких экземпляров. Следующий пример Java 5+ [6] представляет собой потокобезопасную реализацию, использующую ленивую инициализацию с двойной проверкой блокировки .
публичный класс Singleton { частный статический изменчивый экземпляр Singleton = null ; частный синглтон () {} public static Singleton getInstance () { if ( instance == null ) { synchronized ( Singleton . class ) { if ( instance == null ) { instance = new Singleton (); } } } return instance ; } }
Некоторые считают синглтон антишаблоном , который вводит глобальное состояние в приложение, часто без необходимости. Это вводит потенциальную зависимость от синглтона другими объектами, требуя анализа деталей реализации, чтобы определить, существует ли зависимость на самом деле. [7] Эта повышенная связанность может вызвать трудности с модульным тестированием . [8] В свою очередь, это накладывает ограничения на любую абстракцию, использующую синглтон, например, предотвращая одновременное использование нескольких экземпляров. [8] [9] [10]
Синглтоны также нарушают принцип единственной ответственности , поскольку они несут ответственность за обеспечение своей уникальности наряду с выполнением своих обычных функций. [8]
{{cite book}}
: CS1 maint: несколько имен: список авторов ( ссылка ){{cite book}}
: CS1 maint: несколько имен: список авторов ( ссылка )