0

我有一个丑陋的情况,我在 Delphi 应用程序中需要两个数据模块(TDMA,TDMB)。每个数据模块具有相同的数据对象名称(查询、表等),但来自不同的组件集(TZQuery、TADOQuery)。我需要这个,因为我想支持多个数据库,但我的组件套件并不支持所有数据库。我需要访问哪个数据模块由 DBFlag 布尔变量确定。除了为每个数据访问提供几乎相同的代码段之外,还有更有效的方法吗?

如果我可以根据 DBFlag 将像 DMG 这样的全局数据模块变量设置为 DMA 或 DMB,那么我的代码可以引用 DMG 而不是 DMA 或 DMB。这将是理想的,并且只需要很少的代码修改,但据我所知是不可能的。

4

2 回答 2

1

我的建议是放弃DataModules基于特定数据集的构建。仅使用构建它们TClientDataSet并编写所有代码或将所有代码链接DataSources到这些数据集。然后创建其他DataModules来保存您的特定数据集,并使用您的选择方法来选择响应哪个作为 CDS 实例的数据提供者。使用接口来做到这一点的想法确实是一个很好的想法。

这种方法将删除所有重复的代码,并将业务逻辑(处理 CDS 内数据的代码)与持久性(将数据行从数据服务器传输到数据服务器的代码)分开。

于 2014-07-28T10:46:10.433 回答
0

完全有可能拥有一个全局变量,或者更好的是一个函数或单例类,或者最好是一个接口,它根据布尔标志返回对 dmA 和 dmB 共同点的抽象的引用。但是,具体如何去做,需要仔细考虑,其中大部分需要您自己完成,因为只有您知道项目的细节及其要求。

但是,我认为它有一些潜在的问题可能会引导您实现像现在已删除的评论所建议的那样,它取消了数据模块(或将它们隐藏起来)并使用自定义 DB 对象或接口来提供消费者从表格、报告等中访问。

一个大问题与对象可见性在 Delphi + 它的 IDE 中的工作方式有关。

考虑一个具有单元 MyForm1u 的项目,该单元将成为您的 DB 对象的消费者。以及单元 dmAu 和 dmBu,它们包含您通过 IDE 设计器添加的 DB 组件,它们在两个单元中可能具有相同的名称,但可以是不同的实例类型。

现在,MyForm1u 当然可以使用 dmAu 和 dmBu,但存在的问题是 dmA 和 dmB 中的 DB 组件必须具有已发布的可见性(因为它们必须是可流式传输和 IDE 可设计的)。因此,尽管您可以有一个返回 dmA 或 dmB(的实例)的函数,但如果 MyForm1u 使用 dmAu 和 dmBu,则不会强制对它们进行封装,以便只能通过该函数访问它们。

可以做的是定义一个共同的祖先数据模块,在单元 dmCAu 中将其称为 dmCA,然后从中下降 dmA 和 dmB - 事后这样做会有点繁琐,因为如果 dmA 和 dmB 已经存在,您需要如果您想在 dmCA 上拥有一些组件,请手动编辑他们的 DFM 文件以调整组件祖先。但是重新开始,您可以轻松地在您的项目中创建一个新的 dmCA,其中包含 dmA 和 dmB 之间具有相同实例类型的任何共同的 DB 组件,然后在 IDE 中从中删除 dmA 和 dmB。

这将为您提供一个项目结构,其中 myFormu1 不直接使用 dmAu 或 dmBu,有些人会说,dmCA。更好的方法可能是不使用它们,而是使用单元 X,其中包含返回某个类的函数或更好的接口,该接口又具有一组函数,这些函数返回对它们拥有的 dmA 和 dmB 组件的引用在名称(实际上重要的是它们在数据模块的数据模型中的功能)和祖先类型方面是共同的,例如

函数MyDataSet1:TDataSet;

以便它可以返回 dmA 的 AdoQuery1 或 dmB 的 SqlQuery1,具体取决于您的布尔标志。

如果您的消费单元仅使用单元 X 而不是 dmAu、dmBu 或 dmCAu,这将强制对其内容进行封装。

这种基于类或接口的方法将排除使用 IDE 的 Object Inspector 提供的通常的点击方法将 TmyForm1 之类的消费者对象“连接”到 DB 对象,但现在很多人会说这不是坏事。

于 2014-07-28T07:12:59.670 回答