16番会議室「玉石混淆みんなで作るSample蔵」に寄せられたサンプル
"Singletonパターン"
こんにちは。
Delphi(Pascal)はもともとはオブジェクト指向言語ではないため、
Delphiでオブジェクト指向しようとするとなかなか難しい場合もあります。
VCLの設計も、オブジェクト指向的に見ると、若干難があるように感じます。
最近困ったのは、Singletonパターンの実現でしたが、
なんとかんとか、それらしいことをする方法を考えました。
関係のある部分だけ抜き出して書きます。
TPart = class;
TPartClass = class of TPart;
PPart = ^TPart;
//TInterfacedObjectを継承していますが、
//必ずそうしなければならないという事ではありません。
TPart = class(TInterfacedObject)
private
//これはオーバーライドさせない。
class function IsCreate(AI: Integer): Boolean;
protected
//これは擬似Staticフィールドを返す。
class function GetVarPointer: PPart; virtual; abstract;
public
//このクラスの子クラスのインスタンスを取得するには、
//このクラスメソッドからしか取得できない。
class function GetInstance: TPart; virtual;
//普通にCreateすると、失敗する様に実装する。
constructor Create;
destructor Destroy; override;
end;
TMDairitenPart = class(TPart)
private
protected
class function GetVarPointer: PPart; override;
public
end;
implementation
class function TPart.IsCreate(AI: Integer): Boolean;
const
B: Boolean = False;
begin
case AI of
0: B := False;
1: B := True;
end;
Result := B;
end;
class function TPart.GetInstance: TPart;
begin
if GetVarPointer^ = nil then
begin
//Createが例外を出さないようにセット
IsCreate(1);
GetVarPointer^ := Self.Create;
//Createしたら、すぐに元に戻す
IsCreate(0);
end;
Result := GetVarPointer^;
end;
constructor TPart.Create;
begin
//Createしてもよいか調べる
if IsCreate(-1) then
inherited Create
else
raise Exception.Create(
'インスタンスを取得するにはGetInstanceメソッドを使ってください');
end;
destructor TPart.Destroy;
begin
inherited Destroy;
FreeAndNil(GetVarPointer^);
end;
//擬似Static変数
var
MDairitenPart: TPart;
class function TMDairitenPart.GetVarPointer: PPart;
begin
//擬似Staticフィールドのポインタを返す
Result := @MDairitenPart;
end;
initialization
;
finalization
FreeAndNil(MDairitenPart);
end.
TMDairitenPartクラスのインスタンスがほしい場合は、
var
o: TPart;
begin
o := TMDairitenPart.GetInstance;
のような感じで取得します。
必要ならば、TMDairitenPartにダウンキャストします。
o := TMDairitenPart.Create;
とすると、例外が発生します。
こうすることによって、システム全体で、
唯一のインスタンスしか存在しないことが保証されます。
かつぼー
- FDELPHI MES(16):玉石混淆みんなで作るSample蔵【見本蓄積】 01/02/12 -
Original document by かつぼー 氏 ID:(CQU00157)
ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum の16番会議室「玉石混淆みんなで作るSample蔵」に投稿されたサンプルです。これらのサンプルはボーランド株式会社がサポートする公式のものではありません。また、必ずしも動作が検証されているものではありません。これらのサンプルを使用したことに起因するいかなる損害も投稿者、およびフォーラムスタッフはその責めを負いません。使用者のリスクの範疇でご使用下さい。
Copyright 1996-2002 Delphi Users' Forum
|