Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2013.07.28;
Скачать: CL | DM;

Вниз

Singleton в Delphi   Найти похожие ветки 

 
Хыхы   (2013-03-04 00:10) [0]

Как сделать универсальный класс синглетона, если в Delphi нет статичных классовых переменных.


 
Kerk ©   (2013-03-04 00:14) [1]

http://lmgtfy.com/?q=Delphi%2Bsinglton


 
Ega23 ©   (2013-03-04 00:26) [2]


> Как сделать универсальный класс синглетона

Универсальный-то зачем?


 
Хыхы   (2013-03-04 01:07) [3]


> Ega23 ©   (04.03.13 00:26) [2]
>
>
> > Как сделать универсальный класс синглетона
>
> Универсальный-то зачем?


Чтобы наследоваться от TSingleton.


 
картман ©   (2013-03-04 02:45) [4]


> Чтобы наследоваться от TSingleton.

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


 
Дмитрий С ©   (2013-03-04 07:10) [5]


> если в Delphi нет статичных классовых переменных

что значит Если?


 
bems ©   (2013-03-04 08:30) [6]

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


 
icWasya ©   (2013-03-04 09:20) [7]

По простому не получится. Можно завести список, в которые помещать уже созданные экземпляры классов. А ключом в этом списке будет указатель на класс.


 
Хыхы   (2013-03-04 10:54) [8]


> Дмитрий С ©   (04.03.13 07:10) [5]
>
>
> > если в Delphi нет статичных классовых переменных
>
> что значит Если?


Delphi 7  их нет.


> bems ©   (04.03.13 08:30) [6]
>
> Если классовых полей нет, то ничего не мешает выделить под
> это дело отдельный юнит, где просто некому обратиться к
> переменной, объявленной в implementation и поломать инкапсуляцию.
>  


Тогда TSingleton не получится.


> icWasya ©   (04.03.13 09:20) [7]
>
> По простому не получится.


Вот именно.
Нужно заводить глобальные списки и т.д.
Ужас.

Как без них то?


 
DVM ©   (2013-03-04 11:31) [9]

http://ins911.blogspot.ru/2008/12/singletone-delphi.html


 
sniknik ©   (2013-03-04 11:37) [10]

> Нужно заводить глобальные списки и т.д.
> Ужас.
чего ужасного? один список прямо в модуле синглетона. не каждый же раз их писать.

> Как без них то?
можно на "атомах" или "мьютексах" сделать... задавать имя по процессу + номеру "синглетона" (чтобы 2 копии работали).
... и вот тут будет настоящий ужас.


 
Ega23 ©   (2013-03-04 11:55) [11]


> Как без них то?

Да сделай ты протейший вариант:


type

 TMySingleton = class (...)
 .....
 end;

function MySingleton: TMySingleton;

implementation

var
 __MySingleton: TMySingleton;  

function MySingleton: TMySingleton;
begin
 if __MySingleton = nil then
    __MySingleton := TMySingleton.Create;
 Result := __MySingleton;
end;

initialization

finalization
 __MySingleton.Free;

end.


Вот тебе и будет синглтон. Обращаться - MySingleton.


 
DVM ©   (2013-03-04 12:14) [12]


> Ega23 ©   (04.03.13 11:55) [11]


> function MySingleton: TMySingleton;
> begin
>  if __MySingleton = nil then
>     __MySingleton := TMySingleton.Create;
>  Result := __MySingleton;
> end;

Только если поток один, если несколько так не пойдет, InterlockedXXX функции надо тогда.


 
Ega23 ©   (2013-03-04 12:17) [13]


> Только если поток один, если несколько так не пойдет, InterlockedXXX
> функции надо тогда.

Если многопоточность, то CS добавить. Например.
Всё решаемо, причём малой кровью.


 
Дмитрий С ©   (2013-03-04 12:53) [14]

Еще нужно нилить перемернную при освобождении.


 
Ega23 ©   (2013-03-04 12:58) [15]


> Еще нужно нилить перемернную при освобождении.


Это в finalization? :)


 
Kerk ©   (2013-03-04 13:03) [16]


> Ega23 ©   (04.03.13 12:58) [15]

Что будешь делать, если чужая финализация решит к этому объекту обратиться? Упаришься выстраивать порядок финализации. Не люблю я эти синглтоны :)


 
DVM ©   (2013-03-04 13:09) [17]


> Kerk ©   (04.03.13 13:03) [16]

наверное можно решить, освобождая экземпляр не в finalization, в
class destructor класса TMySingleton. Именно в классовом деструкторе.
Примерно так у TEncoding удаляются кодировки, которые тоже синглтоны по сути.


 
Ega23 ©   (2013-03-04 13:16) [18]


> Что будешь делать, если чужая финализация решит к этому
> объекту обратиться?


чужая - это как?


> Упаришься выстраивать порядок финализации. Не люблю я эти
> синглтоны :)

Да я тоже не очень люблю.


 
bems ©   (2013-03-04 13:30) [19]


> Тогда TSingleton не получится.

дело в том, что классовые поля в дельфи более новых версий работают аналогично. например есть код program Project14;

{$APPTYPE CONSOLE}

type
 TA = class
 strict protected
   class var
     FCount: Integer;
 public
   constructor Create; virtual;
 end;

 TB = class(TA)
 public
   constructor Create; override;
 end;

 TC = class(TA)
 public
   constructor Create; override;
 end;

constructor TA.Create;
begin
 writeln(FCount);
 Inc(FCount)
end;

constructor TB.Create;
begin
 inherited;
 writeln(FCount);
 writeln("-------------");
end;

constructor TC.Create;
begin
 inherited;
 writeln(FCount);
 writeln("-------------");
end;

begin
 TB.Create.Destroy;
 TC.Create.Destroy;
 readln
end.


запускаем, и видим что есть только один экземпляр поля FCount:

0
1
-------------
1
2
-------------


поэтому даже с классовыми полями тебе понадобится словарь наследников синглтона


 
Хыхы   (2013-03-04 14:31) [20]


> Ega23 ©   (04.03.13 11:55) [11]
> implementation
>
> var
>  __MySingleton: TMySingleton;  


А если 2 синглетона?
Что будет в __MySingleton?

В FLASH есть глобальная переменная для класса.
Вижу только в новых Delphi такое есть.
А в старых придётся делать какими-то списками...


 
Ega23 ©   (2013-03-04 15:04) [21]


> А если 2 синглетона?

Как может быть ДВА синглтона, если из названия следует, что он ОДИН?


> В FLASH есть глобальная переменная для класса.
> Вижу только в новых Delphi такое есть.


Добавь к проекту новую форму Form2.

Бац, видим что?

type

 TForm2 = class (TForm)

 end;

var

 Form2: TForm2;


Самая натуральная глобальная переменная.


 
XNA   (2013-03-04 15:08) [22]


> Ega23 ©   (04.03.13 15:04) [21]
>
>
> > А если 2 синглетона?
>
> Как может быть ДВА синглтона, если из названия следует,
> что он ОДИН?


Этот случай:


type
 TSingleton_1 = class (TMySingleton);
 TSingleton_2 = class (TMySingleton);


 
Ega23 ©   (2013-03-04 15:14) [23]


> Этот случай:


type
 TSingleton_1 = class (TMySingleton);
 TSingleton_2 = class (TMySingleton);

function Singleton_1: TSingleton_1;
function Singleton_2: TSingleton_2;

implementation

var
 __Singleton_1: TSingleton_1;  
 __Singleton_2: TSingleton_2;

function Singleton_1: TSingleton_1;
begin
 if __Singleton_1 = nil then
   __Singleton_1 := TSingleton_1.Create;
 Result := __Singleton_1;
end;

function Singleton_2: TSingleton_2;
begin
 if __Singleton_2 = nil then
   __Singleton_2 := TSingleton_2.Create;
 Result := __Singleton_2;
end;

....

finalization

 __Singleton_1.Free;
 __Singleton_1.Free;
 


Это если всё в одном модуле сидит.


 
DVM ©   (2013-03-04 15:16) [24]


> А если 2 синглетона?

То это уже не синглтоны


 
Ega23 ©   (2013-03-04 15:22) [25]

Вообще я не понимаю, нафига огород городить?
Вот есть некий класс. Допустим, что логика приложения такова, что он должен существовать в одном экземпляре. Но, блин, при чём тут реализация самого класса? Это реализация логики приложения.

простой пример. Есть база, есть клиентское приложение. Есть коннект к базе. В 90% случаев - он один. Давайте его будем наследовать от специального класса TCustomSingleton, перекрывать всякие FreeInstance, изгаляться над NewInstance, чтобы никакой быдлокодер ВНЕЗАПНО не смог ему Free сделать (а ссылка-то не обнилится, да).
кто-нибудь так делает? Нет. Кидают ADOConnection в датамодуль (который, на минуточку, тоже один, если чё, и тоже как синглтон выступает) и спокойно с ним работают. И почему-то никому в голову не приходит грохнуть этот коннект.

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

ИМХО, не стоит овчинка выделки.


 
Хыхы   (2013-03-04 17:09) [26]


> Ega23 ©   (04.03.13 15:22) [25]


В Delphi класс синглетона замутно делать.
class var облегчает.


 
Ega23 ©   (2013-03-04 17:31) [27]


> В Delphi класс синглетона замутно делать.


Ещё раз: ты не делаешь класс синглтона. Ты делаешь объект некоего класса, как синглтон. А класс - сегодня нужен так, а завтра - этак.

В Delphi замутно было каждый раз для ObjectList тип Object-а прописывать. Либо приводить к нему. Вот это было замутно, т.к. чуть ли не каждый день используешь. TObjectList<T> проблему решил.

Ты почти каждый день пользуешься объектом Connection, который, по сути, в 99% твоих клиентов под БД является синглтоном. Ты же не делаешь свой собственный коннект для каждого запроса, не так ли? Однако почему-то тебе не приходит в голову оборачивать его какими-то хитрыми обёртками.
И главная форма у тебя - ну чем не синглтон, по своей сути-то? И не смущает тебя, что он прямо в юните формы как глобальный var объявлен.
Но стоит только появиться какому-нить несчастному TMyDictionary - всё, начинаем фалломорфировать на паттерны проектирования ради паттернов проектирования.
Вот какой в этом смысл?


 
DVM ©   (2013-03-04 17:37) [28]


> И главная форма у тебя - ну чем не синглтон, по своей сути-
> то? И не смущает тебя, что он прямо в юните формы как глобальный
> var объявлен.

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

Гораздо лучше привести в пример объекты Screen, Printer, Application - вот они по сути синглтоны, но не синглтоны по исполнению.


 
Хыхы   (2013-03-04 17:39) [29]

Да ладно.
Синглетон - это защита от дурака.
У нас дураков нет. :)

Поэтому не нужно.


 
Ega23 ©   (2013-03-04 19:37) [30]

Я это всё к тому, что всегда можно найти способ выстрелить себе в ногу. И, ИМХО, сидеть и создавать супер-пупер-навороченную защиту от выстрела в ногу - не рационально (тем более, что всё равно существует ненулевая вероятность того, что какая-нить пытливая обезьяна таки найдёт способ эту защиту обойти).
гораздо проще в ногу не стрелять. :)


 
bems ©   (2013-03-04 19:48) [31]


> class var облегчает

каким образом облегчает?


 
Хыхы   (2013-03-04 19:53) [32]

> bems ©   (04.03.13 19:48) [31]
> class var облегчает
> каким образом облегчает?

Не нужно заводить глобальных переменных.


 
bems ©   (2013-03-04 20:25) [33]

Ну это всего лишь область видимости секция implementation против области видимости класс. Разницы почти нет.


 
Хыхы   (2013-03-04 20:38) [34]

> bems ©   (04.03.13 20:25) [33]
> Ну это всего лишь область видимости секция implementation против области
> видимости класс. Разницы почти нет.

При наследовании class var будет уникальный для каждого потомка.
А с глобальной переменной - будет косяк. Одна она.


 
bems ©   (2013-03-04 21:11) [35]


> При наследовании class var будет уникальный для каждого
> потомка.

не будет, и я тебе это продемонстрировал в [19]


 
Хыхы   (2013-03-04 21:21) [36]

> bems ©   (04.03.13 21:11) [35]

В других языках вроде как будет.
Иначе я не вижу смысле в этом class var.


 
bems ©   (2013-03-04 21:50) [37]

в каких-то может и будет, но вот например в сишарпе
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
   public class A
   {
       protected static int Count;

       public A()
       {
           Console.WriteLine(Count);
           ++Count;
       }
   }

   public class B: A
   {
       public B()
       {
           Console.WriteLine(Count);
           Console.WriteLine("---------");
       }
   }

   public class C : A
   {
       public C()
       {
           Console.WriteLine(Count);
           Console.WriteLine("---------");
       }
   }

   class Program
   {
       static void Main(string[] args)
       {
           new B();
           new C();
           Console.ReadLine();
       }
   }
}


дает вот это
0
1
---------
1
2
---------


 
Хыхы   (2013-03-04 23:10) [38]

> bems ©   (04.03.13 21:50) [37]

А зачем они нужны эти class var тогда?


 
Ega23 ©   (2013-03-04 23:50) [39]

А по-твоему применение class var - только в синглтоне?


 
Хыхы   (2013-03-05 04:03) [40]

> Ega23 ©   (04.03.13 23:50) [39]
> А по-твоему применение class var - только в синглтоне?

Где я такое говорил?


 
sniknik ©   (2013-03-05 08:12) [41]

> Где я такое говорил?
->
> В других языках вроде как будет.
> Иначе я не вижу смысле в этом class var.

+ оно нигде не будет, ИМХО, смысл другой (ООП-а а не просто дельфи). - инкапсулировать вообще все, т.е. для логически включаемого в класс но могущего работать отдельно (т.е. это по сути регулярные/глобальные процедуры/функции и теперь вот переменные, просто "описаны в классе")



Страницы: 1 2 вся ветка

Текущий архив: 2013.07.28;
Скачать: CL | DM;

Наверх




Память: 0.58 MB
Время: 0.009 c
15-1362408571
Хыхы
2013-03-04 18:49
2013.07.28
Запущен ли скрин-сейвер или трабла с константами?


15-1362429004
Юрий
2013-03-05 00:30
2013.07.28
С днем рождения ! 5 марта 2013 вторник


15-1362291457
Ega23
2013-03-03 10:17
2013.07.28
Онлайн шутер посоветуйте?


15-1362398967
Kerk
2013-03-04 16:09
2013.07.28
Обход графа


11-1200759004
Jon
2008-01-19 19:10
2013.07.28
TabControl Pages