Использование шаблона Singleton (или Одиночка) зачастую очень полезна. По условиям этого шаблона подразумевается (гарантируется), что в контексте существует только один экземпляр класса и предоставляется только одна точка для получения доступа к этому экземпляру - отсюда и его название. В качестве примечания можно отметить, что на самом деле это не обязательно должен быть именно один экземпляр. Если говорить более общо, реализация данного шаблона должна гарантировать существование ограниченного (не памятью, а логикой) количества экземпляров класса.
В связи с наличием определенных ограничений языка LotusScript, являющимся основой для разработки классических приложений под клиент IBM Notes, реализация шаблона Singleton становится не самой тривиальной задачей. Речь идет о следующих ограничениях:
1. Класс не может иметь приватный (private) конструктор.
2. Класс не может иметь статических (static) методов
Вариантов реализации при таких ограничениях весьма скудное количество. Один из них основан на следующих постулатах:
1. Класс, являющийся одиночкой объявляется private (т.е. виден только в рамках библиотеки, в которой объявлен)
2. Получение экземпляра класса от точки доступа к нему происходит в потерей информации о типе. Проще говора будет возвращен Variant.
Примеры таких реализаций приведены здесь:
http://www.lotushints.com/2008/11/design-patterns-part-3-singleton-pattern/
и здесь:
http://www.nsftools.com/tips/LotusScriptSingleton.htm
Разница между ними только в способе организации точки доступа: через фабричную функцию или через класс-фабрику.
Подобная реализация вполне приемлема для версий IBM Domino Designer версий 7 и ниже, до появления интерфейса дизайнера основанной на Eclipse. Информация о пользовательских класса (их методах) и так не была доступна и работа с ними были сравнима с работой с типом Variant - вслепую.
Предлагаемая мной реализация (не претендую на исключительную новизну. но пока не встречал) основана на следующим:
1. Точка доступа - статическая фабричная функция, содержащая статическую переменную для хранению экземпляра-одиночки. Модификатор Static для функции говорит о том, что все переменные, определенных в этой функции, по-умолчанию будут статическими, т.е. не будут менять свое значение между вызовами функции - то что надо для "Одиночки".
2. Для защиты от несанкционированного инстанцирования через конструктор будем использовать приватную переменную библиотеки.
В общем случае код будет выглядеть следующим образом:
Private someSingleton As Boolean 'приватная переменная, препятствующая прямому вызову New
Сам класс:
Class SomeSingletonClass
Public Sub New()
If Not someSingleton Then
Error 5000, {Прямое инстанцирование запрещено. Используйте функцию GetSomeSingleton()} 'Код ошибки для примера
End If
End Sub
'Прочие методы
End Class
Функция для получения доступа к экземпляру:
Static Function GetSomeSingleton() As SomeSingletonClass
Static this As SomeSingletonClass
If this Is Nothing Then
someSingleton = True 'Поднимаем приватный флаг, позволяющий вызвать конструктор без ошибки
Set this = New SomeSingletonClass
someSingleton = False
End If
Set GetSomeSingleton = this
End Function
Некоторые комментарии и примечания:
1. В качестве названия функции можно использовать название класса. Чисто синтаксически вызов любого метода этого класса будет выглядеть как обращение к классу напрямую
2. Вместо функции можно использовать свойство (Static Property Get ...), но у меня иногда происходят ошибки области видимости, вероятно из-за кривости рук, поэтому мне удобнее использовать функцию
3. Авто проверка орфографии предложила заменить слово "кривости" в пред. пункте на "красивости", но решил этого не делать...
4. Исходя из определения модификатора Static, написание Static Function и Static this одновременно - избыточно. Достаточно одного из них, но мне так больше нравится.
Вот как-то так :) Приятного использования и до новых встреч! В следующем посте предполагаю продолжение серии о базовых компонентах Extension Library. Он уже в работе и, надеюсь, выйдет скоро.
Комментарии
Отправить комментарий