Форум: "Прочее";
Текущий архив: 2013.10.06;
Скачать: [xml.tar.bz2];
ВнизНужен третейский судья :) Найти похожие ветки
← →
Ega23 © (2013-04-24 17:57) [240]Удалено модератором
← →
DevilDevil © (2013-04-24 18:01) [241]Удалено модератором
← →
Аббат Пиккола (2013-04-24 18:01) [242]Удалено модератором
← →
DevilDevil © (2013-04-24 18:12) [243]Удалено модератором
← →
Аббат Пиккола (2013-04-24 18:15) [244]Удалено модератором
← →
Аббат Пиккола (2013-04-24 18:25) [245]Удалено модератором
← →
Smile (2013-04-24 18:26) [246]Удалено модератором
← →
Аббат Пиккола (2013-04-24 18:36) [247]Удалено модератором
← →
Компромисс1 © (2013-04-24 18:58) [248]Аббат Пиккола (24.04.13 18:36) [247]
Я работал с одним framework, где почти все объекты были синглтонами, причем заменяемыми и доступными из любого контекста.
Например, был Foo.someMethod1(...), который делегировал всю работу Foo.getInstance().someMethod(...), Foo.someMethod2() делегировал всю работу Foo.getInstance().someMethod2 и т.д. Можно было писать и напрямую, так как getInstance() был public. Был и public Foo.setInstance(foo), то есть можно было менять синглтон. Причем Foo.getInstance() всегда возвращал интерфейс, а не класс. Не могу сказать, что красиво сделано, но по крайней мере работает без проблем.
← →
Ega23 © (2013-04-24 19:22) [249]Есть мнение, что некоторые люди, начитавшись банды четырёх, программирование по паттернам возводят в абсолют.
← →
oxffff © (2013-04-24 20:01) [250]
> euru © (24.04.13 17:00) [224]
>
> > _oxffff (24.04.13 16:15) [208]
> > Я просто поставил задачу внести реализацию в namespace
> класса
>
> unit Unit1;
>
> interface
>
> type
> ISingleton = interface
> end;
>
> type
> TSingleton = class(ISingleton)
> private
> class var Instance: TSingleton;
> constructor Create;
> public
> class function GetInstance: ISingleton;
> end;
>
> implementation
>
> class function TSingleton.GetInstance: ISingleton;
> begin
> if TSingleton.Instance = nil then
> TSingleton.Instance = TSingleton.Create;
> Result := TSingleton.Instance;
> end;
>
> finalization
> if TSingleton.Instance <> nil then
> TSingleton.Instance.Free;
> end.
>
> > Что касаемо Вашего кода, то время жизни объекта тоже вызывает
> вопросы. ;)
> А что не так со временем жизни объекта?
1. Смешивание семантики объектной и ссылочной.
class var Instance: TSingleton;
class function GetInstance: ISingleton;
TSingleton = class( XXX , ISingleton)
Если XXX управляет подсчетом ссылок, то после того как
очередной крайний клиент освободит ссылку, произойдет освобождение объекта. Instance будет указывать на мусор
2. Аналогично Вашего примера(да такого нет в D7, но есть в поздних)
(TSingleton.GetInstance as TObject).free
← →
oxffff © (2013-04-24 20:13) [251]
> euru © (24.04.13 17:00) [224]
Нет, ну конечно и в моем и в Вашем 2 случае проблему можно решить.
Например так:
class destructor FinalizeClass;
begin
freeAndNil(Instance); <-мы то знаем, что сначала nil, потом free
end;
destructor destroy;override;
begin
if assigned(Instance) then exit;
inherited;
end;
← →
oxffff © (2013-04-24 20:17) [252]@euru, помню ты SAP занимался.
Завтра у меня сдача на сертификат по SAP Unwired Platform на Павелецкой. :)
← →
Rouse_ © (2013-04-24 20:18) [253]
> Чем не решение?
Почему бы и нет? :)
← →
oxffff © (2013-04-24 20:28) [254]
> destructor destroy;override;
> begin
> if assigned(Instance) then exit;
> inherited;
> end;
Хех, поторопился. exit переходит на обязательную часть по освобождению. Тем интересней. :)
← →
oxffff © (2013-04-24 20:33) [255]Тогда так
class destructor FinalizeClass;
begin
freeAndNil(Instance);
end;
procedure FreeInstance;override;
begin
if assigned(Instance) then exit;
inherited;
end;
← →
oxffff © (2013-04-24 20:40) [256]Точнее так, чтобы объект не произвел cleanup и не освободился где не положено
class destructor FinalizeClass;
begin
freeAndNil(Instance);
end;
destructor destroy;override;
begin
if assigned(Instance) then exit;
inherited;
end;
procedure FreeInstance;override;
begin
if assigned(Instance) then exit;
inherited;
end;
← →
Дмитрий С © (2013-04-25 06:05) [257]А не проще Instance объявить тоже интерфейсом?
← →
oxffff © (2013-04-25 08:07) [258]Ну от (TSingleton.GetInstance as TObject).free это объявление не спасет.
← →
Дмитрий С © (2013-04-25 14:54) [259]Разве интерфейсу можно сделать as Tobject?
← →
euru © (2013-04-25 17:43) [260]
> oxffff © (24.04.13 20:01) [250]
> Если XXX управляет подсчетом ссылок, то после того как очередной
> крайний клиент освободит ссылку, произойдет освобождение объекта.
> Instance будет указывать на мусор2.
Я давно уже не использую Delphi, поэтому свои примеры писал по той остаточной информации, что ещё помню. И совершенно забыл, что в Delphi у интерфейсов "странное" поведение.
В качестве решения этой проблемы можно у синглтона перегрузить методы AddRef и Release, в которых исключить подсчет ссылок (зачем их считать, если объект всегда в единственном экземпляре).
> (TSingleton.GetInstance as TObject).free
Явное приведение к TObject в данном контексте - это намеренное вредительство :)
Можно перекрыть деструктор синглтона, в котором проверять, действительно ли нужна финализация объекта.
← →
euru © (2013-04-25 17:46) [261]
> oxffff © (24.04.13 20:17) [252]
> @euru, помню ты SAP занимался.Завтра у меня сдача на сертификат
> по SAP Unwired Platform на Павелецкой. :)
Почему занимался? Я и сейчас занимаюсь.
← →
oxffff © (2013-04-25 18:40) [262]
> Дмитрий С © (25.04.13 14:54) [259]
> Разве интерфейсу можно сделать as Tobject?
Уже можно в новых версиях.
← →
Дмитрий С © (2013-04-25 19:49) [263]
> Уже можно в новых версиях.
Прикольно. Интересно что будет, если интерфейс будет инородный.
← →
Дмитрий С © (2013-04-25 20:35) [264]
> Уже можно в новых версиях.
Хорошо, а как насчет исключения в деструкторе?
← →
han_malign (2013-04-26 11:18) [265]- если вам нужно семантическое разделение вариантов использования - делайте это явно
TXXxx = class
...
protected
class function exclusive(): boolean; virtual; abstract;{!!!}
end;
TExclusiveXxx = class(TXXxx)
protected
class function exclusive(): boolean; override;
end;
TSingletonXxx = class(TXXxx)
protected
class function exclusive(): boolean; override;
public
class function getInstance(): TSingletonXxx;
end;
- TXXxx.Create - ругнется на abstract
- TSingletonXxx.getInstance() as TExclusiveXxx - обломает на этапе компиляции...
соответственно, дабы не словить плюху при явном повышении типа(upcast) - тип TXXxx - можно использовать только при связывании внешнего контекста, в идеале - только как входной параметр функции/метода...
Страницы: 1 2 3 4 5 6 7 вся ветка
Форум: "Прочее";
Текущий архив: 2013.10.06;
Скачать: [xml.tar.bz2];
Память: 1.02 MB
Время: 0.03 c