Delphi风格:如何构建可单元测试代码的数据模块?

我正在寻找关于构建Delphi程序的可维护性的一些建议.几十年来,我已经来到Delphi编程,大部分是C/C++,尽管我第一次学习使用Turbo Pascal来编程,所以我对基本语言并不感到不舒服.在我以前的C和C#的经验中,我通过使用cxxtest和NUnit成为了TDD转换.

我继承了我现在负责维护的这个程序.它主要由表单和几个数据模块组成.应用程序业务逻辑和数据访问主要分散在表单上,​​而数据模块主要是全局ADO对象生存的地方.数据库访问通常通过引用TADOQuery或TADOCommand的全局实例来完成,将SQL文本格式化为对象的相关属性,并调用其Open或Execute方法.

我试图将业务逻辑放到一定程度的封装,可以进行单元测试.我看到了this answer,从形式的抽象逻辑来说,这是非常有意义的.我想知道数据访问的最佳做法是什么.我的想法是,数据模块应该公开一种特定于应用程序的mini-API(可能是所有的虚拟方法),以便它们可以被模拟对象替换成测试. this other answer的链接显示了一些让我相信我走在正确轨道上的例子,但是我仍然希望看到关于数据模块的一些最佳实践文档.我可以通过Google找到的大部分页面都提供了与设计时可以做的所有酷的东西一样的例子,它们将数据绑定控件绑定到查询和这种事情上,我对此并不感兴趣在这一刻.

我个人不是TDataModule的粉丝.鼓励良好的OO设计原则很少.如果所有这些都是DB组件的一个方便的容器,这将是一件事情,但是经常会成为在域层中更好的业务逻辑的倾倒场所.当这种情况发生时,它会变成一个神级和一个依赖磁铁.

至少在Delphi 2之后,添加一个错误(或可能是其功能),导致窗体的数据感知控件丢失数据源,如果这些数据源位于窗体之前未打开的单元中.

我的建议

>在您的UI和数据库之间添加域图层
将尽可能多的业务逻辑推入域对象.
>通过使用designarchitectural模式将您的用户界面和数据持久化层尽可能的浅,将决策委托给域层.

如果您不熟悉该技术,那么该技术被称为域驱动设计.它当然不是唯一的解决方案,但它是一个很好的解决方案.基本前提是,UI,业务逻辑和数据库以不同的速率和不同的原因进行更改.因此,将业务逻辑作为问题域的模型,并将其与UI和数据库分开.

这如何使我的代码更可测试?

通过将业务逻辑移动到自己的层,您可以测试它,而不会受到UI或数据库的干扰.这并不意味着您的代码只会因为将其置于自己的层面而固有地可测试.使遗留代码可测试是一项艰巨的任务.大多数遗留代码紧密耦合,所以您将花费大量时间将其分成具有明确责任的课程.

这是德尔福风格吗?

这取决于你的观点.传统上,大多数Delphi应用程序是通过一起开发UI和数据库而创建的.在表单设计器上删除几个数据库感知控件.使用字段添加/更新表以存储控件的数据.使用事件处理程序使用自由的业务逻辑.中提琴!你刚刚烤了一个应用程序.对于非常小的应用程序,这是一个很好的节省时间.但是,不要自欺欺人,小型应用程序往往变成大型应用程序,这种设计成为一种不可持续的维护噩梦.

这真的不是语言的错误.您可以从数百个VB,C#和Java商店找到相同的快速/脏/短视设计.这些类型的应用程序是新手开发人员不了解任何更好的(有经验的开发人员应该更好地了解)的结果,这是一个IDE,使其变得如此容易,并且迫使工作快速完成.

德尔福社区(正如其他社区一样)在很长一段时间一直主张更好的设计技术.

翻译自:https://stackoverflow.com/questions/4972568/delphi-style-how-to-structure-data-modules-for-unit-testable-code

转载注明原文:Delphi风格:如何构建可单元测试代码的数据模块?