Wednesday, December 10, 2008

Реализация паттерна "Singleton" в Delphi

Давно интересовала тема реализации шаблона дизайна "Singleton" в Delphi, которая бы мне просто позволила бы мне получить соответствующее поведение путем простого наследования от некоторого базового класса. В результате нескольких различных вариантов реализаций остановился на таком:
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;

41 comments:

Anonymous said...
This comment has been removed by a blog administrator.
Petrik P'yatochkin said...

Я вас сильно удивлю, если скажу что Singleton переводится как Одиночка? :) Вашу конструкцию лучше назвать по другому, дабы не вводить в заблуждение неокрепшие умы...

Ins said...

Petrik P'yatochkin, а почему по-Вашему эта конструкция не может быть названа именно Singleton?

Maksim said...

Согласен с Petrik P'yatochkin
Для начала, вот:
http://ru.wikipedia.org/wiki/Одиночка_(шаблон_проектирования)

P.S. Автор, не мешало бы почистить спам.

ISchevchenko said...

Код в Вики (на Delphi), насколько я понимаю, не соответствует утверждению из статьи:

"единственный экземпляр должен расширяться путем порождения подклассов, и клиентам нужно иметь возможность работать с расширенным экземпляром без модификации своего кода"

Подклассы он порождать не дает, так как явно создает экземпляр класса TSingleton :)

Anonymous said...

Хорошая статья. Действительно было интересно почитать. Не часто такое и встречается та.Наверное стоит подписаться на ваше RSS

Vladix said...

Отличная реализация, браво!

Из того, что я видел - это лучшее решение, которое применимо для повторного использования.

Можно до посинения вчитываться в классическое описание данного паттерна, так и не попытавшись реализовать его в коде, а можно попытаться реализовать его, и наткнуться на грабли, которые элегантно обойдены в этом решении.

Все, что требуется для паттерна Singleton, здесь есть и даже более того:
1) инстанцию класса можно создать только одну;
2) реализация получения инстанции скрывается в одном модуле, т.е. в производных классах не требуется определять дополнительные статические переменные и писать блоки инициализации-финализации
3) код очень хорошо обособлен, им можно пользоваться как черным ящиком.

Посему, если догматическое мышление участников обсуждения не позволяет признать это решение корректным в рамках определения паттерна и помимо всего прочего еще и красивым, то мне их очень жаль

А автору - спасибо!

Ins said...

Спасибо за отзывы, давно не заходил в свой блог, постараюсь это делать чаще, тем более что есть чем поделиться. Насчет реализации шаблона из вики - очевидно я с ней знаком, но она мне не нравится, по причинам, которые, в общем-то уже были названы. Хотелось бы иметь более универсальное решение, хотя кому что ближе, не настаиваю.

Хотелось бы дополнить, что в некоторых случаях реализовать синглетон можно просто - используя чисто классовые методы (class procedure/function), в этом случае сам класс выступает в качестве единственного и неповторимого экземпляра, а его "единственность" обеспечивается компилятором. То, что классовые методы могут быть виртуальными, делают этот метод достаточно мощным.

Спам вычистил...

Anonymous said...

диета доктора борменталя скачать
диеты скачать


[url=http://dieta.sehost.ru]скачать бесплатную диету
[/url]

Anonymous said...

в тему http://dematom.com/images/2009/08/28/28676-chtoby_plennyh_doprashivati.jpg


_________________
Надо бросить курить, чтобы хвастаться своей силой воли. а

Anonymous said...

Тут кто-нибудь разбирается в радио? Нужен коллега, который рассказал бы вкратце о транзисторе Т2 (не понятно как проверить гв = гв1). Надеюсь, радиолюбители тут “водятся”. Если не по теме совершенно, то извините. Вынужден написать, выхода просто не вижу. ЗЫ: если орфография не правильная то тоже извините, мне 13 лет только. Сайт Ваш правда мало продвинутый и плохопосещаем.Попробуйте оптимизировать его с помощью программного комплекса XRumer 7 Elite (ХРумер 7 Элите) закачать можно тут http://x-rumer.ru/ слышал эффективная программа для раскрутки блог порталов.

Anonymous said...

wow server http://warlife.ru и нижегородское кольцо http://nn-fun.ru вместе http://0we.ru и онлайн http://orange31.ru а так же с сервером http://wow-nsk.ru и городским порталом http://ipsinnovation.com представляют http://05o.ru обо хостинг http://0vv0.ru и нижегородской области http://berkat.su q http://maksima.su wowqrsk http://aquarellse.su и wowpso http://pso-wow.com славики http://slavich.su twilight http://wow-twilight.ru lord wc3 http://a-sa.su кавказцы http://wolike.ru wow wolike http://shift-wow.ru shift deathwing-rage.ru server gigant-online.ru Centralniy city http://teldrassil.ru gm сервер http://bg-ski.ru лыжи в богородске http://qwest.su
[url=http://nn-fun.ru]1[/url] [url=http://warlife.ru]2[/url] [url=http://ipsinnovation.com] 3[/url] [url=http://orange31.ru]4[/url] [url=http://0we.ru]5[/url] [url=http://05o.ru]6[/url] [url=http://wow-nsk.ru]8[/url] [url=http://1eurobank.com]9[/url]

Anonymous said...

kvartir Привет! Заходите на http://vsjstroika.ucoz.ru [url=http://vsjstroika.ucoz.ru]remont kvartir v Zaporozhye[/url].

Anonymous said...

Интернет магазин ShopForYou.org это оригинальные товары для мужчин и женщин по доступным ценам!
У нас можно встретить большой выбор парфюмерии.

Anonymous said...

Stop hack the program!!!

Anonymous said...

У нас самые лучшие девочки по вызову, индивидуалки, есть с подружкой [url=http://123prost.ru]Проститутки Москвы и других городов[/url],[url=http://m123yandex.ru] девочки повызову, вызвать девочку к себе, проститутки по станциям метро[/url] ,[url=http://stopru.ru]девочки по вызову[/url],[url=http://stopru.ru] Шлюхи здесь, шалуньи[/url], [url=http://3d-net.ru]Заказ девочек-проституток, Форум проститутки москвы[/url],[url=http://deskru.ru] Как купить или продать фото, работа в микростоках[/url]

Anonymous said...

Привет всем, есть вопрос, попался сайт с караоке [url=http://vkone.ru/films/3725-karaoke-4000-pesen-na-blu-rey-22-gb.html]vkone.ru[/url] vkone.ru, не могу разобраться как тут быстро скачать, кто нибудь может пояснить? Заранее спасибо.

Anonymous said...

КаждомуСварочные работы в Самаре. Делаем сварочные и монтажные работы по индивидуальным строительным проектам. Сварочные работы в Самаре! Наш сайт [url=http://svarka63.ru/svarochnye-raboty-v-samare/[/url].

Anonymous said...

[url=http://dokagame.tk/]dokagame.tk[/url] dokagame.tk, Узнавайте перрвыми новости мировой игровой индустрии, читайте обзоры игр, скачивайте игровые обои HD. Будьте в курсе!

Anonymous said...

В помощь вашему бизнесу:
Самые новые базы данных предприятий России - 73 города,
последнее обновление - октябрь 2012г,
более 200Мб информации, а это более 1,5 млн.контактов.
Адрес, сфера организации, вид деятельности, телефон, факс, сайт, email, долгота/широта, время работы.
Цена - 2000р.
Гарантии - любые.
http://bulletben.biz/
99995791 - ICQ
admin@bulletben.biz - email

Anonymous said...

В помощь вашему бизнесу:
Самые новые базы данных предприятий России - 73 города,
последнее обновление - октябрь 2012г,
более 200Мб информации, а это более 1,5 млн.контактов.
Адрес, сфера организации, вид деятельности, телефон, факс, сайт, email, долгота/широта, время работы.
Цена - 2000р.
Гарантии - любые.
http://bulletben.biz/
99995791 - ICQ
admin@bulletben.biz - email

Anonymous said...

Ремонтик Под ключ Капитальный жилых помещений в Запорожье http://ukladka-kafelj.ucoz.ua http://vsjstroika.ucoz.ru http://remontkvartiri.at.ua http://vash-remont.ucoz.ua http://ukladkalaminata.at.ua

Anonymous said...

Ремонтик Комплексный Капитальный жилых помещений в Запорожье http://ukladka-kafelj.ucoz.ua http://vsjstroika.ucoz.ru http://remontkvartiri.at.ua http://vash-remont.ucoz.ua http://ukladkalaminata.at.ua

Anonymous said...

Афтар +1

Anonymous said...

Афтар +1

Anonymous said...

Афтар +1

Anonymous said...

Афтар +1

Anonymous said...

Афтар +1

Anonymous said...

Афтар +1

Anonymous said...

Афтар +1

Anonymous said...

Афтар +1

Anonymous said...

ПРОДАМ участок ЧЕЛЯБИНСКАЯ ОБЛАСТЬ МАЛЫЙ КРЕМЕНКУЛЬ, 7СОТОК СОБственость 89080791300 Email: etd09@mail.ru

Anonymous said...

КаждомуСварочные работы в Самаре. Делаем сварочные и монтажные работы по индивидуальным строительным проектам. Сварочные работы в Самаре! Наш сайт [url=http://svarka63.ru/svarochnye-raboty-v-samare/[/url].

Anonymous said...

Куплю конденсаторы км-5 H30 (зеленые)
от 1 кг! Предложения на мыло
serg12011974@mail.ru

Anonymous said...

Привет всем, есть вопрос, попался сайт [url=http://kladidengu.clan.su/]kladidengu.clan.su[/url] kladidengu.clan.su, не могу разобраться как тут зарабатывают, кто нибудь может пояснить? Заранее спасибо.

Anonymous said...

КаждомуСварочные работы в Самаре. Делаем сварочные и монтажные работы по индивидуальным строительным проектам. Сварочные работы в Самаре! Наш сайт [url=http://xn--63-6kcai3c0bf.xn--p1ai/svarochnye-raboty-v-samare/[/url].

Anonymous said...

ВсемСварочные работы в Самаре. Делаем сварочные и монтажные работы по индивидуальным строительным проектам. Сварочные работы в Самаре! Наш сайт [url=http://xn--63-6kcai3c0bf.xn--p1ai/svarochnye-raboty-v-samare/[/url].

Anonymous said...

Купил внове встраиваемую мойку Blanco могу говорить полностью доволен приобретением, советую всем поручение делал чрез сайт интернет магазина, обработали быстрее чем я думал, консультанты для сайте вежливые и отзывчивые,нравиться было.)) Вот доказательство для собственноручно сайт,кому надо http://the.dp.ua

Anonymous said...

Купил внове встраиваемую мойку Blanco могу говорить полностью доволен приобретением, советую всем поручение делал чрез сайт интернет магазина, обработали быстрее чем я думал, консультанты для сайте вежливые и отзывчивые,нравиться было.)) Вот доказательство для собственноручно сайт,кому надо http://the.dp.ua

Anonymous said...

Купил внове встраиваемую мойку Blanco могу говорить полностью доволен приобретением, советую всем поручение делал чрез сайт интернет магазина, обработали быстрее чем я думал, консультанты для сайте вежливые и отзывчивые,нравиться было.)) Вот доказательство для собственноручно сайт,кому надо http://the.dp.ua

Yegor Styblyna said...

При таком подходе AfterConstruction вызывается дважды.
И вообще, вызывать конструктор дважды - не есть гут - обязательно вылезет в наследниках.
Уберите из "Singleton.GetInstance;" вызов "inherited Create;" и все станет на свои места)) (т.к. он вызывается в NewInstance).