소스: http://code.google.com/p/ryulib4delphi/source/browse/trunk/XE2/ObserverList.pas
개요
"Observer Pattern" 과 RTTI 를 응용한 클래스입니다.
다른 점은, 메시지를 수신 받는 객체에서 메시지 안에 있는 문자열과 같은 이름을 가진 메소드가 자동으로 실행 된다는 것 입니다.
예제
unit Unit1;
interface
uses
ObserverList, ValueList,
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
btSendMsg: TButton;
procedure FormCreate(Sender: TObject);
procedure btSendMsgClick(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
FObserverList : TObserverList;
public
published
procedure rp_TestMsg(AParams:TValueList);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.btSendMsgClick(Sender: TObject);
var
Params : TValueList;
begin
Params := TValueList.Create;
try
Params.Values['Code'] := 'TestMsg';
Params.Values['Msg'] := 'Hi!!';
Params.Integers['Year'] := 2013;
FObserverList.AsyncBroadcast(Params);
finally
Params.Free;
end;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
FObserverList.Remove(Self);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
FObserverList := TObserverList.Create(Self);
FObserverList.Add(Self);
end;
procedure TForm1.rp_TestMsg(AParams: TValueList);
begin
ShowMessage(AParams.Values['Msg']);
ShowMessage(AParams.Values['Year']);
end;
end.
5: ObserverList 유닛과 ValueList 유닛을 추가해야 합니다.
53: ObserverList 객체를 생성합니다.
54: Form1 자신을 ObserverList 에 등록합니다. 이제부터 메시지는 자동으로 수신됩니다.
48: 더 이상 메시지 수신이 필요하지 않은 경우에는 Remove 메소드를 통해서 수신 등록을 해제합니다.
29-44: 버턴이 클릭되었을 때, 메시지를 전송하는 코드입니다. ObserverList 에 등록 된 모든 객체에게 메시지를 전송하게 됩니다. 예제에서는 Form1 하나만이 등록되어 있어, Form1 에게만 메시지가 전송됩니다.
TValueList 는 TStringList 를 상속 받아 만들어진 클래스입니다.
35: "Code" 라는 이름으로 "TestMsg" 를 입력하였습니다. 이것은 메시지의 이름입니다. 메시지를 수신 받은 객체는 이 메시지 이름 앞에 "rp_"를 붙인 메소드를 published 에 선언하여 구현하시면 됩니다. 예제에서는 19: 라인에 메소드가 선언되어 있습니다.
37-38: 라인에서는 메시지에 추가적으로 파라메터를 보태서 전송하기 위해 데이터를 추가하고 있습니다.
40: 라인에서는 해당 메시지 정보가 있는 Params 객체를 모든 메시지 수신 객체에게 전송합니다. 비동기적인 방식으로 전송되기 때문에 바로 전달된다는 보장은 없습니다. 바로 전송하기 위해서는 Broadcast(Params) 메소드를 사용하시면 됩니다.
57-61: 라인에서는 전달 받은 메시지를 수신하여 실행 할 메소드가 구현되어 있습니다. 메시지 이름이 "TestMsg" 이기 때문에 메소드 이름은 "rp_TestMsg" 인것을 유의하시기 바랍니다. rp_TestMsg 메소드를 실행하는 코드는 아무 곳에도 없지만, 단지 메시지를 전송하는 것만으로 이름이 같은 메소드가 자동으로 실행되는 것 입니다.
만약 ObserverList 에 등록된 객체가 더 있다면, 해당 객체들도 메시지를 수신하게 됩니다. 해당 객체들에 published 에 rp_TestMsg 메소드가 구현되어 있다면, 그 메소드들도 당연히 실행됩니다.
객체들은 메소드 구현을 하거나 하지 않는 것으로 해당 메시지를 수신 할 것인지 말 것인지를 결정 할 수가 있습니다.
| LazyRelease - 메모리 해제를 뒤로 미루기 (0) | 2012.10.21 |
|---|---|
| JsonFormatter unit 추가 (0) | 2012.08.02 |
| A Simple thread class that can change stack size for it (0) | 2012.07.01 |
| DynamicQueue unit (0) | 2012.06.28 |
| ThreadPool (0) | 2012.01.18 |