ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 设计模式、用Delphi描述-->Lock pattern (转)

设计模式、用Delphi描述-->Lock pattern (转)

原创 Linux操作系统 作者:gugu99 时间:2007-10-17 13:49:30 0 删除 编辑
设计模式、用Delphi描述-->Lock pattern (转)[@more@]

 

Lock pattern

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

lock pattern是Delphi中 TStrings数据更新控制的基础。在本段后面将例举部分Tstrings、TstringList的代码

目的

为类提供一个临时的访问锁控制机制

动机

我们经常发现一个对象经常调度一个返回更改结果的通知。被调度的对象必须控制其内部状态,以同步对象数据。如果同时对一个对象进行多个更改操作,将会产生多个通知并产生一个并发的操作。此时在你的类中加入一个lock pattern的模式,从面提供一个临时锁控制机。从而避免不必要的通知。

我们通过Tbag类来学习:

类TBag提供了collection的行为。每次更改,Tbag将调度OnChange事件。如果我们一次对Tbag加入多个对象,你将得到多个更改通知。一个图形组件可能会进行多次刷新操作。引入lock pattern后,在加入对象前打开Tbag的锁,操作完后关闭锁。如此,我将得到单一的更改通知。更好的办法是加入一个标志,比如:FUpdating

应用

以下是Tbag类部分代码: (仅显示部分相关代码)

 

type

  TBag = class (Tobject)

  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 Exchange(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/10748419/viewspace-977128/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
  • 博文量
    3122
  • 访问量
    2226369