示例:拉模型(pull model)
说明:
目标除最小通知外什么也不送出,而在此之后由观察者显式地向目标询问细节。
代码:
unit uPullModel;
interface
uses
SysUtils, Classes, Dialogs;
type
TSubjectState = record
A, B: Integer;
end;
TObserver = class;
TSubject = class
private
FObservers: TList;
public
constructor Create;
destructor Destroy; override;
//---
procedure Attach(AObserver: TObserver);
procedure Detach(AObserver: TObserver);
procedure Notify;
end;
TConcreteSubject = class(TSubject)
private
FState: TSubjectState;
function GetA: Integer;
function GetB: Integer;
procedure SetA(const Value: Integer);
procedure SetB(const Value: Integer);
public
property A: Integer read GetA write SetA;
property B: Integer read GetB write SetB;
end;
TObserver = class
public
procedure Update; virtual; abstract;
end;
TConcreteObserver = class(TObserver)
protected
FSubject: TSubject;
public
constructor Create(ASubject: TSubject);
destructor Destroy; override;
//---
procedure Update; override;
end;
procedure Test;
implementation
procedure Test;
var
ASubject: TConcreteSubject;
AObserver: TObserver;
begin
ASubject := TConcreteSubject.Create;
AObserver := TConcreteObserver.Create(ASubject);
try
ASubject.A := 1;
ASubject.B := 2;
ASubject.Notify;
finally
AObserver.Free;
ASubject.Free;
end;
end;
constructor TSubject.Create;
begin
FObservers := TList.Create;
end;
destructor TSubject.Destroy;
begin
FObservers.Free;
//---
inherited;
end;
procedure TSubject.Attach(AObserver: TObserver);
begin
FObservers.Add(AObserver);
end;
procedure TSubject.Detach(AObserver: TObserver);
begin
FObservers.Remove(AObserver);
end;
procedure TSubject.Notify;
var
i: integer;
begin
with FObservers do
begin
for i := 0 to Count - 1 do
TObserver(Items[i]).Update;
end;
end;
constructor TConcreteObserver.Create(ASubject: TSubject);
begin
FSubject := ASubject;
if FSubject <> nil then FSubject.Attach(self);
end;
destructor TConcreteObserver.Destroy;
begin
if FSubject <> nil then FSubject.Detach(self);
//---
inherited;
end;
procedure TConcreteObserver.Update;
begin
if FSubject is TConcreteSubject then
begin
with TConcreteSubject(FSubject) do
ShowMessage(IntToStr(A + B));
end;
end;
function TConcreteSubject.GetA: Integer;
begin
Result := FState.A;
end;
function TConcreteSubject.GetB: Integer;
begin
Result := FState.B;
end;
procedure TConcreteSubject.SetA(const Value: Integer);
begin
FState.A := Value;
end;
procedure TConcreteSubject.SetB(const Value: Integer);
begin
FState.B := Value;
end;
end.
《GOF设计模式》—观察者(OBSERVER)—Delphi源码示例:拉模型(pull model)
最新推荐文章于 2024-07-27 18:05:15 发布