- お知らせ -
  • 当wikiのプログラムコードの表示を直してみました(ついでに長い行があると全体が下にぶっ飛ぶのも修正)。不具合があればBBSまでご連絡下さい。

なんか、googleで「PImpl」で検索するとトップに来てるんすけど・・・これはDelphi用な上に、Delphiだと意味が薄れる気が・・・。
大分、下に追いやられますた。google過疎地帯。

はじめに Edit

Singletonと、PImplってのを組み合わせるとよさげらしい。

結論 Edit

いきなり、結論ですが、
Delphiだと意味ナス。

元々、C++で、

  • ヘッダーに、privateメソッドや、メンバを置くのがいや
  • コンパイル速度を上げたい

のが理由ですので、
Delphiだと、ヘッダーと実装部くっついてるし意味ないというか、
コンパイル速度、速いし、というか。

コード例1 Edit

こんな感じでしょうか

TestImpl.dpr Edit

program TestImpl;

{$APPTYPE CONSOLE}

uses
  MemCheck in 'MemCheck.pas',
  SysUtils,
  TestUnit in 'TestUnit.pas';

begin
  THoge.Create;

  Hoge.Messgage := 'マゲ';
  Hoge.Print;

  Hoge.Messgage := Hoge.Messgage + 'マゲ';
  Hoge.Print;

{$WARNINGS OFF}
  if DebugHook <> 0 then Readln; // IDEでの起動時は一旦停止
{$WARNINGS ON}
end.

TestUnit.pas Edit

unit TestUnit;

interface

type
  THoge = class
  private
    procedure SetMessgage(const Value: string);
    function GetMessgage: string;
  public
    constructor Create;
    destructor Destroy; override;

    procedure Print;
    property Messgage: string read GetMessgage write SetMessgage;
  end;


function Hoge: THoge;


implementation

uses SysUtils;

type
  THogeImpl = class
  private
    FMessage: string;

    // Delphiは同ファイル内は、friend 関係なので全部privateでいいや
    procedure Print;
    procedure SetMessgage(const Value: string);
    function GetMessgage: string;
  end;

var
  FHoge: THoge = nil;
  FHogeImpl: THogeImpl = nil;


function Hoge: THoge;
begin
  Result := FHoge;
end;


{ THoge }

constructor THoge.Create;
begin
  FHoge := Self;
  FHogeImpl := THogeImpl.Create;
end;

destructor THoge.Destroy;
begin
  FreeAndNil(FHogeImpl);
  FHoge := nil;
  inherited;
end;

procedure THoge.Print;
begin
  FHogeImpl.Print;
end;

procedure THoge.SetMessgage(const Value: string);
begin
  FHogeImpl.SetMessgage(Value);
end;

function THoge.GetMessgage: string;
begin
  Result := FHogeImpl.GetMessgage;
end;

{ THogeImpl }

procedure THogeImpl.Print;
begin
  Writeln(FMessage);
end;

procedure THogeImpl.SetMessgage(const Value: string);
begin
  FMessage := Value;
end;

function THogeImpl.GetMessgage: string;
begin
  Result := FMessage;
end;

initialization
finalization
  FreeAndNil(FHoge);
end.

実行結果 Edit

マゲ
マゲマゲ

感想 Edit

ブリッジ処理面倒くせー!!

インターフェスにprivateがないのは気持ちがいい。
またDelphiだと、インターフェス部と実装部が同一ファイルなのに、
見せたくないprivateを、インターフェスに書かなくていいのはGood。

でも、property をインターフェスに入れる場合は、いやおうなしに、setXXXX, getXXXX書く必要あるんだなー。この辺は、Delphi の interface 使っても起こることだし仕方ないか。

コンパイル速度に関しては、10万行程度のプロジェクトだと、効果はわかりませんでした。(Delphiの差分コンパイル早すぎ・・・)

コード例2 Edit

上記の

THoge.Create;

Hoge.Messgage := 'マゲ';
Hoge.Print;

THoge.Create; がうざい時は、

function Hoge: THoge;
begin
  if FHoge = nil then
    THoge.Create;
  Result := FHoge;
end;

とするとよいかと。
DelphiのVCLでも使われている方法です(Printersとか、で)。


  • Bridgeがウザイのは、委任(implements)でなんとかならんものか -- TOBY 2004-01-25 (日) 19:00:48
  • Createが隠せない(上位クラスで公開されているものは、隠蔽できないというDelphiの仕様)ために、THogeが生成出来てしまうのはどうしよう・・・ -- TOBY 2004-02-01 (日) 23:47:16
  • delphiはデフォルトでpimplだからコンパイルは早くならんのとちゃいますか -- pimpl? 2007-08-24 (金) 18:06:12
  • そうまもしんないす(汗) -- TOBY 2007-08-30 (木) 04:11:45


Front page   Edit Freeze Diff Backup Upload Copy Rename Reload   New Pages Search Recent changes   Help   RSS of recent changes
Last-modified: 2007-11-22 Thu 11:37:14 JST (3649d)