欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Delphi VCL Framework中的Notify模式

程序员文章站 2022-06-07 08:57:39
...

在Delphi中进行UI设计时,我们会在Form上放置许多的组件,当我们更改窗体的某些属性时,其上所有组件的相应属性都会随着发生改变,这是如何实现的呢?这里就使用到了Delphi VCL Framework中使用最多的一种设计模式 -- Notify模式。

Notify模式最经常发生的应用就是在容器类中的应用。由于容器类管理了许多子类对象,因此客户程序代码可能希望一次操作对所有容器类管理的子类对象进行特定的工作。在这种需求应用中就可以使用Notify模式,客户程序代码只需要传送事件给容器类,而容器类在接收到这个事件之后再逐一的通知它所管理的子类对象。

Delphi中所有组件都是从TComponent类继承而来的,只需要在这个类中实现通知模式,那么它所有的子类对象便都具备了这种模式能力。我们剖析一下Delphi是如何实现这个模式的。

首先打开TComponent所在的单元文件Classes.pas,查找到TComponent类的定义,我们可以看到如下代码(注意加粗的部分)

Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 TComponent=class(TPersistent,IInterface,IInterfaceComponentReference)
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 
private
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 .......
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 FFreeNotifies:TList;
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 .......
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 procedureRemoveNotification(AComponent:TComponent);
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 .......
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 
protected
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 .......
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 procedureNotification(AComponent:TComponent;
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 Operation:TOperation);
virtual;
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 .......
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 
public
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 constructorCreate(AOwner:TComponent);
virtual;
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 destructorDestroy;
override;
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 .......
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 procedureFreeNotification(AComponent:TComponent);
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 procedureRemoveFreeNotification(AComponent:TComponent);
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 .......
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 published
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 propertyName:TComponentNamereadFNamewriteSetNamestoredFalse;
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 propertyTag:LongintreadFTagwriteFTag
default0;
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 end;

当一个组件被创建时,会通过FreeNotification方法将其添加到父组件的FFreeNotifies列表中,确保父组件发生变化时自己能够被通知到;同时父组件也被添加到自己的FFreeNotifies列表中,确保自己发生变化时能够通知到父组件。

Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 procedureTComponent.FreeNotification(AComponent:TComponent);
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 begin
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 
if(Owner=nil)or(AComponent.Owner<>Owner)then
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 begin
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 
//Neveracquireareferencetoacomponentthatisbeingdeleted.
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 
assert(not(csDestroyingin(ComponentState+AComponent.ComponentState)));
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 
ifnotAssigned(FFreeNotifies)thenFFreeNotifies:=TList.Create;
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 
ifFFreeNotifies.IndexOf(AComponent)<0then
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 begin
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 FFreeNotifies.Add(AComponent);
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 AComponent.FreeNotification(Self);
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 end;
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 end;
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 Include(FComponentState,csFreeNotification);
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 end;

FreeNotification方法对应的有一个RemoveFreeNotification方法,此方法是将已经建立关联关系的组件从彼此的FFreeNotifies列表中删除,取消了由FreeNofifies建立的关联。

Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 procedureTComponent.RemoveFreeNotification(AComponent:TComponent);
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 begin
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 RemoveNotification(AComponent);
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 AComponent.RemoveNotification(Self);
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 end;

当一个组件发生变化时,则会调用Notification方法通知FreeNofifies列表中所有的组件。

Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 procedureTComponent.Notification(AComponent:TComponent;
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 Operation:TOperation);
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 var
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 I:Integer;
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 begin
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 
if(Operation=opRemove)and(AComponent<>nil)then
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 RemoveFreeNotification(AComponent);
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 
ifFComponents<>nilthen
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 begin
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 I:
=FComponents.Count-1;
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 
whileI>=0do
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 begin
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 TComponent(FComponents[I]).Notification(AComponent,Operation);
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 Dec(I);
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 
ifI>=FComponents.Countthen
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 I:
=FComponents.Count-1;
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 end;
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 end;
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 end;

Notification方法对应的亦有一个私有的RemoveNotification方法,此方法的作用是将与之关联的组件从FFreeNotifies列表中去除,如果没有与之关联的组件,则销毁FFreeNotifies列表。

Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 procedureTComponent.RemoveNotification(AComponent:TComponent);
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 begin
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 
ifFFreeNotifies<>nilthen
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 begin
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 FFreeNotifies.Remove(AComponent);
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 
ifFFreeNotifies.Count=0then
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 begin
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 FFreeNotifies.Free;
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 FFreeNotifies:
=nil;
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 end;
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 end;
Delphi VCL Framework中的Notify模式
            
    
    博客分类: Delphi delphi设计模式 end;

小结一下

从TComponent类的定义代码可以看出Delphi只将FreeNotificationRemoveFreeNotification方法公开出来,是希望我们利用这两个方法在建立和取消组件间的关联;而将Notification方法定义为受保护的虚方法,则为我们提供了改写通知组件时执行附加操作的机会。

使用时机

  • 在设计容器类时程序员想定义和外界一致的交互接口
  • 需要对一群组件执行预定义好的特定工作

应用举例

在编写MIS软件时,会涉及到一些单据的填写,就以进货单为例。在一张进货单中会填写货品的单价、价格,我们希望在这两个字段的值发生变化时系统能够自动的计算出最新的总价。在这里,我们就可以借鉴Notify模式,将数量与单价加入到彼此的通知列表中,并编写通知处理方法如上面讲到的Notification方法。这样,无论单价还是数量发生变化都会触发通知事件,进而达到重新计算总价的目的。

个人拙见,还望各位斧正。

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关标签: delphi 设计模式