Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 как переделать на синглтон  [new]
СинийТон
Guest
Есть библиотечка, а в ней классик.
Как его переделать на синглтон, чтобы не менять код в других модулях?
2 янв 18, 18:19    [21078998]     Ответить | Цитировать Сообщить модератору
 Re: как переделать на синглтон  [new]
rgreat
Member

Откуда:
Сообщений: 4169
СинийТон
Есть библиотечка, а в ней классик.
Как его переделать на синглтон

function -> class function
procedure -> class procedure
var -> class var

, чтобы не менять код в других модулях?
Никак. Код менять придется.
2 янв 18, 18:32    [21079014]     Ответить | Цитировать Сообщить модератору
 Re: как переделать на синглтон  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 10313
Попробуйте внятно объяснить, что у Вас есть, почему Вас это не устраивает и, что Вы хотите изменить?
2 янв 18, 18:41    [21079028]     Ответить | Цитировать Сообщить модератору
 Re: как переделать на синглтон  [new]
СинийТон
Guest
rgreat, так можно, да, но люди привыкли к Сreate-Free.

Ещё есть доп-условия:
- не менять ранее написанный код использования,
- не создавать раньше первого реального Сreate,
- Сreate может быть из нескольких потоков,
- если можно, то сделать реальный Free, если сейчас этот объект не нужен (хотелка)

по-факту даже не синглтон получается, а как-то так ...

Что-то туплю, чую простое решение, но туплю.
2 янв 18, 18:54    [21079050]     Ответить | Цитировать Сообщить модератору
 Re: как переделать на синглтон  [new]
СинийТон
Guest
_Vasilisk_, внятно объяснить это наверное завтра, может отосплюсь, а то тяжело синапсам так сразу в бой )
2 янв 18, 18:59    [21079060]     Ответить | Цитировать Сообщить модератору
 Re: как переделать на синглтон  [new]
rgreat
Member

Откуда:
Сообщений: 4169
СинийТон
rgreat, так можно, да, но люди привыкли к Сreate-Free.

Вы так говорите как будто это что-то хорошее.

Ещё есть доп-условия:
- не менять ранее написанный код использования,

В чем тогда смысл синглтона, и что вы вообще подразумеваете под этим термином?

- не создавать раньше первого реального Сreate,

Разве бывают некие-то "не реальные" Create?

- Сreate может быть из нескольких потоков,

Ок, но при чем тут синглтон?

- если можно, то сделать реальный Free, если сейчас этот объект не нужен (хотелка)
по-факту даже не синглтон получается, а как-то так ...

Может вам не синглтон а контейнер нужен?

Что-то туплю, чую простое решение, но туплю.
Как-то да. TList<T> или TDictionary<T> маячат на горизонте.
2 янв 18, 19:49    [21079135]     Ответить | Цитировать Сообщить модератору
 Re: как переделать на синглтон  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 10313
СинийТон
Ещё есть доп-условия:
- не менять ранее написанный код использования,
- не создавать раньше первого реального Сreate,
- если можно, то сделать реальный Free, если сейчас этот объект не нужен (хотелка)

1. Исходный класс переименовываем и прячем в Implementation
2. Объявляем интерфейс с тем же именем и методами, что раньше были у класса
3. Объявляем, что наш класс реализует этот интерфейс
4. Объявляем у интерфейса метод Free и делаем пустым его реализацию
5. Объявляем функцию CreateMyObject в таком духе
var
  GSingleton: IMyIntf;

function CreateMyObject: IMyIntf;
begin
  if GSingleton = nil then begin
    GSingleton := TMyObj.Create;
    Result := GSingleton;
    GSingleton._Release;  // Освобождаем счетчик ссылок
  end else
    Result := GSingleton;
end;

6. В деструкторе не забываем обнулить ссылку
destructor TMyObj.Destroy;
begin
  Pointer(GSingleton) = nil;
  inherited Destroy;
end;

СинийТон
- Сreate может быть из нескольких потоков,
Не забываем про синхронизацию доступа как к самому GSingleton, так и к его полям

Таким образом, все задачи, кроме
СинийТон
но люди привыкли к Сreate
решены. Вместо Сreate придется таки писать CreateMyObject
2 янв 18, 19:52    [21079144]     Ответить | Цитировать Сообщить модератору
 Re: как переделать на синглтон  [new]
X-Cite
Member

Откуда: Минск
Сообщений: 1065
Чтобы все удовлетворяло вашим условиям и нигде не менять код Используйте паттерн адаптер
Вы сможете повторить все методы вашего класса + добавить новые (Free когда объект реально (по мнению разработчика, а не системы) не нужен). Внутри адаптера реализуйте ваш класс в виде синглтона.
Платой за это будет дублирование всех public методов и свойств
2 янв 18, 20:05    [21079161]     Ответить | Цитировать Сообщить модератору
 Re: как переделать на синглтон  [new]
СинийТон
Guest
Спасибо за замечания-предложения!

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


- Да, адаптер, как-бы оно, но его и хочется сделать синглтоном (не создавать на каждый Create).


- А если по аналогии с
4. Объявляем у интерфейса метод Free и делаем пустым его реализацию
подменить конструктор на:
TTest = class
  class function Create:TTest;
end;

class function TTest.Create: TTest;
begin
 // inc(fRef);
 // if single then
 Result := inherited Create;
end;
Так сработает или это совсем грязно?
3 янв 18, 10:26    [21079785]     Ответить | Цитировать Сообщить модератору
 Re: как переделать на синглтон  [new]
makhaon
Member

Откуда: A galaxy far far away
Сообщений: 2577
нужно, как в соседней ветке, для начала разобраться с тз: нужен один инстанс класса (синглтон) или много инстансов? потом думать как тз реализовать.
3 янв 18, 12:45    [21079975]     Ответить | Цитировать Сообщить модератору
 Re: как переделать на синглтон  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 10313
СинийТон
Да, адаптер, как-бы оно, но его и хочется сделать синглтоном
Зачем? В адаптере нет никаких полей. Зачем он синглтоном
СинийТон
Так сработает или это совсем грязно?
Для конструктора сработает. Для Free как метода класса - нет
3 янв 18, 15:07    [21080169]     Ответить | Цитировать Сообщить модератору
 Re: как переделать на синглтон  [new]
СинийТон
Guest
makhaon, да, тз:

Реализовать класс который
- поддерживает многопоточное использование;
- создаст только один инстанс на время использования;
- когда все ссылки на инстанс будут освобождены, освободит и этот {один} инстанс;
4 янв 18, 11:29    [21081330]     Ответить | Цитировать Сообщить модератору
 Re: как переделать на синглтон  [new]
makhaon
Member

Откуда: A galaxy far far away
Сообщений: 2577
СинийТон,

судя по тз, единственный инстанс во время работы должен постоянно создаваться и разрушаться?
4 янв 18, 11:39    [21081347]     Ответить | Цитировать Сообщить модератору
 Re: как переделать на синглтон  [new]
X-Cite
Member

Откуда: Минск
Сообщений: 1065
СинийТон
makhaon, да, тз:

Реализовать класс который
- поддерживает многопоточное использование;
- создаст только один инстанс на время использования;
- когда все ссылки на инстанс будут освобождены, освободит и этот {один} инстанс;


У вас во время создания инстанса происходит долгая инициализация? Или класс должен быть statefull между разными потоками? Или по коду должен быть один экземпляр общий для всех? (Например настройки приложения)
Какой смысл перевода на синглтон? Просто работа ради работы или есть действительное обоснование?
4 янв 18, 13:27    [21081539]     Ответить | Цитировать Сообщить модератору
 Re: как переделать на синглтон  [new]
СинийТон
Guest
makhaon
единственный инстанс во время работы должен постоянно создаваться и разрушаться?
да, но там всплески активности раз в час или несколько часов, а использующие на самом деле не сразу зовут фри, а с некоторой задержкой.

У вас во время создания инстанса происходит долгая инициализация?
Или класс должен быть statefull между разными потоками?
Или по коду должен быть один экземпляр общий для всех? (Например настройки приложения)
- Иногда, - да, - да
Какой смысл перевода на синглтон? Просто работа ради работы или есть действительное обоснование?
Первоначально не думалось про многопоточное использование (и такой псевдо синглтон получался сам собой). Теперь ещё и оптимизации какой-то захотелось и разобраться для себя интересно.
4 янв 18, 14:34    [21081678]     Ответить | Цитировать Сообщить модератору
 Re: как переделать на синглтон  [new]
kealon(Ruslan)
Member

Откуда: Нижневартовск
Сообщений: 2995
СинийТон
rgreat, так можно, да, но люди привыкли к Сreate-Free.
Откуда только такие дегенераты берутся, гнать таких надо. "Программист" и "привык" это всё - крах карьеры.

модуль по сути и есть синглтон, не надо всякую фигню изобретать без острой необходимости.
5 янв 18, 08:52    [21082759]     Ответить | Цитировать Сообщить модератору
 Re: как переделать на синглтон  [new]
makhaon
Member

Откуда: A galaxy far far away
Сообщений: 2577
СинийТон,

костылевато, конечно, довольно сильно. ну да ладно.

Create/Free переопределить, вести в них счетчик (если многопоточка - то через InterlockedIncrement/TInterlocked.Increment). Счетчик и сам инстанс сделать классовыми переменными. В Create если счетчик = 0, создаём единственный внутренний инстанс, иначе ничего не деаем. Во Free пока счетчик больше 0, ничего не делаем. Когда становится равным нулю, разрушаем единственный инстанс. Все методы и свойства делаем через классовый методы к внутреннему реальному инстансу.
5 янв 18, 11:43    [21082895]     Ответить | Цитировать Сообщить модератору
 Re: как переделать на синглтон  [new]
СинийТон
Guest
makhaon, оно то всё так, но с многопоточкой есть нюансы.

Когда одновременно два потока зайдут в Create кто-то из них должен будет создать инстанс, а кто-то подождать результата его работы.

И при обычных условия внутри Create у нас уже есть новый инстанс, нужно, как я понимаю, переопределить NewInstance.
Буду смотреть в отладчике как там и что, раньше с таким не сталкивался. Если у кого есть примерчик с краткими пояснениями, то не откажусь.
5 янв 18, 13:31    [21083107]     Ответить | Цитировать Сообщить модератору
 Re: как переделать на синглтон  [new]
СинийТон
Guest
kealon(Ruslan), ?

Есть мой функционал в dll. Для удобства его использования сделал обёртку.

Ребята используют как-то так:
w :=TWrapper.Create;
try
  w.Run();
finally
  w.Free;
end;
Хочу-нужно изменить внутреннюю реализацию, по возможности, не напрягая коллег.

Что в этом неэстетического, что Вас огорчило?
5 янв 18, 13:51    [21083140]     Ответить | Цитировать Сообщить модератору
 Re: как переделать на синглтон  [new]
X-Cite
Member

Откуда: Минск
Сообщений: 1065
СинийТон,

Так пусть w :=TWrapper.Create; создается хоть 100500 экземпляров... Он как адаптер обернет ваш скрытый синглтон, который будет в единственном экземпляре.
Не надо городить переопределения NewInstance FreeInstance.
Сделали Адаптер и забыли... Единственное что при появлении метода в вашем классе, его надо пробросить и в адаптер. Но это решается комментариями к классу
5 янв 18, 14:06    [21083166]     Ответить | Цитировать Сообщить модератору
 Re: как переделать на синглтон  [new]
СинийТон
Guest
X-Cite
Так пусть w :=TWrapper.Create; создается хоть 100500 экземпляров...
да, новогодний перфекционизм рассеялся - скрипач синглтон не нужен )).
5 янв 18, 14:42    [21083229]     Ответить | Цитировать Сообщить модератору
 Re: как переделать на синглтон  [new]
makhaon
Member

Откуда: A galaxy far far away
Сообщений: 2577
автор
Когда одновременно два потока зайдут в Create кто-то из них должен будет создать инстанс, а кто-то подождать результата его работы.


Один поток создаст инстанс потому, что счётчик будет = 0. Второй поток должен, как я понимаю, InterlockedIncrement'ом придержаться. И ему уже вернётся счетчик = 1. Отдельную проверку счетчику не делать, проверять результат InterlockedIncrement'а.
5 янв 18, 19:14    [21083697]     Ответить | Цитировать Сообщить модератору
 Re: как переделать на синглтон  [new]
makhaon
Member

Откуда: A galaxy far far away
Сообщений: 2577
Если совсем не получится - то по-старинке, критической секцией, одной на конструктор и деструктор. Тогда и счетчик можно не лочить.
5 янв 18, 19:17    [21083700]     Ответить | Цитировать Сообщить модератору
 Re: как переделать на синглтон  [new]
makhaon
Member

Откуда: A galaxy far far away
Сообщений: 2577
также можно посмотреть в сторону InterlockedCompareExchange и InterlockedAdd.
5 янв 18, 19:30    [21083721]     Ответить | Цитировать Сообщить модератору
 Re: как переделать на синглтон  [new]
kealon(Ruslan)
Member

Откуда: Нижневартовск
Сообщений: 2995
СинийТон
kealon(Ruslan), ?

Есть мой функционал в dll. Для удобства его использования сделал обёртку.

Ребята используют как-то так:
w :=TWrapper.Create;
try
  w.Run();
finally
  w.Free;
end;
Хочу-нужно изменить внутреннюю реализацию, по возможности, не напрягая коллег.

Что в этом неэстетического, что Вас огорчило?
меня это нисколько не огорчает, пока будут такие деятели у меня будет работа и зп

чем
???_Run();
сложнее для понимания?
5 янв 18, 20:16    [21083782]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Delphi Ответить