【问题标题】:What are the advantages of using DB Aware Controls instead of non DB Aware Controls in Delphi在 Delphi 中使用 DB Aware Controls 而不是非 DB Aware Controls 有什么优势
【发布时间】:2012-01-19 09:29:06
【问题描述】:

我会说服朋友,在开发数据库应用程序时,在 Delphi 中使用数据库组件(DB 感知控件)是迄今为止最好的选择。

这个争论始于多年前的他:直到今天,他仍然相信使用 TEdit、TStringGrid 等简单的控件以及一组 getter 和 setter 方法来填充它们,在灵活性和灵活性方面都是最好的解决方案。整个项目的可维护性。

至少对我来说这听起来违反直觉。

我认为在开发数据库应用程序时使用 DB Aware Controls,如 TDBEdit、TDBGrid 等是正确的做法。

所以:请帮助我用合理的建议说服他使用 DB Aware Controls!

提前感谢你们所有人,他们至少会发表他自己的建议,无论是支持哪种解决方案。

-- 法比奥维莱

【问题讨论】:

  • +1 因为我喜欢这个问题,但我属于从不使用 Db-aware-controls 阵营,所以我不打算回答。
  • 这取决于哪个控件、dbedit 等都很好,但有时像 dbgrid 这样的东西还有很多不足之处
  • +1 对于小型数据库应用程序(我需要快速解决方案),我会使用 DB Aware Controls,特别是如果数据库是本地的(如 MS-Access)。对于大规模和完整的数据库应用程序,我更喜欢使用我自己的非感知控件。对于 DBGrid 的示例,我使用未绑定 DataSet 的虚拟树。这是更多的工作,但至少我不受限制。
  • 我支持@Cosmin,尽管我有时认为 DBAware 控件本身不是问题,而是您使用它们的方式。它们往往会导致所有业务逻辑都以事件形式编码。如果您避免这种情况,请将您的数据集分组到数据模块上,并将您的业务逻辑放在您已经做得更好的查询事件中。将您的业务逻辑放在实例化数据模块时实例化的类中,并从数据集/模块事件调用业务类方法,这样您就可以在应用程序发展时更轻松地切换到正确分离的层。
  • 当我第一次阅读你的问题的标题时,我和@CosminPrund 的意见相同......因为就个人而言,我喜欢客观的比较。但是,在阅读了您的问题后,我意识到您真正想要的只是一些弹药来“证明您的朋友是错误的”。你已经下定了决心,你对客观的比较不感兴趣。这实在不利于学习。你不妨问问你的宗教为什么是对的,而他的宗教是错的。

标签: delphi


【解决方案1】:

DB-Aware 与非 DB-Aware 是一种过时的讨论。 DB-Aware 控件具有自动数据绑定,这意味着它们会自动填充数据、进行更改检测并写入有界数据源的成员;在非 dbaware 控件中,由您来完成这些任务。这也可能导致代码混乱 - 或过度设计的框架只是为了进行数据绑定。这两种情况都很糟糕。

数据源的种类和单个控件的质量将决定性能。我已经看到很多数据绑定 TStringGrid 的代码只是为了避免 TDBGrid 因为纯粹主义(当 TDbGrid 做得很好时) - 只是一个过于荒谬的时间损失。

当 TClientDataset 成为断开连接应用程序的事实数据集时,它已成为过时的讨论:您可以提取数据、断开连接、处理数据、再次连接并应用更改。由于 CDS+DbAware 控件将完成 99% 的界面,因此您在接下来的 1% 中使用非数据感知控件(对于一些复杂的界面)。

我仍然没有 XE2 来查看 LiveBindings 是否可以很好地执行 OO 数据绑定工作 - 如果可以,现在所有控件都可以在需要时识别 db。

编辑:在 da-soft 的回答中,他(她?)认为 DbAware 控件实现了 MVC 模式,而 LachlanG 不同意,即使确实如此,代码本身不是 MVC。我会在这里给我的 0.02 美分 ;-)

我认为在 DataModule 和 Entity(如 ERD)中使用 1:1 关系 - 或 DataModule 和 Form - 您可以获得职责分离的应用程序:

  • form dfm -> 布局和设计时数据绑定(只有数据源)
  • form *.pas -> 控制界面并向数据模块请求数据(就像控制器一样)
  • 数据模块 -> 回答表单数据检索请求的方法 和数据更新

我通常有一个用于数据库连接的单独数据模块,它通过表单/实体的属性传递。

【讨论】:

    【解决方案2】:

    数据库感知控制专家:

    1. 将数据加载到控件并将数据保存到数据集的工作由 VCL 执行。您需要编写的代码更少 - 真的很RAD。
    2. DB 感知控件 + TDataSource + TDataSet 实现 MVC 模式。这有助于分离 GUI 和数据访问代码。
    3. 代码验证、重新格式化、对数据进行其他后处理将在明确定义的时刻使用事件处理程序调用。这有助于集中此类代码并避免与应放置的位置混淆。并避免与调用它的时刻混淆。

    缺点:

    1. 这不是通用方法。不能将 DB 感知控件绑定到非 TDataSet 数据源。在 Delphi XE2 中引入实时数据绑定解决了这个问题。
    2. 事件驱动的编程可能会让一些开发人员感到困惑。并且需要了解 TDataSource、TDataSet、TField 事件和架构,并导致与 Pros (3) 的争议。糟糕的事件驱动代码可能是一场噩梦。

    【讨论】:

    • 我是数据感知控件的粉丝,但我不同意你的第二个专业人士。即使控件实现了 MVC(我不相信他们会这样做),但这并不意味着您的代码会这样做。您必须努力正确分层数据感知控件应用程序,这不是使用数据感知控件的自动结果。
    • @LachlanG:如果正确使用TDataModule,Delphi是一种类似MVC的东西:Form-> controls + TDataSource;表单 *.pas -> 命令接口并请求数据;数据模块:响应表单请求的数据检索和更新方法。
    • @FabricioAraujo:我强烈反对。无论您如何使用它们,它们都不像 MVC。我并不是说 MVC 一定比数据感知组件更好或更差,只是这两者是非常不同的方法,几乎​​没有共同点。
    • @LachlanG:我们必须同意不同意。您不一定需要一个完整的单独类来担任控制器角色。
    【解决方案3】:

    DB 感知组件和非 DB 感知组件各有利弊,具体取决于您正在开发的应用程序类型。

    对于中小型应用程序,鼓励使用可识别数据库的组件,除非这些应用程序在运行时存在特定要求或条件。例如,一个简单的数据输入应用程序将更容易使用 DB 感知组件进行开发和维护。即使是大中型应用程序,如果设计和实施得当,也可以通过 DB-aware 组件获得良好的性能。

    但是,在开发模块化应用程序(尤其是多层系统)时,DB 感知组件可能会对应用程序性能和可维护性产生负面影响。这对于通过 Internet 访问数据的应用程序尤其明显。造成这种情况的主要原因是数据库感知组件需要与数据库的持续连接,这会显着增加网络流量。

    使用不支持 DB 的组件可能会更复杂,因为它需要更好地理解底层机制,但在多用户和分布式多层环境中,它的扩展性要好得多。此外,您可以(并且应该)将数据访问层与表示 (UI) 层分开,这将允许您稍后对一个子系统(模块、层)进行更改,而无需更改其他任何内容。

    今天,数据可以在任何地方,而且大多数时候并不存储在本地计算机或网络上。使用 DB 感知组件访问该数据可能会对应用程序和数据库性能产生重大负面影响。有一些数据访问层可以改进这一点(UniDAC、AnyDac、...),因此将 DB-aware 组件与它们一起使用可能会获得更好的性能。尽管如此,不支持 DB 的组件仍然可以胜过任何东西。

    由开发人员决定使用哪种机制,因为正如我所说,这完全取决于您正在制作什么样的应用程序以及它将在什么环境中工作。

    【讨论】:

    • +1 因为明确命名“multi-tier”分层架构的唯一答案。简而言之:数据库组件很难维护和扩展。值得一提的是Service Oriented Architecture (SOA) 方法。 RAD DB 组件是 1990 年代的典型开发:它适用于原型设计和小型应用程序,但对于业务应用程序,在 21 世纪应避免使用。
    • DB-aware components require a constant connection to the database。仅当您将数据访问组件直接链接到控件时才如此。否则,DB-control 将向 TDatasource 询问数据,它会来自任何它......
    【解决方案4】:

    这可能是 Visual Basic 经验的遗留问题。我记得,甚至微软也告诉开发人员不要在生产代码中使用 DB 感知控件。

    Delphi 从未遇到过这个问题,但正如其他人所说,这取决于您正在构建的项目类型以及您是否遇到性能问题。

    【讨论】:

      【解决方案5】:

      轶事:一个 DB 感知控件曾经搞砸了我们的 InterBase 数据库:为了指示一个“空”或空日期,日期编辑控件 TcxDBDateEdit (ExpressQuantumGrid) 使用 negative 日期值,它表示字面意思是“01/00/0000”。

      因此,当用户清除输入表单中的日期编辑字段并将此值发布到数据库时,记录变得不可读(SELECT 语句失败)。

      【讨论】:

      • 轶事:我曾经复制和粘贴错误,并将错误的值保存到错误的字段中。事实上,我已经不止一次这样做了。 ;-)
      • 日期时间选择器是一种控件,它显示了创建它的程序员是多么小心(或粗心)。我看到很多 DBAware DTP 也无法正确处理 null 情况。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-25
      • 1970-01-01
      • 2013-03-05
      • 1970-01-01
      • 2011-09-23
      相关资源
      最近更新 更多