소스: 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 |