상세 컨텐츠

본문 제목

ObserverList

RyuLib/RyuLib for Delphi

by ryujt 2010. 12. 13. 17:11

본문

소스: http://code.google.com/p/ryulib4delphi/source/browse/trunk/XE2/ObserverList.pas

예제: http://bit.ly/VcPLIE



개요

"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 메소드가 구현되어 있다면, 그 메소드들도 당연히 실행됩니다.  

객체들은 메소드 구현을 하거나 하지 않는 것으로 해당 메시지를 수신 할 것인지 말 것인지를 결정 할 수가 있습니다.






'RyuLib > RyuLib for Delphi' 카테고리의 다른 글

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

관련글 더보기