Singleton в Delphi

Як зробити універсальний клас синглетону, якщо Delphi немає статичних класових змінних.

> Як зробити універсальний клас синглетонуУніверсальний навіщо?

Для успадкування від TSingleton.

> Щоб успадковуватися від TSingleton.ти можеш зробити один клас, який буде надавати синглетон(и) будь-якого класу.

> якщо у Delphi немає статичних класових зміннихщо означає Якщо?

Якщо класових полів немає, то нічого не заважає виділити під цю справу окремий юніт, де просто нема кому звернутися до змінної, оголошеної в implementation і поламати інкапсуляцію. Але давно вже пора злазити з давніх версій дельфі

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

Delphi 7 їх немає.

Тоді TSingleton не вийде.

Ось саме. Потрібно заводити глобальні списки і т.д. Жах.

> Потрібно заводити глобальні списки і т.д. > Жах. чого жахливого? один список прямо у модулі синглетону. не щоразу їх писати.

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

> Як без них то?

TMySingleton = class (. ) . end;

функція MySingleton: TMySingleton;

var __MySingleton: TMySingleton;

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

Ось тобі і буде сінглтон. Звертатися - MySingleton.

> Тільки якщо потік один, якщо так не піде, InterlockedXXX > функції треба тоді.Якщо багатопоточність, то CS додати. Наприклад. Все вирішуване, причому малою кров'ю.

Ще треба нилити перемірну при звільненні.

> Ще потрібно нилити перемірну при звільненні.

> Що робитимеш, якщо чужа фіналізація вирішить до цього > об'єкту звернутися?

> Упаришся вибудовувати порядок фіналізації. Не люблю ці > синглтони:)Так я теж не дуже люблю.

> Тоді TSingleton не вийде.справа в тому, що класові поля в дельфі новіших версій працюють аналогічно. наприклад, є код program Project14;

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;

конструктор TA.Create; begin writeln(FCount); Inc(FCount) end;

конструктор TB.Create; begin inherited; writeln(FCount); writeln("-------------"); end;

конструктор TC.Create; begin inherited; writeln(FCount); writeln("-------------"); end;

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

запускаємо, і бачимо, що є тільки один екземпляр поля FCount:

тому навіть із класовими полями тобі знадобиться словник спадкоємців синглтона

А якщо 2 синглетони? Що буде в __MySingleton?

У FLASH є глобальна змінна для класу. Бачу тільки в нових Delphi таке є. А в старих доведеться робити якимись списками.

> А якщо 2синглетона?Як може бути ДВА синглтона, якщо з назви випливає, що він ОДИН?

> У FLASH є глобальна змінна класу. > Бачу тільки у нових Delphi таке є.

Додай до проекту нову форму Form2.

TForm2 = class (TForm)

Найнатуральніша глобальна змінна.

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

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

function Singleton_1: TSingleton_1; Function Singleton_2: TSingleton_2;

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. Result := __Singleton_2; end;

Це коли все в одному модулі сидить.

> А якщо 2 синглетони?То це вже не синглтони

Взагалі я не розумію, нафіга город городити? Ось є якийсь клас. Припустимо, що логіка програми така, що він має існувати в одному примірнику. Але, млинець, до чого тут реалізація самого класу? Це реалізація логіки програми.

Ну а в іншому додатку логіка така, що даний об'єкт не як синглтон може існувати, а взагалі поряд 100500 екземплярів. Переписуватимемо?

ІМХО, не коштує шкурка вичинки.

У Delphi клас синглетону невиразно робити. class var полегшує.

> У Delphi клас синглетону невиразно робити.

Ще раз: ти не робишклассинглтона. Ти робиш об'єкт якогось класу, яксинглтон. А клас – сьогодні потрібний так, а завтра – так.

У Delphi замутно було щоразу для ObjectList тип Object-а прописувати. Або приводити до нього. Ось це було невиразно, т.к. мало не щодня використовуєш. TObjectList проблему вирішив.

Ти майже кожен день користуєшся об'єктом Connection, який, по суті, у 99% твоїх клієнтів під базою даних є синглтоном. Ти ж не робиш свій власний коннект для кожного запиту, чи не так? Однак чомусь тобі не спадає на думку обертати його якимись хитрими обгортками. І головна форма у тебе - ну чим не синглтон, за своєю суттю? І не бентежить тебе, що він прямо у юніті форми як глобальний var оголошений. Але варто тільки з'явитися якомусь нитку нещасному TMyDictionary - все, починаємо фаломорфувати на патерни проектування заради патернів проектування. От який у цьому сенс?

> І головна форма у тебе – ну чим не синглтон, за своєю суттю- > то? І не бентежить тебе, що він просто в юніті форми як глобальний > var оголошено.Мене бентежить, мені взагалі незрозуміло нафіга вони так зробили, тут точно глобальна змінна нафіг не здалася. Але це так, до речі.

Набагато краще привести в приклад об'єкти Screen, Printer, Application - ось вони насправді синглтони, але не синглтони по виконанню.

Та гаразд. Синглетон - це захист від дурня. У нас дурнів немає. :)

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

> class varполегшуєяким чином полегшує?

Не треба заводити глобальних змінних.

Ну це всього лише область видимості секція implementation проти області видимості клас. Різниці майже немає.

При наслідуванні class var буде унікальний для кожного нащадка. А з глобальною змінною - буде косяк. Одна вона.

> При наслідуванні class var буде унікальним для кожного > нащадка.не буде, і я тобі це продемонстрував у [19]

В інших мовах начебто буде. Інакше я не бачу сенсу в цьому class var.

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

namespace ConsoleApplication1 public class A protected static int 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(); > > >

А навіщо вони потрібні ці class var?

А по-твоєму застосування class var – лише у синглтоні?