示例:Colleague—Mediator通信(使用观察者模式) 说明: 当一个感兴趣的事件发生时,Colleague必须与其Mediator通信。一种实现方法是使用观察者模式(Observer),将Mediator实现为一个Observer,各Colleague作为Subject,一旦其状态改变就发送通知给Mediator。Mediator作出的响应是将状态改变的结果传播给其他的Colleague。 代码: unit uObserver; interface uses classes; type TObserver = class; TSubjectData = class protected FObservers: TList; FNotifyEnabled: Boolean; procedure SetEnableNotify(AEnable: Boolean); public constructor Create; destructor Destroy; override; //--- procedure Attach(AObserver: TObserver); procedure Detach(AObserver: TObserver); //--- property NotifyEnabled: Boolean read FNotifyEnabled write SetEnableNotify; end; TObserver = class private FDatas: TList; public constructor Create; destructor Destroy; override; //--- procedure Attach(AData: TSubjectData); procedure Detach(AData: TSubjectData); //--- procedure Update(AData: TSubjectData); virtual;abstract; end; implementation constructor TSubjectData.Create; begin FObservers := TList.Create; end; destructor TSubjectData.Destroy; //--- procedure _DetachAll; var i:Integer; begin with FObservers do begin for i := Count - 1 downto 0 do TObserver(Items[i]).Detach(self); end; end; begin _DetachAll; FObservers.Free; //--- inherited; end; procedure TSubjectData.Attach(AObserver: TObserver); begin FObservers.Add(AObserver); end; procedure TSubjectData.Detach(AObserver: TObserver); begin FObservers.Remove(AObserver); end; procedure TSubjectData.SetEnableNotify(AEnable: Boolean); //--- procedure _NotifyObservers; var i: integer; begin with FObservers do begin for i := 0 to Count - 1 do TObserver(Items[i]).Update(self); end; end; begin FNotifyEnabled := AEnable; if FNotifyEnabled then _NotifyObservers; end; constructor TObserver.Create; begin FDatas := TList.Create; end; destructor TObserver.Destroy; //--- procedure _DetachAll; var i:Integer; begin with FDatas do begin for i := Count - 1 downto 0 do TSubjectData(Items[i]).Detach(self); end; end; begin _DetachAll; FDatas.Free; //--- inherited; end; procedure TObserver.Attach(AData: TSubjectData); begin FDatas.Add(AData); AData.Attach(self); end; procedure TObserver.Detach(AData: TSubjectData); begin FDatas.Remove(AData); AData.Detach(self); end; end. unit uMediatorObserver; interface uses SysUtils, Dialogs,uObserver; type TMediator = class; TColleague = class(TSubjectData) end; TConcreteColleague1 = class(TColleague) private FValue: Integer; procedure SetValue(const Value: Integer); public property Value: Integer read FValue write SetValue; end; TConcreteColleague2 = class(TColleague) private FValue: Integer; procedure SetValue(const Value: Integer); public property Value: Integer read FValue write SetValue; end; TMediator = class(TObserver) end; TConcreteMediator = class(TMediator) private FColleague1: TConcreteColleague1; FColleague2: TConcreteColleague1; public constructor Create; destructor Destroy; override; //--- procedure Update(AData: TSubjectData); override; procedure Calc; end; procedure Test; implementation procedure Test; var AMediator: TConcreteMediator; begin AMediator := TConcreteMediator.Create; AMediator.Calc; AMediator.Free; end; procedure TConcreteColleague1.SetValue(const Value: Integer); begin FValue := Value; //--- self.NotifyEnabled := true; end; procedure TConcreteColleague2.SetValue(const Value: Integer); begin FValue := Value; //--- self.NotifyEnabled := true; end; procedure TConcreteMediator.Calc; begin FColleague1.Value := 1; end; procedure TConcreteMediator.Update(AData: TSubjectData); begin if AData = FColleague1 then FColleague2.Value := FColleague1.Value + 2 else if AData = FColleague2 then ShowMessage(IntToStr(FColleague2.Value)); end; constructor TConcreteMediator.Create; begin inherited; //--- FColleague1 := TConcreteColleague1.Create; self.Attach(FColleague1); //--- FColleague2 := TConcreteColleague1.Create; self.Attach(FColleague2); end; destructor TConcreteMediator.Destroy; //--- procedure _Free(AColleague: TColleague); begin if AColleague <> nil then AColleague.Free; end; begin _Free(FColleague1); _Free(FColleague2); //--- inherited; end; end.