В программной инженерии , то шаблон одноточечно является шаблоном проектирования программного обеспечения , что ограничивает создание экземпляра в виде класса к одному «единым» , например. Это полезно, когда требуется ровно один объект для координации действий в системе. Термин происходит от математической концепции синглтона .
Критики считают синглтон анти-шаблоном в том смысле, что он часто используется в сценариях, где он нецелесообразен, вводит ненужные ограничения в ситуациях, когда единственный экземпляр класса фактически не требуется, и вводит глобальное состояние в приложение. [1] [2] [3] [4]
Обзор [ править ]
Шаблон проектирования singleton [5] - это один из двадцати трех хорошо известных шаблонов проектирования «Банда четырех», которые описывают, как решать повторяющиеся проблемы проектирования для разработки гибкого и многократно используемого объектно-ориентированного программного обеспечения, то есть объектов, которые проще в использовании. внедрять, изменять, тестировать и повторно использовать.
Шаблон проектирования singleton решает такие проблемы, как: [6]
- Как можно гарантировать, что у класса есть только один экземпляр?
- Как можно легко получить доступ к единственному экземпляру класса?
- Как класс может управлять созданием своего экземпляра?
- Как можно ограничить количество экземпляров класса?
- Как получить доступ к глобальной переменной?
Шаблон проектирования singleton описывает, как решать такие проблемы:
- Скройте конструктор класса.
- Определите общедоступную статическую операцию (
getInstance()
), которая возвращает единственный экземпляр класса.
Ключевая идея в этом шаблоне - сделать сам класс ответственным за управление его экземпляром (что он создается только один раз).
Скрытый конструктор (объявленный как частный ) гарантирует, что класс никогда не может быть создан извне.
Доступ к общедоступной статической операции можно легко получить, используя имя класса и имя операции ( Singleton.getInstance()
).
Обычное использование [ править ]
- Абстрактная фабрика , Фабричный метод , строитель и прототип модели могут использовать одиночка в их реализации.
- Фасадные объекты часто бывают одиночными, потому что требуется только один фасадный объект.
- Государственные объекты часто бывают одиночными.
- Синглтоны часто предпочтительнее глобальных переменных, потому что:
- Они не загрязняют глобальное пространство имен (или, в языках с вложенными пространствами имен, содержащее их пространство имен) ненужными переменными. [5]
- Они допускают отложенное выделение и инициализацию, тогда как глобальные переменные во многих языках всегда потребляют ресурсы.
Соображения, касающиеся антипаттернов [ править ]
Шаблон Singleton обычно считается "анти-шаблоном" по следующим причинам:
Одноэлементные классы нарушают принципы объектно-ориентированного проектирования [ править ]
- Он не может быть унаследован от . Чтобы добавить новую функциональность, новый класс не может быть наследником, чтобы содержать эту функциональность, нарушая разделение проблем.
- Нет контроля над созданием . Невозможно сказать, относится ли ссылка к существующему экземпляру или новому экземпляру.
- Предотвращает внедрение зависимостей . Поскольку существует только один экземпляр класса, зависимость не может быть введена в него. Если это сделано через свойство, зависимость изменяется для всех ссылок на этот экземпляр.
Одноэлементные классы не допускают разработки через тестирование (TDD). [ редактировать ]
- Поскольку нет контроля над созданием, «чистый» экземпляр объекта не может использоваться для каждого теста.
- Без внедрения зависимостей фиктивные объекты нельзя использовать в тестах.
Реализация [ править ]
Реализация одноэлементного шаблона должна:
- убедитесь, что когда-либо существует только один экземпляр одноэлементного класса; и
- предоставить глобальный доступ к этому экземпляру.
Обычно это делают:
- объявление всех конструкторов класса закрытыми ; и
- предоставление статического метода , возвращающего ссылку на экземпляр.
Экземпляр обычно хранится как частная статическая переменная ; экземпляр создается при инициализации переменной, в какой-то момент до первого вызова статического метода. Ниже приводится пример реализации, написанной на Java .
public final class Singleton { частный статический финальный синглтон INSTANCE = новый синглтон (); частный синглтон () {} общедоступный статический синглтон getInstance () { return INSTANCE ; } }
Реализация Python [ править ]
class Singleton : __instance = None def __new__ ( cls , * args ): if cls . __instance is None : cls . __instance = объект . __new__ ( cls , * args ) возвращает cls . __пример
Реализация C # [ править ]
публичный запечатанный класс Singleton { публичный статический экземпляр Singleton { получить ; } = новый синглтон (); частный синглтон () { } }
В C # вы также можете использовать статические классы для создания синглтонов, где сам класс является синглтоном.
общедоступный статический класс Singleton { общедоступный статический экземпляр MyOtherClass { получить ; } = новый MyOtherClass (); }
Реализация Unity [ править ]
Синглтоны могут быть полезным инструментом при разработке с помощью Unity благодаря уникальному способу создания экземпляров классов. Этот метод предпочтительнее скрытия конструктора, поскольку в Unity можно создать экземпляр объекта с помощью скрытого конструктора.
Чтобы предотвратить перезапись экземпляра, необходимо выполнить проверку, чтобы убедиться, что экземпляр равен нулю. Если Instance не равен нулю, GameObject, содержащий вредоносный скрипт, должен быть уничтожен.
Если другие компоненты зависят от синглтона, порядок выполнения скрипта следует изменить. Это гарантирует, что компонент, определяющий синглтон, будет выполнен первым.
class Singleton : MonoBehaviour { общедоступный статический экземпляр Singleton { получить ; частный набор ; } private void Awake () { if ( Instance ! = null && Instance ! = this ) { Destroy ( this . gameObject ); } else { Экземпляр = это ; } } }
Примечание. Также возможно реализовать, удалив только скрипт-нарушитель, а не GameObject, вместо этого вызывая Destroy (this);
Ленивая инициализация [ править ]
В одноэлементной реализации может использоваться отложенная инициализация , когда экземпляр создается при первом вызове статического метода. Если статический метод может быть вызван из нескольких потоков одновременно, может потребоваться принять меры для предотвращения состояний гонки, которые могут привести к созданию нескольких экземпляров класса. Ниже приводится пример реализации потокобезопасности с использованием отложенной инициализации с блокировкой с двойной проверкой , написанный на Java. [а]
public final class Singleton { частный статический изменчивый экземпляр Singleton = null ; частный синглтон () {} общедоступный статический синглтон getInstance () { если ( экземпляр == нуль ) { синхронизирован ( синглтон . класс ) { если ( экземпляр == нуль ) { экземпляр = новый синглтон (); } } } возвратный экземпляр ; } }
Реализация дротика [ править ]
class Singleton { Синглтон . _ (); статический синглтон получить экземпляр => синглтон . _ ();}
Реализация PHP [ править ]
класс Синглтон{ частный статический $ instance = null ; частная функция __construct () {} публичная статическая функция getInstance () : self { if ( null === self :: $ instance ) { self :: $ instance = new self (); } вернуть self :: $ instance ; }}
Реализация Java [7] [ править ]
public class Coin { частный статический final int ADD_MORE_COIN = 10 ; приватная внутренняя монета ; частный статический экземпляр Coin = new Coin (); // С нетерпением загрузка экземпляра синглтона private Coin () { // закрытый, чтобы никто другой не мог создать экземпляр } public static Coin getInstance () { возвратный экземпляр ; } public int getCoin () { вернуть монету ; } public void addMoreCoin () { монета + = ADD_MORE_COIN ; } public void deductCoin () { монета - ; }}
Реализация Kotlin [7] [ править ]
Ключевое слово объекта Kotlin объявляет одноэлементный класс [8]
object Coin { частная монета var : Int = 0 fun getCoin (): Int { вернуть монету } fun addCoin () { монета + = 10 } fun deductCoin () { монета - }}
Реализация Delphi и Free Pascal [ править ]
GetInstance - это поточно-ориентированная реализация Singleton.
unit SingletonPattern ;интерфейстип TTest = класс запечатанный строгий частный FCreationTime : TDateTime ; публичный конструктор Create ; свойство CreationTime : TDateTime читать FCreationTime ; конец ;функция GetInstance : TTest ;выполнениеиспользует SysUtils , SyncObjs ;var FCriticalSection : TCriticalSection ; FInstance : TTest ;функция GetInstance : TTest ; начать FCriticalSection . Приобрести ; попробуйте, если не назначено ( FInstance ), то FInstance : = TTest . Создать ; Результат : = FInstance ; наконец FCriticalSection . Выпуск ; конец ; конец ;конструктор TTest . Создать ; begin унаследовано Create ; FCreationTime : = Сейчас ; конец ;инициализация FCriticalSection : = TCriticalSection . Создать ;доработка FreeAndNil ( FCriticalSection ) ;конец .
Использование:
процедура TForm3 . btnCreateInstanceClick ( Отправитель : TObject ) ; var i : целое число ; begin for i : = от 0 до 5 do ShowMessage ( DateTimeToStr ( GetInstance . CreationTime )) ; конец ;
Заметки [ править ]
- ^ В Java, чтобы избежать накладных расходов на синхронизацию при сохранении ленивой инициализации с безопасностью потоков, предпочтительным подходом является использование идиомы инициализации по требованию держателя . [ необходима цитата ]
Ссылки [ править ]
- ^ Скотт Денсмор. Почему одиночки - зло , май 2004 г.
- ^ Стив Егге. Синглтоны считаются глупыми , сентябрь 2004 г.
- ^ Беседы о чистом коде - глобальное состояние и синглтоны
- ^ Максимилиано Контьери. Синглтон-паттерн: корень всего зла , июнь 2020 г.
- ^ a b Эрих Гамма, Ричард Хелм, Ральф Джонсон, Джон Влиссидес (1994). Шаблоны проектирования: элементы объектно-ориентированного программного обеспечения многократного использования . Эддисон Уэсли. С. 127 и далее . ISBN 0-201-63361-2.CS1 maint: несколько имен: список авторов ( ссылка )
- ^ «Шаблон проектирования Singleton - проблема, решение и применимость» . w3sDesign.com . Проверено 16 августа 2017 .
- ^ a b «Вы разработчик Android и еще не используете класс Singleton?» .
- ^ "Объявления объекта" . Проверено 19 мая 2020 .
Внешние ссылки [ править ]
Использование внешних ссылок в этой статье может не соответствовать политикам или рекомендациям Википедии . Ноябрь 2016 г. ) ( Узнайте, как и когда удалить этот шаблон сообщения ) ( |
В Wikibook Computer Science / Design Patterns есть страница по теме: Реализации синглтонов на разных языках |
Викискладе есть медиафайлы, связанные с шаблоном синглтона . |
- Полная статья « Объяснение паттерна Java Singleton »
- Четыре различных способа реализации синглтона в Java « Способы реализации синглтона в Java »
- Отрывок из книги: Реализация шаблона Singleton на C # от Джона Скита
- Синглтон в Центре разработчиков шаблонов и практик Microsoft
- Статья IBM Питера Хаггара " Двойная проверка блокировки и шаблон синглтона "
- Статья IBM « Используйте свои одиночные игры с умом », автор: JB Rainsberger
- Гири, Дэвид (25 апреля 2003 г.). «Как ориентироваться в обманчиво простом шаблоне Singleton» . Шаблоны проектирования Java. JavaWorld . Проверено 21 июля 2020 .
- Статья Google " Почему синглтоны вызывают споры "
- Google Singleton Detector (анализирует байт-код Java для обнаружения синглтонов)