Читайте также:
|
|
У паттерна одиночка есть определенные достоинства:
Q контролируемый доступ к единственному экземпляру. Поскольку класс Singleton инкапсулирует свой единственный экземпляр, он полностью контролирует то, как и когда клиенты получают доступ к нему;
а уменьшение числа имен. Паттерн одиночка - шаг вперед по сравнению с глобальными переменными. Он позволяет избежать засорения пространства имен глобальными переменными, в которых хранятся уникальные экземпляры;
а допускает уточнение операций и представления. От класса Singleton можно порождать подклассы, а приложение легко сконфигурировать экземпляром расширенного класса. Можно конкретизировать приложение экземпляром того класса, который необходим во время выполнения;
а допускает переменное число экземпляров. Паттерн позволяет вам легко изменить свое решение и разрешить появление более одного экземпляра класса Singleton. Вы можете применять один и тот же подход для управления числом экземпляров, используемых в приложении. Изменить нужно будет лишь операцию, дающую доступ к экземпляру класса Singleton;
а большая гибкость, чем у операций класса. Еще один способ реализовать функциональность одиночки - использовать операции класса, то есть статические функции-члены в C++ и методы класса в Smalltalk. Но оба этих приема препятствуют изменению дизайна, если потребуется разрешить наличие нескольких экземпляров класса. Кроме того, статические функции-члены в C++ не могут быть виртуальными, так что их нельзя полиморфно заместить в подклассах.
Реализация
При использовании паттерна одиночка надо рассмотреть следующие вопросы:
а гарантирование единственного экземпляра. Паттерн одиночка устроен так, что тот единственный экземпляр, который имеется у класса, - самый обычный, но больше одного экземпляра создать не удастся. Чаще всего для этого прячут операцию, создающую экземпляры, за операцией класса (то есть за статической функцией-членом или методом класса), которая гарантирует создание не более одного экземпляра. Данная операция имеет доступ к переменной, где хранится уникальный экземпляр, и гарантирует инициализацию переменной этим экземпляром перед возвратом ее клиенту. При таком подходе можно не сомневаться, что одиночка будет создан и инициализирован перед первым использованием.
В C++ операция класса определяется с помощью статической функции-члена Instance класса Singleton. В этом классе есть также статическая
Паттерн Singleton
переменная-член „instance, которая содержит указатель на уникальный
экземпляр.
Класс Singleton объявлен следующим образом:
class Singleton { public:
static Singleton* Instance(); protected:
Singleton(); private:
static Singleton* „instance;
A реализация такова:
Singleton* Singleton::_instance = 0;
Singleton* Singleton::Instance () { if (_instance == 0) {
_instance = new Singleton;
return „instance;
Клиенты осуществляют доступ к одиночке исключительно через функцию-член Instance. Переменная „instance инициализируется нулем, а статическая функция-член Instance возвращает ее значение, инициализируя ее уникальным экземпляром, если в текущий момент оно равно 0. Функция Instance использует отложенную инициализацию: возвращаемое ей значение не создается и не хранится вплоть до момента первого обращения. Обратите внимание, что конструктор защищенный. Клиент, который попытается инстанцировать класс Singleton непосредственно, получит ошибку на этапе компиляции. Это дает гарантию, что будет создан только один экземпляр.
Далее, поскольку „instance - указатель на объект класса Singleton, то функция-член Instance может присвоить этой переменной указатель на любой подкласс данного класса. Применение возможности мы увидим в разделе «Пример кода».
О реализации в C++ скажем особо. Недостаточно определить рассматриваемый патерн как глобальный или статический объект, а затем полагаться на автоматическую инициализацию. Тому есть три причины:
- мы не можем гарантировать, что будет объявлен только один экземпляр
статического объекта;
- у нас может не быть достаточно информации для инстанцирования лю
бого одиночки во время статической инициализации. Одиночке могут
быть необходимы данные, вычисляемые позже, во время выполнения
программы;
- в C++ не определяется порядок вызова конструкторов для глобальных
объектов через границы единиц трансляции [ES90]. Это означает, что
Дата добавления: 2015-09-11; просмотров: 73 | Поможем написать вашу работу | Нарушение авторских прав |