DelFusa Blog 総本山

プログラミングの話題とかです。

NEW | PAGE-SELECT | NEXT

≫ EDIT

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

| スポンサー広告 | --:-- | comments(-) | trackbacks(-) | TOP↑

≫ EDIT

イベントデリゲートメソッドリストの実装


    ∧,,∧  夏は冷え茶で
   ミ,,゚Д゚彡
    ミ つ旦)
  @と,,,~),,~)  旦
]]]]]]]]]]]]]]]]]]]]]]]]]]]]

では落ち着いて、冷え茶でも飲みながら。


実は、TNotifyEventManagerの実装は目が飛び出るくらい・・・

簡単です。


TNotifyEventList という、イベントを保持するリストクラスを使ってイベントリストを管理しているだけです。イベントトリガーが呼び出されたら、登録されているイベントを呼び出すだけですね。

────────────────────
 TNotifyEventManager = class(TObject)
 private
 protected
  { protected 宣言 }
 public
  EventList: TNotifyEventList;
  procedure EventTrigger(Sender: TObject);
  constructor Create;
  destructor Destroy; override;
 published
 end;

{ TNotifyEventmanager }

constructor TNotifyEventmanager.Create;
begin
 EventList := TNotifyEventList.Create;
end;

destructor TNotifyEventmanager.Destroy;
begin
 EventList.Free;
 inherited;
end;

procedure TNotifyEventmanager.EventTrigger(Sender: TObject);
var
 I: Integer;
begin
 for I := 0 to EventList.Count - 1 do
 begin
   EventList.Items[I](Sender);
 end;
end;
────────────────────
続いて、TNotifyEventListの実装です。

コンパイラ指令のincludeを使っているので、あまり見かけないコードですが、TEventList というクラスをTNotifyEventListと名前を変更しているだけです。TEventListで管理される、TEventをTNotifyEventに割り当てています。

コンパイラ指令のIncludeの使い方がよくわからない方は、DelphiTechnicに載っているのでそちらをどうぞ。
────────────────────
unit NotifyEventList;

interface

uses
 Classes, //TList / TNotifyEvent
 Types; //TPoint

type
 TEvent = TNotifyEvent;

////////////////////////////////////////////////////////////
{$include EventList.inc.pas}
////////////////////////////////////////////////////////////

 TNotifyEventList = TEventList ;

implementation

////////////////////////////////////////////////////////////
{$include EventList.inc.pas}
////////////////////////////////////////////////////////////

initialization
finalization
end.
────────────────────
このような実装になっている理由は、TNotifyEvent に対する TNotifyEventList を作るのと同じように、様々なイベントに対してT○○EventListを作りたいので、主な処理をEventList.inc.pasファイルに書いています。

この行
 TEvent = TNotifyEvent;
と、この行
 TNotifyEventList = TEventList ;

これをTNotifyEventではなく、別のイベントに割り当てて、別名で保存すれば、どんなイベントのリストを作ることも楽々です。


では、EventList.inc.pasの実装です。

ここでもまた、コンパイラ指令のincludeを使っています。
────────────────────
////////////////////////////////////////////////////////////
{$ifndef EventList}
{$define EventList}
// interface
////////////////////////////////////////////////////////////

 TRecord = TEvent;

////////////////////////////////////////////////////////////
{$include RecordList.inc.pas}
////////////////////////////////////////////////////////////

 TEventList = TRecordList;

////////////////////////////////////////////////////////////
{$else}
// implementation
////////////////////////////////////////////////////////////

function RecordEqual(const Value1, Value2: TRecord): Boolean; forward;

////////////////////////////////////////////////////////////
{$include RecordList.inc.pas}
////////////////////////////////////////////////////////////

//-------------------------------
//メソッドが一致するかどうか調べる関数
function SameMethod(const A, B: TMethod): Boolean;
begin
 if (A.Code = B.Code) and (A.Data = B.Data) then
  Result := True
 else
  Result := False;
end;

function RecordEqual(const Value1, Value2: TRecord): Boolean;
begin
 if SameMethod(TMethod(Value1), TMethod(Value2)) then
 begin
  Result := True;
 end else
 begin
  Result := False;
 end;
end;

////////////////////////////////////////////////////////////
{$endif}
////////////////////////////////////////////////////////////

────────────────────
Record型のListを実現するためのRecordList.inc.pasを拡張して、Event用のListを実現しているコードです。基本的にはRecordEqualメソッドを実装しているだけですね。

RecordEqualが実装されているので
RecordListの IndexOfによってメソッド検索もできるようになっています。

RecrdList.inc.pasについては、Delphiライブラリを探してみてください。


『シンプルイズベスト。』という格言があります。


このイベントデリゲート。使ってみても、作ってみても、実際に実装してみるとかなりあっさりシンプル。

ですが、もうひとつの格言があります。

『複雑なものをシンプルにするのは超難しい』


そ。簡単そうに見えて、実はいろいろ根回しもしているわけですよ。頭は使っているわけです。


もしデザインパターンだか、なんだか、様々な実装場面で、クラス構成、クラス設計を考えているうちに、「.NETのイベントデリゲートなら、簡単に実装できるのに!」なんて思える場面のコードがあるのでしたら、この仕組みを使って、 Delphi Win32 でも簡単に実現できてしまえることになってしまいました。

他言語でもかまわないので、アスペクト指向のよい事例などあって何かこうしたら良さそうな事例があれば教えてください。

機会があって、それを実装できるような実力があれば試してみますよ。

ではでは。また次回。

次回は、Delphi Prism の事前条件、事後条件、requreとensureのWin32での拡張実装です。

ちなみに俺のメイン環境はいまだにD2007でございますので、それでの実装です。
スポンサーサイト

| 未分類 | 23:21 | comments:1 | trackbacks(-) | TOP↑

COMMENT

もしかすると、このメソッドリスト、引数をarray of variantで実装すれば、全イベントの型に対して実装しなくても、上からうまい具合にラッピングして使えるのではないかと。

| ミ・д・彡 | 2010/07/30 12:55 | URL | ≫ EDIT















非公開コメント

PREV | PAGE-SELECT | NEXT

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。