gpt4 book ai didi

delphi - 是否可以在没有.DFM 的情况下使用数据模块?

转载 作者:行者123 更新时间:2023-12-03 15:47:52 33 4
gpt4 key购买 nike

我将所有 ADO 引擎卸载到一个单独的数据模块中,因此单个模块可以被多个应用程序引用。我的所有应用程序基本上只需要两种 worker 方法来访问数据:

AdoQueryTADODataSet 的形式提供结果集。
AdoExecute 执行简单的更新/删除查询,而不获取任何结果。

这是类结构:

type
TMyDataModule = class(TDataModule)
procedure DataModuleCreate(Sender: TObject);
procedure DataModuleDestroy(Sender: TObject);
private
procedure pvtAdoConnect;
procedure pvtAdoExecute(const sql: string);
function pvtAdoQuery(const sql: string): TADODataSet;
public
AdoConnection: TADOConnection;
end;

然后我向类方法添加了两个公开公开的包装器。我用它来避免调用中的长类引用:

function AdoQuery(const sql: string): TADODataSet;
procedure AdoExecute(const sql: string);

implementation

function AdoQuery(const sql: string): TADODataSet;
begin
Result := MyDataModule.pvtAdoQuery(sql);
end;

上面是我从所有表单中调用的worker函数。

AdoConnect 仅在 DataModuleCreate 事件上运行一次。 TDatModule 派生自 TPercient,它允许在整个运行时保留单个连接实例。

到目前为止,唯一让我烦恼的是一个无用的 .DFM,我根本不需要它。
有什么选择可以摆脱它吗?

最佳答案

我会用两种方式之一处理这种类型的事情,使用接口(interface)或继承。在这些情况下,我不想将类暴露给外界。第二个几乎可以称为没有接口(interface)的接口(interface):)

接口(interface)

此版本返回一个包含所需方法的接口(interface)。外界只需要使用接口(interface)即可。我们对实现细节保密。我们的 TMyDBClass 实现了我们向外界公开的接口(interface),并且我们的全局函数 GetDBInterface 返回单个实例。

interface

uses
ADODB;

type
IMyDBInterface = interface
['{2D61FC80-B89E-4265-BB3D-93356BD613FA}']
function AdoQuery(const sql: string): TADODataSet;
procedure AdoExecute(const sql: string);
end;

function GetDBInterface: IMyDBInterface;

implementation

type
TMyDBClass = class(TInterfacedObject, IMyDBInterface)
strict private
FConnection: TADOConnection;
protected
procedure AfterConstruction; override;
procedure BeforeDestruction; override;
public
function AdoQuery(const sql: string): TADODataSet;
procedure AdoExecute(const sql: string);
end;

var
FMyDBInterface: IMyDBInterface;

procedure TMyDBClass.AdoExecute(const sql: string);
begin
// ...
end;

function TMyDBClass.AdoQuery(const sql: string): TADODataSet;
begin
// ...
end;

procedure TMyDBClass.AfterConstruction;
begin
inherited;
FConnection := TADOConnection.Create(nil);
end;

procedure TMyDBClass.BeforeDestruction;
begin
FConnection.Free;
inherited;
end;

// Our global function

function GetDBInterface: IMyDBInterface;
begin
if not Assigned(FMyDBInterface) then
FMyDBInterface := TMyDBClass.Create;
Result := FMyDBInterface;
end;

initialization

finalization
FMyDBInterface := nil;
end.

继承

此版本使用具有所需方法的基类。这对人们来说更容易处理,因为它排除了对于刚开始的人来说可能很复杂的界面。我们再次向用户隐藏实现细节,只公开包含我们希望人们访问的两个方法的类的外壳。这些方法的实现由继承自公开类的实现中的类执行。我们还有一个返回此类实例的全局函数。与此方法相比,接口(interface)方法的一大优点是该对象的用户无法意外释放该对象。

interface

uses
ADODB;

type
TMyDBClass = class(TObject)
public
function AdoQuery(const sql: string): TADODataSet; virtual; abstract;
procedure AdoExecute(const sql: string); virtual; abstract;
end;

function GetDBClass: TMyDBClass;

implementation

type
TMyDBClassImplementation = class(TMyDBClass)
strict private
FConnection: TADOConnection;
protected
procedure AfterConstruction; override;
procedure BeforeDestruction; override;
public
function AdoQuery(const sql: string): TADODataSet; override;
procedure AdoExecute(const sql: string); override;
end;

var
FMyDBClass: TMyDBClassImplementation;

procedure TMyDBClassImplementation.AdoExecute(const sql: string);
begin
inherited;
// ...
end;

function TMyDBClassImplementation.AdoQuery(const sql: string): TADODataSet;
begin
inherited;
// ...
end;

procedure TMyDBClassImplementation.AfterConstruction;
begin
inherited;
FConnection := TADOConnection.Create(nil);
end;

procedure TMyDBClassImplementation.BeforeDestruction;
begin
FConnection.Free;
inherited;
end;

// Our global function

function GetDBClass: TMyDBClass;
begin
if not Assigned(FMyDBClass) then
FMyDBClass := TMyDBClassImplementation.Create;
Result := FMyDBClass;
end;

initialization
FMyDBClass := nil;
finalization
FMyDBClass.Free;
end.

使用

这些的使用非常简单。

implementation

uses
MyDBAccess; // The name of the unit including the code

procedure TMyMainForm.DoSomething;
var
myDataSet: TADODataSet;
begin
myDataSet := GetDBInterface.AdoQuery('SELECT * FROM MyTable');
...
// Or, for the class version
myDataSet := GetDBClass.AdoQuery('SELECT * FROM MyTable');
...
end;

关于delphi - 是否可以在没有.DFM 的情况下使用数据模块?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31037863/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com