Delphi的基于接口(IInterface)的多播监听器模式(观察者模式 )
2021-02-01 21:15
标签:虚拟 offset rri bsp 举例 nap array 对象 ext 本文来自:http://www.cnblogs.com/hezihang/p/6083555.html Delphi采用接口方式设计模块,可以降低模块之间的耦合,便于扩展和维护。本文提供一个实现基于接口(IInterface)方式的监听器模式(观察者模式、订阅者模式),实现一个自动多播器。 下面程序在Berlin下测试通过,其他Delphi版本未测试,未进行跨平台测试(应该可以支持) 1.prepare 在观察者模式中采用接口,可以将相关函数汇合为接口。 举例:假设我们窗口有一个TTreeView,用于显示应用中的对象,用户通过点击TreeView中的不同对象,切换其他多个不同窗口中的显示内容。 在传统的方式下,维护一个通知列表,可以采用TreeView.OnChange事件中调用所有通知,然后处理如下:(也可采用多播方式,详见:http://www.cnblogs.com/hezihang/p/3299481.html) 显然采用传统方式,各窗口都需要uses TreeView所在窗口。 另外,如果TreeView所在窗口还有其他事件需要对多个外部窗口或对象进行通知, 则再需要建立一个通知列表。 采用事件方式,需要自己维护一个或多个通知列表,同时各个使用事件的单元都需要引用事件源的单元。 2. 如果我们采用接口方式,将所有事件包含进去,由TreeView所在窗口去调用: 注意实现自动观察者的接口必须打开RTTI,{$M+} 然后,只需要如下调用,就可以让所有监听者(观察者)的OnResize被调用(接口内所有方法均可被调用): 其中: (1). AddObserver是添加监听者,RemoveObject是删除观察者 Source就是前面提到的用于多播调用的虚拟接口。 uMainForm.dfm 4. 下面是uInterfaceObservable.pas https://www.cnblogs.com/hezihang/p/6083555.html Delphi的基于接口(IInterface)的多播监听器模式(观察者模式 ) 标签:虚拟 offset rri bsp 举例 nap array 对象 ext 原文地址:https://www.cnblogs.com/findumars/p/11579259.htmlprocedure TForm2.TreeView1Change(Sender: TObject; Node: TTreeNode);
var
L:TTVChangedEvent;
begin
for L in FList do //FList:TList
type
{$M+}
ICurrentStateObserver=interface
[‘{20E8D6CB-3BCF-4DAE-A6CE-FEA727133C57}‘]
procedure OnCurrentObjectChange(CurObj:Pointer);
procedure OnDataReceive(Buf:Pointer; Size:Integre);
procedure OnResize(W, H:Integer);
end;
{$M-}
procedure TForm2.FormResize(Sender: TObject);
begin
CurrentStateDispatcher.Source.OnResize(Width, Height);
end;
CurrentStateDispatcher.Source:ICurrentStateObserver
是一个虚拟接口,也是ICurrentStateObserver类型。调用此接口内的方法,就自动调用所有观察者所对应方法。
这样我们只需要调用
CurrentStateDispatcher.Source.OnCurrentObjectChange(...);
CurrentStateDispatcher.Source.OnDataReceive(...);
CurrentStateDispatcher.Source.OnResize(...);
就可以实现所有观察者的调用。
(2).CurrentStateDispatcher:IInterfaceObservable
IInterfaceObservable
IInterfaceObservable = interface
procedure AddObserver(const aListener: T);
procedure RemoveObserver(const aListener: T);
function GetSource: T;
property Source: T read GetSource;
end;
(3).在使用模式的对象中声明:
TForm2=class(TForm)
....
private
FCurrentStateDispatcher:IInterfaceObservable
3.
下面我们看一个完整的使用例子:
uMainForm.pasunit uMainForm;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs , uInterfaceObservable, Vcl.StdCtrls,
Vcl.ComCtrls;
type
{$M+}
ITestObserver=interface
[‘{FE7F7C11-13BC-472A-BB7A-6536E20BCEDD}‘]
procedure OnClick(Sender:TObject);
procedure OnResize(Sender:TObject; X, Y:Integer);
end;
{$M-}
TForm2=class;
TObserver1=class(TInterfacedObject, ITestObserver)
F:TForm2;
procedure OnClick(Sender:TObject);
procedure OnResize(Sender:TObject; W, H:Integer);
constructor Create(Owner:TForm2);
end;
TObserver2=class(TInterfacedObject, ITestObserver)
F:TForm2;
procedure OnClick(Sender:TObject);
procedure OnResize(Sender:TObject; W, H:Integer);
constructor Create(Owner:TForm2);
end;
TForm2 = class(TForm)
Memo2: TMemo;
procedure FormClick(Sender: TObject);
procedure FormResize(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
FTestDispatcher:IInterfaceObservable
object Form2: TForm2
Left = 0
Top = 0
Caption = ‘Form2‘
ClientHeight = 309
ClientWidth = 643
OnClick = FormClick
OnCreate = FormCreate
OnDestroy = FormDestroy
OnResize = FormResize
TextHeight = 13
object Memo2: TMemo
Left = 0
Top = 152
Width = 643
Height = 157
Align = alBottom
TabOrder = 0
end
end
unit uInterfaceObservable;
interface
uses System.Generics.Collections, System.TypInfo, System.Rtti;
type
IInterfaceObservable = interface
procedure AddObserver(const aListener: T);
procedure RemoveObserver(const aListener: T);
function GetSource: T;
property Source: T read GetSource;
end;
TDioInterfaceDispatcher
文章标题:Delphi的基于接口(IInterface)的多播监听器模式(观察者模式 )
文章链接:http://soscw.com/index.php/essay/49660.html