示例:拉模型(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.