Примеры использования Паттерн Singleton (Одиночка) - [3]

Шрифт
Интервал

>

>void Do1(){printf("Singleton::Do1\n");}

>};


>Singleton* Singleton::_self=NULL;

>int Singleton:: _refcount=0;


>class Client {

> base *objs[2];

> int ind;

>public:

> Client(){>  objs[0]=NULL;objs[1]=NULL;ind=0; }

> ~Client() {

>  for(int i=0;iFreeInst();

> }

> void Add(base *p){if(ind<2) objs[ind++]=p;}

> void Do() {

>  for(int i=0;iDo1();

> }

>};


>void main() {

> Client cl;

> cl.Add(Singleton::Instance());

> cl.Add(new Simple());

>cl.Do();

>}


результат работы программы:


Singleton::Do1 Simple::Do1 Singleton::~Singleton Simple::~Simple


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

Применение шаблонов языка C++.

Альтернативой приведенной выше реализации может служить реализация класса Singleton при помощи шаблонов языка С++. Преимущество такого подхода заключается в автоматической параметризации метода Instance(), что приводит к отсутствию необходимости переопределять его в классах потомках. По изложенным ранее причинам конструктор класса-потомка также должен быть объявлен защищенным, а деструктор виртуальным. Кроме того, базовый класс Singleton должен быть объявлен другом класса наследника, поскольку метод Instance() базового класса в этой модели создает объект производного класса.

листинг 9

>template

>class Singleton {

> static T* _self;

> static int _refcount;

>protected:

> Singleton(){}

> virtual ~Singleton(){_self=NULL;}

>public:

> static T* Instance();

> void FreeInst();

>};


>template

>T* Singleton::_self = NULL;


>template

>int Singleton::_refcount=0;


>template

>T* Singleton::Instance() {

> if(!_self) _self=new T;

> _refcount++;

> return _self;

>}


>template

>void Singleton::FreeInst() {

> if(--_refcount==0) delete this;

>}


>class Derived: public Singleton {

>protected:

> Derived(){}

> friend class Singleton;

>};


>int main(int argc, char* argv[]) {

> Derived *p = Derived::Instance();

> …

> …

> …

> p->FreeInst();

> return 0;

>}


Классы, объекты которых должны существовать в единственном экземпляре, просто наследуются от шаблонного класса Singleton. Такой подход, однако, не позволяет создать иерархию классов во главе с классом-интерфейсом, в которой некоторые из классов-наследников реализуют паттерн проектирования Singleton, а некоторые нет (См листинг 8). С другой стороны, применение параметризованного класса позволяет вынести код Singleton’а в отдельный файл и включать его в последствии в создаваемые приложения, обеспечивая тем самым повторное использование паттерна Singleton.

Резюме

1. В классе Singleton конструктор должен быть объявлен в защищенной секции для предотвращения создания объекта способом, отличным от вызова метода Instance().

2. Деструктор также следует поместить в защищенную секцию класса, чтобы исключить возможность удаления объекта оператором delete.

3. Для автоматического подсчета ссылок при освобождении объекта следует применять специальный метод, такой как FreeInst().

4. При наследовании от класса, реализующего паттерн Singleton, конструктор класса-потомка также должен быть объявлен в защищенной секции. Деструктор должен быть объявлен как виртуальный. Класс-потомок должен переопределить метод Instance(), так, чтобы он создавал объект нужного типа.

5. Если предполагается полиморфная работа с классами, наследуемыми от одного базового класса, причем некоторые классы потомки реализуют паттерн Singleton, а некоторые нет, следует в базовом классе определить метод FreeInst() как виртуальный. Базовый класс предоставляет реализацию по умолчанию этого метода, просто вызывая оператор delete this. В классах-потомках, реализующих паттерн Singleton, при реализации метода FreeInst(), используйте механизм подсчета ссылок.

6. Если используется параметризированная версия Singleton, то в производных классах следует объявить базовый класс (Singleton) дружественным.

Литература

1. http://www.firststeps.ru/theory/c/r.php?29

2. http://ooad.asf.ru/patterns/patterninfo.asp?ID=13

3. Э. Гамма, Р. Хелм, Р. Джонсон, Дж. Влиссидес “Приемы объектно-ориентированного проектирования. Паттерны проектирования”

Комментарии: 

Как бы так это заделать???

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


>template

>T*  Singleton::Instance()

>{

>  if(!_self)

>  {

>    _self=new T;

>    _refcount++; // вот это

>  }

>  _refcount++;

>  return _self;

>}


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


Еще от автора Дмитрий Федоров
Виктор Тихонов. Жизнь во имя хоккея

Виктор Васильевич Тихонов – легенда советского и российского хоккея. В качестве главного тренера сборной он трижды добился с командой золотых медалей на Олимпиадах, восемь раз его команда завоевала титул чемпиона мира, а команда ЦСКА двенадцать раз становилась чемпионом СССР. Каким он был, «Мистер Дисциплина»? Как ему удалось добиться с командой таких успехов? Ответы на эти вопросы – в его дневниках и воспоминаниях супруги, Татьяны Васильевны, а также – в фотографиях из их личного архива.


Загольная жизнь

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


Удар из галактики

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


Города Алисы

«Города Алисы» — сериал коротких приключенческих рассказов, действие которых происходит в красивых городах. Лондон, Хельсинки, Нью-Йорк, Мюнхен, Кёльн, Рим. Главная героиня — энергичная девушка Алиса. Умная, с чувством юмора, немного желчная, красивая, при этом не стерва, стильная, но не гламурная. Стоит ей только покинуть Россию, как вокруг неё сразу начинают происходить нереальные события, и люди с чудинкой оказываются на её пути. У Алисы есть коммуникабельный и доброжелательный пёс — грифон по кличке Соломон.


Отдыхай с Гусом Хиддинком: четыре анекдотичные футболяшки

«Отдыхай с Гусом Хиддинком» – четыре нереально смешные фантастические истории, герои которых существуют в каком-то странном пространстве – то ли виртуальном, то ли со смещенным временем, то ли вообще в мире галлюцинаций. В День национального единства русские гении – Пушкин, Достоевский и другие – играют против Рональдинью, Джеррарда, Анри и прочих звезд мира.Со школы знакомые картины, вроде «Грачи прилетели», становятся фанатскими баннерами, а Гоголь переделывает бессмертного «Резизора» под актуальные футбольные нужды.Руководство «Спартака» придумывает радикальный пиар-ход, чтобы стать ближе к народу.


Голевой телекинез. Фельетон-фэнтези

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


Рекомендуем почитать
Изучаем Java EE 7

Java Enterprise Edition (Java EE) остается одной из ведущих технологий и платформ на основе Java. Данная книга представляет собой логичное пошаговое руководство, в котором подробно описаны многие спецификации и эталонные реализации Java EE 7. Работа с ними продемонстрирована на практических примерах. В этом фундаментальном издании также используется новейшая версия инструмента GlassFish, предназначенного для развертывания и администрирования примеров кода. Книга написана ведущим специалистом по обработке запросов на спецификацию Java EE, членом наблюдательного совета организации Java Community Process (JCP)


Pro Git

Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.


Как функции, не являющиеся методами, улучшают инкапсуляцию

Когда приходится инкапсулировать, то иногда лучше меньше, чем большеЯ начну со следующего утверждения: Если вы пишете функцию, которая может быть выполнена или как метод класса, или быть внешней по отношению к классу, Вы должны предпочесть ее реализацию без использования метода. Такое решение увеличивает инкапсуляцию класса. Когда Вы думаете об использовании инкапсуляции, Вы должны думать том, чтобы не использовать методы.Удивлены? Читайте дальше.


Обработка событий в С++

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


Программное обеспечение встроенных систем. Общие требования к разработке и документированию

Embedded system software. General requirements for development and documentationСтандарт подготовлен в развитие ГОСТ Р ИСО/МЭК 12207-99 «Информационная технология. Процессы жизненного цикла программных средств» с целью учета специфики разработки и документирования программного обеспечения встроенных систем реального времени.


Как пасти котов. Наставление для программистов, руководящих другими программистами

«Как пасти котов» – это книга о лидерстве и руководстве, о том, как первое совмещать со вторым. Это, если хотите, словарь трудных случаев управления IT-проектами. Программист подобен кошке, которая гуляет сама по себе. Так уж исторически сложилось. Именно поэтому так непросто быть руководителем команды разработчиков. Даже если вы еще месяц назад были блестящим и дисциплинированным программистом и вдруг оказались в роли менеджера, вряд ли вы знаете, с чего надо начать, какой выбрать стиль руководства, как нанимать и увольнять сотрудников, проводить совещания, добиваться своевременного выполнения задач.