示例:观察者接口 说明: (1)、定义 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。 (2)、结构 目标 Subject(目标):目标知道它的观察者。可以有任意多个观察者观察同一个目标。提供注册和删除观察者对象的接口。 ConcreteSubject(具体目标):将有关状态存入各ConcreteObserver对象。当它的状态发生改变时,向它的各个观察者发出通知。 观察者 Observer(观察者):为那些在目标发生改变时需获得通知的对象定义一个更新接口。 ConcreteObserver(具体观察者):维护一个指向ConcreteSubject对象的引用。存储有关状态,这些状态应与目标的状态保持一致。实现Observer的更新接口以使自身状态与目标的状态保持一致。 代码: unit uObserver2; interface uses SysUtils, Classes,Dialogs; type TSubject = class; TObserver = class public procedure Update; virtual; abstract; end; TConcreteObserver = class(TObserver) private FSubject: TSubject; FState: Integer; public constructor Create(ASubject: TSubject); destructor Destroy; override; //--- procedure Update; override; end; 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: Integer; function GetState: Integer; procedure SetState(const Value: Integer); public property State: Integer read GetState write SetState; end; procedure Test; implementation procedure Test; var ASubject: TConcreteSubject; AObserver: TObserver; begin ASubject := TConcreteSubject.Create; AObserver := TConcreteObserver.Create(ASubject); try ASubject.State := 123; finally AObserver.Free; ASubject.Free; end; end; constructor TSubject.Create; begin inherited; //--- 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 inherited Create; //--- FSubject := ASubject; FSubject.Attach(self); end; destructor TConcreteObserver.Destroy; begin FSubject.Detach(self); //--- inherited; end; procedure TConcreteObserver.Update; begin FState := TConcreteSubject(FSubject).State; ShowMessage(IntToStr(FState)); end; function TConcreteSubject.GetState: Integer; begin Result := FState; end; procedure TConcreteSubject.SetState(const Value: Integer); begin FState := Value; //--- Self.Notify; end; end.