お知らせ

電子会議

ライブラリ

パレット

Delphi FAQ検索

Delphi FAQ一覧

サンプル蔵





FDelphi FAQ
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