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

на главную - закладки

Жанры

Поделиться:

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

Шрифт:

Проблемы, связанные с глобальными объектами

При разработке больших проектов, часто возникает необходимость обращаться из одного модуля программы к объектам, существующим в другом модуле. Такие объекты, как правило, существуют в единичных экземплярах, поэтому наиболее распространенной практикой является создание глобальных объектов данного типа и ссылка на них из других модулей программы с применением ключевого слова extern. Так, например, при создании ATL проекта в среде MSVC++, мастер проекта создает экземпляр класса – наследника от CComModule, _Module, в главном файле проекта, и помещает объявление extern CMyModule _Module в stdafx.h, что делает доступным объект _Module из других файлов проекта. Однако при таком подходе отсутствует механизм, предотвращающий создание нескольких объектов данного типа. Кроме того, поскольку объект создается статически, отсутствует возможность управлять процессом его создания. То есть, объект создается автоматически, до момента его фактического применения в программе. Это может приводить к некоторым неприятным последствиям: если объект работает с некоторой инфраструктурой, то инициализация и освобождение этой инфраструктуры должны быть помещены, например, в этот же класс.

листинг 1

class BusinesLogic //использует инфраструктуру COM

{

public:

 BusinesLogic {

CoInitializeEx(NULL, COINIT_MULTITHREADED);

//некая работа с COM

 }

 ~BusinesLogic {

CoUninitialize;

 }

};

Глядя на следующий фрагмент, нельзя сказать, была ли инициализирована инфраструктура, а если да, то ничего нельзя сказать о выбранной потоковой модели COM. Как следствие, такой код – источник ошибок и возможных проблем с их диагностикой.

листинг 2

BusinesLogic BL;

void main {

 HRESULT hr;

 IUnknown *p;

 hr=CoCreateInstance(CLSID_AppartmentThreadClass, NULL, CLSCTX_INPROC_SERVER, IID_IUnknown, (void**)&p);

}

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

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

Листинг 3

class Singleton {

 static Singleton* _self;

protected:

 Singleton{}

public:

 static Singleton* Instance {

if (!_self) _self = new Singleton;

return _self;

 }

 //методы

 void aFunc1;

 void aFunc2;

 //данные

 int aData;

};

Singleton* Singleton::_self=NULL;

ПРИМЕЧАНИЕ Конструктор класса объявлен в защищенной секции. Благодаря этому отсутствует возможность создавать объекты класса по оператору new или статически. Вместо этого для конструирования объекта служит метод Instance, который гарантирует, что в программе будет существовать только один экземпляр данного класса.

Таким образом, класс Singleton инкапсулирует в себе методы и свойства данной сущности, может быть доступен из любого места программы благодаря методу Instance, а, кроме того, теперь мы можем управлять временем жизни этого объекта. Вот пример использования класса Singleton:

Модуль MAIN

#include "app.h"

void main {

 Application* application = Application::Instance;

 application->Run;

 delete application;

}

Модуль APP

#include <string>

using std::string;

class Window;

class Application {

 static Application* _self;

 Window *wnd;

protected:

 Application{}

public:

 static Application* Instance;

 int loadIniInt(string& section, string& var);

 void saveIniInt(string& section, string& var, int val);

 void Run;

};

Application* Application::Instance {

 if(!_self) _self = new Application;

 return _self;

}

int Application::loadIniInt(string& section, string& var) {

 printf("loadIni\n");

 return 100;

}

 void Application::saveIniInt(string& section, string& var, int val) {

 printf("saveIni\n");

}

void Application::Run {

 wnd=new Window;

 //цикл обработки сообщений

 delete wnd;

}

Application* Application::_self=NULL;

Модуль WINDOW

#include "app.h"

class Window {

 int width;

 int height;

public:

 Window {

Application *p=Application::Instance;

p->loadIniInt(string("Window"), string("width"));

p->loadIniInt(string("Window"), string("height"));

 }

 ~Window {

Application *p=Application::Instance;

Комментарии:
Популярные книги

Первый среди равных. Книга VIII

Бор Жорж
8. Первый среди Равных
Фантастика:
аниме
фантастика: прочее
эпическая фантастика
попаданцы
5.00
рейтинг книги
Первый среди равных. Книга VIII

Идеальный мир для Лекаря 22

Сапфир Олег
22. Лекарь
Фантастика:
юмористическое фэнтези
аниме
фэнтези
5.00
рейтинг книги
Идеальный мир для Лекаря 22

Черный Маг Императора 19

Герда Александр
19. Черный маг императора
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Черный Маг Императора 19

На гребне обстоятельств

Шелег Дмитрий Витальевич
7. Живой лед
Фантастика:
фэнтези
5.25
рейтинг книги
На гребне обстоятельств

Второгодка. Книга 2. Око за око

Ромов Дмитрий
2. Второгодка
Фантастика:
героическая фантастика
альтернативная история
фэнтези
5.00
рейтинг книги
Второгодка. Книга 2. Око за око

Кровь на эполетах

Дроздов Анатолий Федорович
3. Штуцер и тесак
Фантастика:
альтернативная история
7.60
рейтинг книги
Кровь на эполетах

Двойник короля 13

Скабер Артемий
13. Двойник Короля
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Двойник короля 13

Жена со скидкой, или Случайный брак

Ардова Алиса
Любовные романы:
любовно-фантастические романы
8.15
рейтинг книги
Жена со скидкой, или Случайный брак

Сильные

Олди Генри Лайон
Сильные
Фантастика:
героическая фантастика
боевая фантастика
5.00
рейтинг книги
Сильные

Стеллар. Трибут

Прокофьев Роман Юрьевич
2. Стеллар
Фантастика:
боевая фантастика
рпг
8.75
рейтинг книги
Стеллар. Трибут

Егерь Ладов

Шелег Дмитрий Витальевич
3. Кровь и лёд
Фантастика:
боевая фантастика
аниме
фэнтези
5.00
рейтинг книги
Егерь Ладов

Последний Герой. Том 1

Дамиров Рафаэль
1. Последний герой
Фантастика:
попаданцы
альтернативная история
фантастика: прочее
5.00
рейтинг книги
Последний Герой. Том 1

Двойник Короля 4

Скабер Артемий
4. Двойник Короля
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Двойник Короля 4

Я уже граф. Книга VII

Дрейк Сириус
7. Дорогой барон!
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Я уже граф. Книга VII