PDA

Просмотр полной версии : Singleton в Delphi, как сделать подобие?


Felan
03.02.2005, 13:40
Как лушче всего реализовать подобие Singleton'а (С++) в делфи?
Или как вообще поступают в делфи, когда надо гарантировать один экземпляр класса на приложение?
Я вижу только один способ, передавать параметром по иерархии классов. Т.е. один раз создается, а потом передается классам верхнего уровня, а те, в свою очередь, передают его ниже в процедурах установки свойств.
Но способ мне не нравится, надо следить за всеми этими присвоениями. Вобщем, как првильно сделать в Delphi 7 (если версия имеет значение).

PVitaliy
09.02.2005, 11:26
достаточно просто.
Пути я вижу 3, выбери тот который тебе больше всего нравится:

1. в том модуле, где обьявлен твой класс сделай в интерфейсной части глобальную переменную типа твоего класса. В initialize модуля создай экземпляр класса, и присвой ей

2. в том модуле, где обьявлен твой класс сделай глобальную переменную типа твоего класса но в секции implementation. В initialize модуля создай экземпляр класса, и присвой ей. В классе сделай класс функцию (статические в С++) и пусть она возвращает нашу переменную.

3. в том модуле, где обьявлен твой класс в секции implementation сделай глобальную переменную типа твоего класса. В классе сделай класс функцию типа такого:
if YourVar = nil then YourVar:=YourClass.Create;
result:=YourVar;

возможны еще вариации, но ИМХО выходит самый настоящий сингилитон

is_absent
09.02.2005, 12:13
{$J+}
unit Singleton;

interface

uses
Classes, SysUtils, Forms, Controls, Windows;

type

TSingleton = class(TControl)
private
//
protected
//
constructor CreateInstance;
class function AccessInstance(Request: Integer): TSingleton;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;

class function Instance: TSingleton;
class procedure ReleaseInstance;
end;

implementation

class function TSingleton.AccessInstance(Request: Integer): TSingleton;
const
FInstance: TSingleton = nil;
begin
case Request of
0: ;
1: if not Assigned(FInstance) then FInstance:= CreateInstance;
2: FInstance := nil;
else raise Exception.CreateFmt('Illegal request %d in AccessInstance', [Request]);
end;
Result := FInstance;
end;

constructor TSingleton.Create;
begin
// нельзя его вызывать!
raise Exception.CreateFmt('Access class %s through Instance only', [ClassName]);
end;

constructor TSingleton.CreateInstance;
begin
inherited Create(nil);
// делаем то, что нужно
end;

destructor TSingleton.Destroy;
begin
// прибираемся за собой
inherited;
end;

class function TSingleton.Instance: TSingleton;
begin
Result := AccessInstance(1);
end;

class procedure TSingleton.ReleaseInstance;
begin
AccessInstance(0).Free;
end;

end.

так красивше :)

соответственно потом обращаться TSingleton.instance....