본문 바로가기
Delphi/문법

델파이(Delphi) 디자인패턴(Design pattern) 2탄

by MonoSoft 2021. 5. 31.
728x90
반응형

델파이(Delphi) 디자인패턴(Design pattern) 2탄

 

 

옵져버(Observer) 패턴

 

"Observer" 라는 단어를 영어사전에서 찾아 보면 아래와 같습니다.

 

Observer - 보는 사람, 목격자, 관찰자. 정찰병, 참관인

 

이런 여러가지 말이 나오는데 디자인패턴에서 통용되는 가장 적합한 

해석은 바로 "관찰자" 또는 "정찰병" 입니다. 

 

이 관찰자의 핵심적인 역활은 다음과 같습니다. 

 

1. 어떤 상황이 발생하는지 잘 관찰하는 것

 

2. 특정상황이 발생하면 그 사실을 꼭 알아야 하는 다른 대상들에게 전파해 주는 것

 

이런 개념이 개발에도 꼭 필요한 경우가 있습니다.

채팅프로그램이 Observe 패턴을 쓰는 가장 좋은 예입니다. 

채팅방에 10명의 대화자가 참가중인데 

이중에 누구든 글을 쓰면 다른 대화자들도 

그 내용을 볼수 있어야 하기 때문입니다.

 

Observe 패턴의 TObserve 클래스의 핵심기능은 다음과 같습니다.

 

1. TObserver 클래스는 전파대상들을 TList 에 보관한다.

 

2. 어떤 상황이 일어나면 TList 안에 보관된 전파대상의 특정 이벤트를 발생시켜 준다. 

 

그럼 아래의 간단한 예제를 보도록 하겠습니다. [예제는 첨부파일에 있습니다.]

아래 예제는 어떤 TObsv 클래스의 인스턴스가 전파대상들을 보관하고 있다가

그 대상들에게 특정이벤트를 통고해 주는 역활을 합니다. 


참고로 TObsv 라는 클래스 명칭을 원래는 TObserver 라고 쓰고 싶었는데, 이렇게 쓰니깐

Windows Defender 가 내 테스트 프로그램을 바이러스로 오인하는 

어처구니 없는 상황이 발생하였습니다.


이 문제를 해결하기 위해 클래스 이름을 TObsv 라고 밖에 할 수 없었음을 양해바랍니다.

아마도 바이러스 프로그램의 클래스 명칭들이 Observer 로 되어 있는 경우가 많은 모양입니다. 

참고들 하시기 바랍니다.


unit Unit1;

 

interface

 

uses

  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

  Dialogs, StdCtrls, ExtCtrls;

 

type

  TObsv = class(TObject)

  private

    FBtns : TList; //전파 대상자들을 TList 에 보관

  protected

    procedure   SpreadEventToBtns; //전파대상자들의 특정 이벤트 발생 시켜줌.

  public

    constructor Create;

    destructor  Destroy;override;

    procedure   RegBtn( aBtn : TButton); //전파 대상자 추가

    procedure   UnRegBtn( aBtn : TButton);//전파 대상자 삭제

  end;


  TForm1 = class(TForm)

    btnObsv: TButton;

    btn1: TButton;

    btn2: TButton;

    Bevel1: TBevel;

    Bevel2: TBevel;

    Bevel3: TBevel;

    Bevel4: TBevel;

    Bevel5: TBevel;

    btn3: TButton;

    edtText: TEdit;

    procedure FormDestroy(Sender: TObject);

    procedure btnObsvClick(Sender: TObject);

    procedure btn1Click(Sender: TObject);

    procedure btn2Click(Sender: TObject);

    procedure btn3Click(Sender: TObject);

    procedure FormCreate(Sender: TObject);

  private

    { Private declarations }

  public

    { Public declarations }

  end;

 

var

  Form1: TForm1;

 

implementation


var

  sObsv : TObsv;


{$R *.dfm}


{ TObsv }


constructor TObsv.Create;

begin

  FBtns := TList.Create;

end;

 

destructor TObsv.Destroy;

begin

  FBtns.Free;

  inherited;

end;

 

procedure TObsv.RegBtn( aBtn : TButton );

begin

  if FBtns.IndexOf(aBtn) = -1 then FBtns.Add( aBtn );

end;


procedure TObsv.UnRegBtn( aBtn : TButton );

begin

  FBtns.Remove(aBtn);

end;


procedure TObsv.SpreadEventToBtns;//<= 이벤트 전파 [이 메서드가 Observer 패턴의 핵심입니다. ]

var

  i: Integer;

  aBtn: TButton;

begin

  for i := 0 to FBtns.Count - 1 do begin

    aBtn := FBtns[i];

    aBtn.OnClick(self);

  end;

end;


{Form}

 

procedure TForm1.FormCreate(Sender: TObject);

begin

  sObsv := TObsv.Create;

  sObsv.RegBtn( btn1 );

  sObsv.RegBtn( btn2 );

  sObsv.RegBtn( btn3 );

end;

 

procedure TForm1.FormDestroy(Sender: TObject);

begin

  sObsv.Free;

end;

 

procedure TForm1.btnObsvClick(Sender: TObject);

begin

  sObsv.SpreadEventToBtns;

end;

 

procedure TForm1.btn1Click(Sender: TObject);

begin

  btn1.Caption := edtText.Text + '의 필통';

end;

 

procedure TForm1.btn2Click(Sender: TObject);

begin

  btn2.Caption := edtText.Text + '의 연필';

end;

 

procedure TForm1.btn3Click(Sender: TObject);

begin

  btn3.Caption := edtText.Text + '의 지우개';

end;

 

end.

728x90
반응형

댓글