Delphi中的Observer模式在基本Observer模式進行了擴展。更多Observer模式的資料請參 [Gam+, pages 293..303]<?XML:namespace prefix = o ns = "urn:schemas-microsoft-com:office:Office" />
定義一個對象間的一種一對多的依賴關系,當一個對象狀態發生變化時,所有依賴於它的對象者得到通知並自動更新
將一個系統分割成一系列相互協作的類有一定的副作用:必須給護相關對象間的一致性。我們不希望為了維擴一致性而使各類緊密耦合,因為這樣降低了它們的重用性。[Gam+, p293].
Delphi的事件(實際的方法地址)讓你有一個處理這些問題的好的結構,事件讓你消除耦合並更好的耦合,比如:事件TButton.OnClick被分派去完成相關的工作。但類並不保存對事件句柄的引用。在observer模式中,分派事件的類稱為目標對象(subject),而控制事件的類稱為觀察者(observer)
所在Delphi的事件更好的消除類的耦合,如果你想對多個事件進行控制,引用observer模式,你可以進立一對多的通知機制。一個目標可以有任意多個觀察者。所有的觀察者都會目標的狀態改變時接受通知。觀察者接到通知後,立即查詢目標對象,以保持與目對象的同步。
這種交互也稱為發布―訂閱,目標是通知的發布者。它發現通知時並不需要知道誰是它的觀察者。可以有任意數目觀察者訂閱並接收通知。
這個observer模式應用會帶給你Delphi事件機制在處理類耦合優勢。一對多的結構通過registering和un-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;
在上面的實現代碼中:
? Tsubject的Change方法迭代所有注冊的觀察者,並調用每個觀察者的Change方法,一個對多通知的實現。
? 觀察者的Enabled屬性決定它是或接受通知
? TsubjectObserver的OnChange事件真正的處理同步等操作。
正在組織
//很多摘自《設計模式》