設計模式、用Delphi描述-->Lock pattern (轉)

worldblog發表於2007-12-10
設計模式、用Delphi描述--&gtLock pattern (轉)[@more@]

 

Lock pattern

起源:namespace prefix = o ns = "urn:schemas--com::office" />

lock pattern是中 TStrings資料控制的基礎。在本段後面將例舉部分Tstrings、TstringList的程式碼

目的

為類提供一個臨時的訪問鎖控制機制

動機

我們經常發現一個經常排程一個返回更改結果的通知。被排程的物件必須控制其內部狀態,以同步物件資料。如果同時對一個物件進行多個更改操作,將會產生多個通知併產生一個併發的操作。此時在你的類中加入一個lock pattern的,從面提供一個臨時鎖控制機。從而避免不必要的通知。

我們透過Tbag類來學習:

類TBag提供了collection的行為。每次更改,Tbag將排程OnChange事件。如果我們一次對Tbag加入多個物件,你將得到多個更改通知。一個圖形可能會進行多次重新整理操作。引入lock pattern後,在加入物件前開啟Tbag的鎖,操作完後關閉鎖。如此,我將得到單一的更改通知。更好的辦法是加入一個標誌,比如:FUpdating

應用

以下是Tbag類部分程式碼: (僅顯示部分相關程式碼)

 

type

  TBag = class (T)

  private

  FLockCnt: Integer;

  protected

  function Locked: Boolean;

  procedure SetLocking(Updating: Boolean);

  public

  procedure Lock;

  procedure UnLock;

  end;

 

implementation

 

procedure TBag.Lock;

begin

  Inc(FLockCnt);

  if FLockCnt = 1 then SetLocking(False);

end;

 

function TBag.Locked: Boolean;

begin

  Result := (FLockCnt <> 0);

end;

 

procedure TBag.SetLocking(Updating: Boolean);

begin

end;

 

procedure TBag.UnLock;

begin

  Dec(FLockCnt);

  if FLockCnt = 0 then SetLocking(True);

end;

 

Tbag說明:

·  FlockCnt儲存鎖機制的內部狀態。FLockCnt = 0表示其處於非鎖狀態,其它值都表示其處於鎖定狀態。類Tbag透過Lock與Unlock來設定它的值。

·  Lock與Unlock提供了鎖的介面,每一次都將引起鎖的關態變化,並呼叫SetLocking方法。

·  SetLocking方法中有一個Updating的引數,Lock呼叫的引數為False,而Unlock呼叫的引數為True。對了,你可以在方法中插入一引起其它的程式碼,分配給它更多的操作表示它的鎖狀態的更改。.

·  Locked 返回類的鎖狀態。

注意:Lock、 Unlock必須同時使用,從而避免類保持在鎖狀態。明智的方法是使用try..finally塊來保持Lock、 Unlock的同時呼叫。

 

一個典型的應用例子:

 

procedure TBag.Add(Item: Pointer);

begin

  { Add Item to internal structure }

  Change;

end

 

procedure TBag.AddItems(Items: TList);

begin

  Lock;

  { Add multiple items }

  try

  for I := 0 to Items.Count - 1 do

  Add(Items[I]);

  finally

  { use try..finally to make sure Unlock is called }

  Unlock;

  end;

end;

 

procedure TBag.Change;

begin

  if not Locked then

  if Assigned(FOnChange) then FOnChange(Self);

end;

 

procedure TBag.SetLocking(Updating: Boolean);

begin

  if Updating then { Bag has become unlocked }

  Change;

end;

Delphi例項:TString、TstringList

TStrings = class(TPersistent)

  private

FUpdateCount: Integer;

  Protected

procedure (Index1, Index2: Integer); virtual;

procedure SetUpdateState(Updating: Boolean); virtual;

public

  procedure BeginUpdate;

  procedure EndUpdate;

procedure Changed; virtual;

  procedure Changing; virtual;


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-990946/,如需轉載,請註明出處,否則將追究法律責任。

相關文章