|
Программирование >> Многопоточная библиотека с принципом минимализма
Реализация шаблона Singleton Шаблон проектирования Singleton (Gamma et al, 1995) представляет собой уникальную комбинацию простого описания и сложной реализации. Об этом свидетельствуют многочисленные книги и журнальные публикации (например, Vlissides, 1996, 1998). Описание шаблона Singleton в книге Gamma et al. (1995) весьма просто: Шаблон гарантирует, что класс имеет только один экземпляр и обеспечивает глобальный доступ к нему . Синглтон - это улучшенный вариант глобальной переменной. Новшество заключается в том, что второй объект типа Singleton создать нельзя. Следовательно, синглтоны можно использовать в приложениях при моделировании типов, имеющих только один экземпляр, таких как Keyboard, Display, PrintManager и Systemclock. Создавать вторые экземпляры таких классов соверщенно неестественно и, кроме того, опасно. Глобальный доступ имеет скрытые побочные последствия - с точки зрения клиента объект класса singleton владеет самим собой. Для создания объекта класса Singleton клиент ничего не должен делать. Следовательно, объект класса Singltone сам создает и разрушает себя. Управление продолжительностью жизни синглтона представляет собой головоломную задачу. В этой главе обсуждаются наиболее важные вопросы, связанные с проектированием и реализацией разных вариантов класса Singleton в языке С++. Свойства, которые отличают синглтон от обычной глобальной переменной. Основные идиомы языка С++ для поддержки синглтонов. Обеспечение уникальности синглтона. Уничтожение синглтона и распознавание доступа после уничтожения. Усовершенствованное управление продолжительностью жизни объекта класса Singltone. Многопоточность. Мы опишем способы решения перечисленных выше проблем, а затем применим их для реализации обобщенного шаблонного класса SingletonHolder. Оптимальной реализации шаблона проектирования Singleton не существует. В зависимости от конкретной задачи наилучшими оказываются различные реализации, включая машинно-зависимые. Подход, описанный в этой главе, предназначен для разработки семейства реализаций на основе обобщенного скелета класса в духе проектирования на основе стратегий (глава 1). Класс SingletonHand оставляет также возможности для его расширения и настройки. В конце этой главы мы разработаем шаблонный класс SingletonHolder, способный генерировать много синглтонов разного типа. Класс SingletonHolder предостав- ляет профаммисту возможности для детального управления распределением памяти при создании и уничтожении синглтонов при условии, что это не создает опасности для потоков. Кроме того, класс определяет, что делать, если пользователь попытался обратиться к уже разрушенному синглтону. Шаблонный класс singletonHolder предоставляет программисту функциональные возможности, выходящие за рамки обычных типов, определенных пользователем. 6.1. Статические данные + статические функции != синглтон На первый взгляд кажется, что для создания класса singleton нужны лишь статические функции-члены и переменные-члены. class Font {...}; class Printerport { ... }; class PrintJob { ... } class MyOnlyPrinter { public: static void AddPrintJobCPrintJobA newjob) { ifCprintQueue .emptyC) && printingPort .availableC)) printingPort . sendCnewjob.DataO); else { printQueue .pushCnewjob); . private: все данные являются статическими static std::queue<PrintJob> printQueue ; static printerport printingPort ; static Font defaultFont ; PrintJob somePrintJobCMyDocument.txt ); MyOnlyPrinter::AddPrintJobCsomePrintJob); Однако это решение в некоторых ситуациях имеет много недостатков. Основная проблема заключается в том, что статические функции не могут быть виртуальными, что не позволяет изменять поведение объекта при открытии кода класса MyOnlyPrinter. Кроме того, инициализация и удаление объекта затрудняются. В классе MyOnlyPrinter нет конкретных точек, в которых инициализируются и удаляются данные, хотя эти задачи могут быть нетривиальными - например, переменная-член default-Font, может зависеть от скорости обмена данными порта, поведение которого описывается переменной printingPort . Таким образом, реализация синглтонов сводится к созданию и управлению уникальным объектом, при этом создавать другие объекты такого типа запрещено. На самом деле этот код иллюстрирует шаблон проектирования Monostate (Ball and Crawford, 1998). 6.2. Основные идиомы языка С++для поддержки синглтонов Чаще всего синглтоны создаются с помощью вариаций следующей идиомы. Заголовочный файл Singleton.h class Singleton public: static Singleton* instanceC) Единственная точка доступа { if (!pinstance ) plnstance = new singleton; return pinstance ; ... операции ... private: SingletonC); предотвращает создание нового объекта класса Singleton Singleton(const Sing1eton&); предотвращает создание копии объекта класса singleton static Sing1eton&* plnstance ; Единственный экземпляр Файл реализации Singleton.cpp Singleton* singleton::pinstance = 0; Поскольку все конструкторы закрыты, код пользователя не может создать объект класса Singleton. Однако класс содержит функции-члены, в частности, функцию Instance, которые позволяют создавать объекты. Следовательно, требование уникальности объекта класса Singleton накладывается на этапе компиляции. В этом и заключается суть реализации щаблона проектирования Si ngl eton в языке С++. Если объект класса Singleton никогда не используется (в профамме нет вызовов функции Instance), он не создается. Для осуществления такой оптимизации в начале функции Instance выполняется дополнительная проверка (обычно весьма несложная). Преимущество такого подхода становится значительным, если объект класса singleton фебует для своего создания больших затрат и в то же время редко используется. Есть большое искушение упростить класс, заменив указатель plnstance в предыдущем примере полноценным объектом класса singleton. Заголовочный файл Singleton.h class Singleton public: static Singleton* instanceC) Единственная точка доступа { return &instance ; int DoSomethingO; private: static Singleton instance.; Файл реализации singleton.cpp si ngleton singleton::instance ; Это неудачное решение. Несмотря на то что переменная instance является статическим членом класса Singleton (как и указатель plnstance в предыдущем при-
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |