【一起学UniGUI】--UniGUI的窗体和模块(8)

(六)、数据模块(DataModules):

       uniGUI支持向项目中添加数据模块(DataModules)。它允许开发人员像标准VCL应用程序那样设计他们的应用程序,将应用程序业务逻辑划分为几个数据模块。需要记住的重要一点是,虽然uniGUI数据模块与标准VCL数据模块在本质上是相同的,但是当使用uniGUI向导创建它们时,它们将为每个会话自动管理(其生存期将与会话本身相同)。如果使用标准IDE创建数据模型,则开发人员须要在适当的时候创建并释放它,并且有可能还是各会话共用(如果开发者不额外处理的话),须解决多会话间冲突问题。

      uniGUI中有两种类型的数据模块。 分别为:应用程序数据模块(Application DataModule) 与 自由数据模块(Free DataModule)。在下面的章节中,我会分子类进行讲述。

1)、应用程序数据模块(Application DataModule)

     应用程序数据模块(Application DataModule)是一个由uniGUI在运行时额外自动生成的,有如下几个特点:

  • 它在应用程序运行初始化时注册生成的
  • 它是在每个会话的开始或按需创建的(依据属性MainModule.ApplicationDataModuleOptions.CreateOnDemand),一个会话对应一个
  • 如果用户不手动释放(使用Free),则在关闭某对应会话时会相对应的自动释放(属于A会话的,在A会话关闭时,会自动释放A对应的应用程序数据模块)

       需要额外数据模型的小型应用程序(比如,多个MainModule)可能会使用缺省值(CreateOnDemand=False),但是大型应用程序将享受更好的内存管理,可以按需创建数据模型(并尽快释放它们)。

这是应用程序中DataModule自动生成的代码:

unit _AppDM1;
 
interface
 
uses
  SysUtils, Classes, FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Param,
  FireDAC.Stan.Error, FireDAC.DatS, FireDAC.Phys.Intf, FireDAC.DApt.Intf,
  Data.DB, FireDAC.Comp.DataSet, FireDAC.Comp.Client, FireDAC.Stan.StorageBin;
 
type
  TAppDM1 = class(TDataModule)
    tblList: TFDMemTable;
    tblListID: TAutoIncField;
    tblListText: TStringField;
    dsList: TDataSource;
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
function AppDM1: TAppDM1;
 
implementation
 
{$R *.dfm}
 
uses
  UniGUIVars, uniGUIMainModule, MainModule;
 

// 这个函数返回一个TAppDM1数据模块实例

// MainModule.ApplicationDataModuleOptions.CreateOnDemandTrue,如果尚未创建datamodule实例,

// 这个函数将创建一个实例并返回给它,否则它将返回先前创建的实例。

// MainModule.ApplicationDataModuleOptions.CreateOnDemandFalse。这个函数在会话启动时直接创建相同的datamodule实例并将返回给它

function AppDM1: TAppDM1;
begin
  Result := TAppDM1(UniMainModule.GetModuleInstance(TAppDM1));
end;
 
initialization
  RegisterModuleClass(TAppDM1);
 
end.

     注意这段代码与应用程序窗体(Application Form)非常相似。
     如果将参数CreateOnDemand设置为true,让我们看看窗体将如何使用应用程序数据模块(Application DataModule)。

unit _TestForm;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics,
  Controls, Forms, uniGUITypes, uniGUIAbstractClasses,
  uniGUIClasses, uniGUIForm,
  _AppDM1, uniGUIBaseClasses, uniBasicGrid, uniDBGrid;
 
type
  TTestForm = class(TUniForm)
    UniDBGrid1: TUniDBGrid;
    procedure UniFormDestroy(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
function TestForm: TTestForm;
 
implementation
 
{$R *.dfm}
 
uses
  MainModule, uniGUIApplication;
 
function TestForm: TTestForm;
begin
  Result := TTestForm(UniMainModule.GetFormInstance(TTestForm));
end;
 
procedure TTestForm.UniFormDestroy(Sender: TObject);
begin
  AppDM1.Free;  //如果此数据模块(AppDM1)确实不再使用时或也没有其他窗体使用时,在这里写Free方法进行手工释放也是可以的(但不是必须)

                  //如果此数据模块(AppDM1)被占用了,或者同一会话中的其他几个窗体也使用了它,那么不应该调用Free方法

                  //如果这里没有调用Free方法,则在其所属的会话终止时也会自动释放此数据模块(AppDM1)

end;
 
end.

       在窗体OnDestroy销毁事件中显式进行datamodule释放(也就是说,当窗体不再需要它时)。但是没有代码将UniDBGrid链接到数据模块中。让我们来看看DFM文件:

object TestForm: TTestForm
  Left = 0
  Top = 0
  ClientHeight = 246
  ClientWidth = 477
  Caption = 'Test (using App DM On Demand)'
  OldCreateOrder = False
  MonitoredKeys.Keys = <>
  OnDestroy = UniFormDestroy
  PixelsPerInch = 96
  TextHeight = 13
  object UniDBGrid1: TUniDBGrid
    Left = 0
    Top = 0
    Width = 477
    Height = 246
    Hint = ''
    DataSource = AppDM1.dsList
    LoadMask.Message = 'Loading data...'
    Align = alClient
    Anchors = [akLeft, akTop, akRight, akBottom]
    TabOrder = 0
  end
end

该链接在表单设计器中也可见:

数据源(TDataSource)在设计时链接到数据模块。在运行时不需要这样做。
运行应用程序证明它确实在没有内存泄漏的情况下工作(内存不泄漏)。

2)、自由数据模块(Free DataModule) 

      这种自由数据模块型只是一个普通的旧数据模型,即与传统VCL的datamodule一样,须要手工创建和释放它。

unit _FreeDataModule;
 
interface
 
uses
  SysUtils, Classes;
 
type
  TFreeDataModule = class(TDataModule)
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
implementation
 
{$R *.dfm}
 
 
end.

       这种数据模块的使用方法与在常见VCL应用程序中使用的方法相同。用户完全有责任在需要时创建它,并在不再需要时释放它。 使用这种数据模型的原因是,一些非可视组件需要一个主机/容器(或者以这种方式使用它们更容易)。一个很好的例子是报表工具,因为即使用户只将它用于导出报表,它通常也会被放入一个DataModule中。
       使用数据模块的另一个原因是不应该在表示层(TForm、TUniForm、任何窗体)中承载“业务代码”。使用自由的数据模块(Free DataModule)允许开发人员按需处理资源,从而将内存使用量降到最低。
      自由数据模块的使用在FastReport和ReportBuilder等如何使用,我会在后面一些深入的学习中再讲述(计划在报表部分中讲解)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值