type
// Базовый класс для объектов, реализующих паттерн
// "Singleton". Для получения доступа к экземпляру
// необходимо вызвать GetInstance. Если экземпляр
// еще не существует, то он будет создан. Иначе -
// возвращена ссылка на ранее созданный экземпляр.
// Уничтожить экземпляр можно вручную, вызвав Free,
// иначе он будет уничтожен автоматически перед
// завершением приложения
TSingleton = class(TObject)
private
class procedure RegisterInstance(Instance:
TSingletone);
procedure UnRegisterInstance;
class function FindInstance: TSingletone;
protected
// Инициализацию производить только в этом
// конструкторе, а не в GetInstance.
// Не рекомендуется выносить этот конструктор
// из секции protected
constructor Create; virtual;
public
class function NewInstance: TObject; override;
procedure BeforeDestruction; override;
// Точка доступа к экземпляру
constructor GetInstance;
end;
...
implementation
uses Contnrs;
var
SingletonList: TObjectList;
{ TSingleton }
procedure TSingleton.BeforeDestruction;
begin
UnregisterInstance;
inherited BeforeDestruction;
end;
constructor TSingleton.Create;
begin
inherited Create;
end;
class function TSingleton.FindInstance:
TSingletone;
var
i: Integer;
begin
Result := nil;
for i := 0 to SingletonList.Count - 1 do
if SingletonList[i].ClassType = Self
then begin
Result := TSingleton(SingletonList[i]);
Break;
end;
end;
constructor TSingleton.GetInstance;
begin
inherited Create;
end;
class function TSingleton.NewInstance: TObject;
begin
Result := FindInstance;
if Result = nil then begin
Result := inherited NewInstance;
TSingleton(Result).Create;
RegisterInstance(TSingleton(Result));
end;
end;
class procedure TSingleton.RegisterInstance(Instance:
TSingleton);
begin
SingletonList.Add(Instance);
end;
procedure TSingletone.UnRegisterInstance;
begin
SingletonList.Extract(Self);
end;
initialization
SingletonList := TObjectList.Create(True);
finalization
SingletonList.Free;
Wednesday, December 10, 2008
Реализация паттерна "Singleton" в Delphi
Давно интересовала тема реализации шаблона дизайна "Singleton" в Delphi, которая бы мне просто позволила бы мне получить соответствующее поведение путем простого наследования от некоторого базового класса. В результате нескольких различных вариантов реализаций остановился на таком:
Subscribe to:
Post Comments (Atom)
36 comments:
Я вас сильно удивлю, если скажу что Singleton переводится как Одиночка? :) Вашу конструкцию лучше назвать по другому, дабы не вводить в заблуждение неокрепшие умы...
Petrik P'yatochkin, а почему по-Вашему эта конструкция не может быть названа именно Singleton?
Согласен с Petrik P'yatochkin
Для начала, вот:
http://ru.wikipedia.org/wiki/Одиночка_(шаблон_проектирования)
P.S. Автор, не мешало бы почистить спам.
Код в Вики (на Delphi), насколько я понимаю, не соответствует утверждению из статьи:
"единственный экземпляр должен расширяться путем порождения подклассов, и клиентам нужно иметь возможность работать с расширенным экземпляром без модификации своего кода"
Подклассы он порождать не дает, так как явно создает экземпляр класса TSingleton :)
Хорошая статья. Действительно было интересно почитать. Не часто такое и встречается та.Наверное стоит подписаться на ваше RSS
Отличная реализация, браво!
Из того, что я видел - это лучшее решение, которое применимо для повторного использования.
Можно до посинения вчитываться в классическое описание данного паттерна, так и не попытавшись реализовать его в коде, а можно попытаться реализовать его, и наткнуться на грабли, которые элегантно обойдены в этом решении.
Все, что требуется для паттерна Singleton, здесь есть и даже более того:
1) инстанцию класса можно создать только одну;
2) реализация получения инстанции скрывается в одном модуле, т.е. в производных классах не требуется определять дополнительные статические переменные и писать блоки инициализации-финализации
3) код очень хорошо обособлен, им можно пользоваться как черным ящиком.
Посему, если догматическое мышление участников обсуждения не позволяет признать это решение корректным в рамках определения паттерна и помимо всего прочего еще и красивым, то мне их очень жаль
А автору - спасибо!
Спасибо за отзывы, давно не заходил в свой блог, постараюсь это делать чаще, тем более что есть чем поделиться. Насчет реализации шаблона из вики - очевидно я с ней знаком, но она мне не нравится, по причинам, которые, в общем-то уже были названы. Хотелось бы иметь более универсальное решение, хотя кому что ближе, не настаиваю.
Хотелось бы дополнить, что в некоторых случаях реализовать синглетон можно просто - используя чисто классовые методы (class procedure/function), в этом случае сам класс выступает в качестве единственного и неповторимого экземпляра, а его "единственность" обеспечивается компилятором. То, что классовые методы могут быть виртуальными, делают этот метод достаточно мощным.
Спам вычистил...
диета доктора борменталя скачать
диеты скачать
[url=http://dieta.sehost.ru]скачать бесплатную диету
[/url]
в тему http://dematom.com/images/2009/08/28/28676-chtoby_plennyh_doprashivati.jpg
_________________
Надо бросить курить, чтобы хвастаться своей силой воли. а
Тут кто-нибудь разбирается в радио? Нужен коллега, который рассказал бы вкратце о транзисторе Т2 (не понятно как проверить гв = гв1). Надеюсь, радиолюбители тут “водятся”. Если не по теме совершенно, то извините. Вынужден написать, выхода просто не вижу. ЗЫ: если орфография не правильная то тоже извините, мне 13 лет только. Сайт Ваш правда мало продвинутый и плохопосещаем.Попробуйте оптимизировать его с помощью программного комплекса XRumer 7 Elite (ХРумер 7 Элите) закачать можно тут http://x-rumer.ru/ слышал эффективная программа для раскрутки блог порталов.
Интернет магазин ShopForYou.org это оригинальные товары для мужчин и женщин по доступным ценам!
У нас можно встретить большой выбор парфюмерии.
Stop hack the program!!!
Привет всем, есть вопрос, попался сайт с караоке [url=http://vkone.ru/films/3725-karaoke-4000-pesen-na-blu-rey-22-gb.html]vkone.ru[/url] vkone.ru, не могу разобраться как тут быстро скачать, кто нибудь может пояснить? Заранее спасибо.
Ремонтик Под ключ Капитальный жилых помещений в Запорожье http://ukladka-kafelj.ucoz.ua http://vsjstroika.ucoz.ru http://remontkvartiri.at.ua http://vash-remont.ucoz.ua http://ukladkalaminata.at.ua
Ремонтик Комплексный Капитальный жилых помещений в Запорожье http://ukladka-kafelj.ucoz.ua http://vsjstroika.ucoz.ru http://remontkvartiri.at.ua http://vash-remont.ucoz.ua http://ukladkalaminata.at.ua
Афтар +1
Афтар +1
Афтар +1
Афтар +1
Афтар +1
Афтар +1
Афтар +1
Афтар +1
ПРОДАМ участок ЧЕЛЯБИНСКАЯ ОБЛАСТЬ МАЛЫЙ КРЕМЕНКУЛЬ, 7СОТОК СОБственость 89080791300 Email: etd09@mail.ru
Куплю конденсаторы км-5 H30 (зеленые)
от 1 кг! Предложения на мыло
serg12011974@mail.ru
Купил внове встраиваемую мойку Blanco могу говорить полностью доволен приобретением, советую всем поручение делал чрез сайт интернет магазина, обработали быстрее чем я думал, консультанты для сайте вежливые и отзывчивые,нравиться было.)) Вот доказательство для собственноручно сайт,кому надо http://the.dp.ua
Купил внове встраиваемую мойку Blanco могу говорить полностью доволен приобретением, советую всем поручение делал чрез сайт интернет магазина, обработали быстрее чем я думал, консультанты для сайте вежливые и отзывчивые,нравиться было.)) Вот доказательство для собственноручно сайт,кому надо http://the.dp.ua
Купил внове встраиваемую мойку Blanco могу говорить полностью доволен приобретением, советую всем поручение делал чрез сайт интернет магазина, обработали быстрее чем я думал, консультанты для сайте вежливые и отзывчивые,нравиться было.)) Вот доказательство для собственноручно сайт,кому надо http://the.dp.ua
При таком подходе AfterConstruction вызывается дважды.
И вообще, вызывать конструктор дважды - не есть гут - обязательно вылезет в наследниках.
Уберите из "Singleton.GetInstance;" вызов "inherited Create;" и все станет на свои места)) (т.к. он вызывается в NewInstance).
Господа, есть тут кто живой?
Собственно: создаю наследника от базового класса TSingleton. Каждый раз при выполнении конструктора Create заново создаются все классы, содержащиеся в этом наследнике. Вставлял проверку - все классы равны nil. Разве смысл одиночки не в том, что экземпляр создается один раз за весь жизненный цикл программы и этим экземпляром можно пользоваться в любой точке приложения? Здесь так не получается, или я чего-то не понимаю?
Вопрос снят. Как всегда, виноваты руки и невнимательность. При повторном изучении кода нашел ошибку.
Стоп. Рано радоваться) Новая беда: При выходе из приложения сначала выполняется секция finalization, а потом вызывается процедура BeforeDestruction. Получается, что список одиночек у нас уже уничтожен, а мы пытаемся удалить из него объект. Как следствие - трудноуловимый(для меня, по крайней мере) АВ. Не могли бы уважаемые гуру осветить данную проблему и посоветовать решение вопроса? Пока я нашел такое решение: перед обращением к списку делаю проверку:
if Assigned(SingletonList) then
SingletonList.Extract(Self);
Может опять мои кривые грабки где-то напортачили? Подскажите, пожалуйста!
Wow, fantastic blog layout! How long have you been blogging for? you made blogging look easy. The overall look of your website is excellent, let alone the content!
Hello! I simply would like to give you a huge thumbs up for your excellent information you've got here on this post. I'll be coming back to your website for more soon.
У данного кода могут наблюдаться проблемы при многопоточном использовании
Post a Comment