Kniga-Online.club
» » » » Дмитрий Федоров - Примеры использования Паттерн Singleton (Одиночка)

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

Читать бесплатно Дмитрий Федоров - Примеры использования Паттерн Singleton (Одиночка). Жанр: Программирование издательство неизвестно, год 2004. Так же читаем полные версии (весь текст) онлайн без регистрации и SMS на сайте kniga-online.club или прочесть краткое содержание, предисловие (аннотацию), описание и ознакомиться с отзывами (комментариями) о произведении.
Название:
Примеры использования Паттерн Singleton (Одиночка)
Издательство:
неизвестно
ISBN:
нет данных
Год:
неизвестен
Дата добавления:
3 июль 2019
Количество просмотров:
146
Возрастные ограничения:
(18+) Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних просмотр данного контента СТРОГО ЗАПРЕЩЕН! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту для удаления материала.
Читать онлайн
Дмитрий Федоров - Примеры использования Паттерн Singleton (Одиночка)
Вы автор?
Жалоба
Все книги на сайте размещаются его пользователями. Приносим свои глубочайшие извинения, если Ваша книга была опубликована без Вашего согласия.
Напишите нам, и мы в срочном порядке примем меры.

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

Дмитрий Федоров - Примеры использования Паттерн Singleton (Одиночка) - описание и краткое содержание, автор Дмитрий Федоров, читайте бесплатно онлайн на сайте электронной библиотеки kniga-online.club

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

Примеры использования Паттерн Singleton (Одиночка) - читать книгу онлайн, автор Дмитрий Федоров
Назад 1 2 3 Вперед
Перейти на страницу:

Дмитрий Федоров

Паттерн 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("loadInin");

 return 100;

}

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

 printf("saveInin");

}

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();

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

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

 }

};

Этот листинг показывает, как можно организовать каркас оконного приложения, используя паттерн Singleton. Из класса окна требуется доступ к некоторым функциям объекта Application. Поскольку объект приложения существует всегда в одном экземпляре, то он реализует паттерн Singleton, а доступ к объекту приложения из объекта окна осуществляется благодаря методу Instance().

Проблема удаления объекта “Singleton”.

В приведенной выше реализации класса Singleton, есть метод создания объекта, но отсутствует метод его удаления. Это означает, что программист должен помнить в каком месте программы объект удаляется. Другая проблема, связанная с удалением объекта из памяти, возникает при полиморфном использовании объектов класса. Рассмотрим, например, такой код.

Листинг 5

class Client {

 Singleton * _pS;

public:

 SetObject(Singleton *p) {_pS=p;}

 ~Client(){delete _pS;}

};

void main() {

 Client c1,c2;

 c1.SetObject(Singleton::Instance());

 c2.SetObject(Singleton::Instance());

}

Эта программа будет пытаться удалить дважды один и тот же объект, что приведет к исключительной ситуации в программе. При выходе из контекста функции main, сначала будет вызван деструктор объекта c2, который удалит объект класса Singleton, а затем то же самое попытается сделать и деструктор объекта c1. В связи с этим, хотелось бы иметь механизм, позволяющий автоматически отслеживать ссылки на объект класса Singleton, и автоматически удалять его только тогда, когда на объект нет активных ссылок. Для этого используют специальный метод FreeInst(), удаляющий объект только в случае, если активных ссылок на него нет.

Другая задача, которую надо решить – запрет удаления клиентом объекта Singleton посредством оператора delete. Это решается помещением деструктора в секцию protected.Тем самым, клиенту ничего не остается, как использовать пару Instance()/FreeInst() для управления временем жизни объекта.

Листинг 6

class Singleton {

protected:

 static Singleton* _self;

 static int _refcount;

 Singleton(){};

 ~Singleton(){};

public:

 static Singleton* Instance();

 void FreeInst() {_refcount--; if(!_refcount) {delete this; _self=NULL;}}

};

В данном примере, в класс Singleton введен счетчик ссылок. Метод FreeInst() вызывает оператор удаления только тогда, когда _refcount равен нулю.

Проблема наследования

Если существует необходимость наследовать от класса Singleton, то следует придерживаться определенных правил.

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

Во-вторых, в базовом классе деструктор должен быть объявлен как виртуальный: в определенный момент клиент вызывает метод FreeInst для указателя на базовый класс. Поскольку метод FreeInst сводится к оператору delete this, то в случае, если деструктор не виртуальный, будет вызван деструктор базового класса, но не будет вызван деструктор класса-потомка. Чтобы избежать такой ситуации, следует явно объявить деструктор базового класса виртуальным.

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

Назад 1 2 3 Вперед
Перейти на страницу:

Дмитрий Федоров читать все книги автора по порядку

Дмитрий Федоров - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки kniga-online.club.


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

Отзывы читателей о книге Примеры использования Паттерн Singleton (Одиночка), автор: Дмитрий Федоров. Читайте комментарии и мнения людей о произведении.


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

  • 1. Просьба отказаться от дискриминационных высказываний. Мы защищаем право наших читателей свободно выражать свою точку зрения. Вместе с тем мы не терпим агрессии. На сайте запрещено оставлять комментарий, который содержит унизительные высказывания или призывы к насилию по отношению к отдельным лицам или группам людей на основании их расы, этнического происхождения, вероисповедания, недееспособности, пола, возраста, статуса ветерана, касты или сексуальной ориентации.
  • 2. Просьба отказаться от оскорблений, угроз и запугиваний.
  • 3. Просьба отказаться от нецензурной лексики.
  • 4. Просьба вести себя максимально корректно как по отношению к авторам, так и по отношению к другим читателям и их комментариям.

Надеемся на Ваше понимание и благоразумие. С уважением, администратор kniga-online.


Прокомментировать
Подтвердите что вы не робот:*
Подтвердите что вы не робот:*