Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1087203
  • 博文数量: 282
  • 博客积分: 10865
  • 博客等级: 上将
  • 技术积分: 2480
  • 用 户 组: 普通用户
  • 注册时间: 2006-05-12 12:35
文章存档

2017年(1)

2016年(3)

2015年(10)

2014年(12)

2013年(5)

2012年(10)

2011年(29)

2010年(3)

2008年(13)

2007年(92)

2006年(104)

我的朋友

分类: 项目管理

2007-09-20 23:36:37

模式

起源

Delphi中的Observer模式在基本Observer模式进行了扩展。更多Observer模式的资料请参 [Gam+, pages 293..303]

目的

定义一个对象间的一种一对多的依赖关系,当一个对象状态发生变化时,所有依赖于它的对象者得到通知并自动更新

动机

将一个系统分割成一系列相互协作的类有一定的副作用:必须给护相关对象间的一致性。我们不希望为了维扩一致性而使各类紧密耦合,因为这样降低了它们的重用性。[Gam+, p293].

Delphi的事件(实际的方法地址)让你有一个处理这些问题的好的结构,事件让你消除耦合并更好的耦合,比如:事件TButton.OnClick被分派去完成相关的工作。但类并不保存对事件句柄的引用。在observer模式中分派事件的类称为目标对象(subject),而控制事件的类称为观察者(observer

所在Delphi的事件更好的消除类的耦合如果你想对多个事件进行控制引用observer模式,你可以进立一对多的通知机制。一个目标可以有任意多个观察者。所有的观察者都会目标的状态改变时接受通知。观察者接到通知后,立即查询目标对象,以保持与目对象的同步。

这种交互也称为发布—订阅,目标是通知的发布者。它发现通知时并不需要知道谁是它的观察者。可以有任意数目观察者订阅并接收通知。

应用

这个observer模式应用会带给你Delphi事件机制在处理类耦合优势。一对多的结构通过registeringun-registering来注册观察者。一对多的机制实际应用在的迭代器的基础。

假设你有一个Tsubject类定义了有意义的行为。先看看一段observer模式的演示代码:

 

type

  TSubject = class (TObject)

  private

    FObservers: TList;

  public

    procedure RegisterObserver(Observer: TSubjectObserver);

    procedure UnregisterObserver(Observer: TSubjectObserver);

  end;

 

  TSubjectObserver = class (TComponent)

  private

    FEnabled: Boolean;

  published

    property Enabled: Boolean read FEnabled write FEnabled; default True;

  end;

 

有上面的接口中:

·      一个注册机制用于为Tsubject注册观察者。

¨    FObservers: TList;存贮已注册的观察者。

¨    RegisterObserver(..)用于注册观察者,并增加到Fobservers

¨    UnregisterObserver(..)用于注消观察者,并从Fobservers移去相关对象。

 

·      observer模式还需创建一个新的类TSubjectObserver

¨    此类为Tcomponent的后代。

¨    .一个Enabled属性设置观察的开与关。.

 

下面的observer模式的实际应:

 

procedure TSubject.RegisterObserver(Observer: TSubjectObserver);

begin

  if FObservers.IndexOf(Observer) = -1 then

    FObservers.Add(Observer);

end;

 

procedure TSubject.UnregisterObserver(Observer: TSubjectObserver);

begin

  FObservers.Remove(Observer);

end;

 

上观的实现支持了对观察者的注册部分。那一对多通知机制在哪里呢。实际的一对多通知应用,你可以为Tsubject定义一个Change方法来通知它的注册的观察者,观察者可以定义一个OnChange的事件属性来处理调度。代码如下:

type

  TSubject = class (TObject)

  private

    FObservers: TList;

  protected

»   procedure Change;     {调用此方法来分派通知}

  public

    procedure RegisterObserver(Observer: TSubjectObserver);

    procedure UnregisterObserver(Observer: TSubjectObserver);

  end;

 

  TSubjectObserver = class (TComponent)

  private

    FEnabled: Boolean;

»   FOnChange: TNotifyEvent;

  protected

»   procedure Change;

  published

    property Enabled: Boolean read FEnabled write FEnabled;

»   property OnChange: TNotifyEvent read FOnChange write FOnChange;

  end;

 

implementation

 

procedure TSubject.Change;

var

» Obs: TSubjectObserver;

» I: Integer;

begin

» for I := 0 to FObservers.Count - 1 do

» begin

»   Obs := FObservers[I];

»   if Obs.Enabled then Obs.Change;

» end;

end;

 

procedure TSubject.RegisterObserver(Observer: TSubjectObserver);

begin

  if FObservers.IndexOf(Observer) = -1 then

    FObservers.Add(Observer);

end;

 

procedure TSubject.UnregisterObserver(Observer: TSubjectObserver);

begin

  FObservers.Remove(Observer);

end;

 

procedure TSubjectObserver.Change;

begin

» if Assigned(FOnChange) then FOnChange(Self);

end;

 

在上面的实现代码中:

·      TsubjectChange方法迭代所有注册的观察者并调用每个观察者的Change方法一个对多通知的实现。

·      观察者的Enabled属性决定它是或接受通知

·      TsubjectObserverOnChange事件真正的处理同步等操作。

阅读(1385) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~