《GOF设计模式》—中介者 (MEDIATOR)—Delphi源码示例:Colleague—Mediator通信(使用观察者模式)

    技术2022-05-20  62

    示例: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.


    最新回复(0)