Observer模式" />
Delphi中的Observer模式在基本Observer模式進(jìn)行了擴(kuò)展。更多Observer模式的資料請(qǐng)參 [Gam+, pages 293..303]
定義一個(gè)對(duì)象間的一種一對(duì)多的依賴關(guān)系,當(dāng)一個(gè)對(duì)象狀態(tài)發(fā)生變化時(shí),所有依賴于它的對(duì)象者得到通知并自動(dòng)更新
將一個(gè)系統(tǒng)分割成一系列相互協(xié)作的類有一定的副作用:必須給護(hù)相關(guān)對(duì)象間的一致性。我們不希望為了維擴(kuò)一致性而使各類緊密耦合,因?yàn)檫@樣降低了它們的重用性。[Gam+, p293].
Delphi的事件(實(shí)際的方法地址)讓你有一個(gè)處理這些問題的好的結(jié)構(gòu),事件讓你消除耦合并更好的耦合,比如:事件TButton.OnClick被分派去完成相關(guān)的工作。但類并不保存對(duì)事件句柄的引用。在observer模式中,分派事件的類稱為目標(biāo)對(duì)象(subject),而控制事件的類稱為觀察者(observer)
所在Delphi的事件更好的消除類的耦合,如果你想對(duì)多個(gè)事件進(jìn)行控制,引用observer模式,你可以進(jìn)立一對(duì)多的通知機(jī)制。一個(gè)目標(biāo)可以有任意多個(gè)觀察者。所有的觀察者都會(huì)目標(biāo)的狀態(tài)改變時(shí)接受通知。觀察者接到通知后,立即查詢目標(biāo)對(duì)象,以保持與目對(duì)象的同步。
這種交互也稱為發(fā)布―訂閱,目標(biāo)是通知的發(fā)布者。它發(fā)現(xiàn)通知時(shí)并不需要知道誰是它的觀察者。可以有任意數(shù)目觀察者訂閱并接收通知。
這個(gè)observer模式應(yīng)用會(huì)帶給你Delphi事件機(jī)制在處理類耦合優(yōu)勢(shì)。一對(duì)多的結(jié)構(gòu)通過registering和un-registering來注冊(cè)觀察者。一對(duì)多的機(jī)制實(shí)際應(yīng)用在的迭代器的基礎(chǔ)。
假設(shè)你有一個(gè)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;
有上面的接口中:
? 一個(gè)注冊(cè)機(jī)制用于為Tsubject注冊(cè)觀察者。
¨ FObservers: TList;存貯已注冊(cè)的觀察者。
¨ RegisterObserver(..)用于注冊(cè)觀察者,并增加到Fobservers。
¨ UnregisterObserver(..)用于注消觀察者,并從Fobservers移去相關(guān)對(duì)象。
? observer模式還需創(chuàng)建一個(gè)新的類TSubjectObserver
¨ 此類為Tcomponent的后代。
¨ .一個(gè)Enabled屬性設(shè)置觀察的開與關(guān)。.
下面的observer模式的實(shí)際應(yīng):
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;
上觀的實(shí)現(xiàn)支持了對(duì)觀察者的注冊(cè)部分。那一對(duì)多通知機(jī)制在哪里呢。實(shí)際的一對(duì)多通知應(yīng)用,你可以為Tsubject定義一個(gè)Change方法來通知它的注冊(cè)的觀察者,觀察者可以定義一個(gè)OnChange的事件屬性來處理調(diào)度。代碼如下:
type
TSubject = class (TObject)
private
FObservers: TList;
protected
» procedure Change; {調(diào)用此方法來分派通知}
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;
在上面的實(shí)現(xiàn)代碼中:
? Tsubject的Change方法迭代所有注冊(cè)的觀察者,并調(diào)用每個(gè)觀察者的Change方法,一個(gè)對(duì)多通知的實(shí)現(xiàn)。
? 觀察者的Enabled屬性決定它是或接受通知
? TsubjectObserver的OnChange事件真正的處理同步等操作。
正在組織
//很多摘自《設(shè)計(jì)模式》
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注