如何/如果仅使用表单和数据模块重构 Delphi 程序
Posted
技术标签:
【中文标题】如何/如果仅使用表单和数据模块重构 Delphi 程序【英文标题】:How / if to refactor a Delphi program using only forms and data modules 【发布时间】:2010-10-07 15:43:10 【问题描述】:在多年将 Delphi 程序编码为表单和数据模块中不可测试的代码(包括全局变量)之后,唯一的类是表单本身,包含表单 UI 本身所需的所有代码。
如何将代码转换为一组执行实际工作的类?我是否需要停止使用数据源/数据集并在课堂上做所有事情?我需要 ORM 吗?
通常零需要重用表单中的代码,那么将逻辑转换为类是否有意义?
【问题讨论】:
【参考方案1】:导入Modelmaker 是我面对现有的 Delphi 项目时的第一个操作。 Modelmaker 将协助您重构您的代码,因为:
它以图形方式表示所有类、方法、变量等。 在 Delphi IDE(主菜单、弹出菜单、 单独的 Modelmaker 资源管理器, 工具栏、键盘快捷键)。这 集成让您可以快速 无需执行必要的操作 离开 IDE 它有一个专用的“重构”模块让您可以快速创建、移动 并重命名类和变量 不得不担心改变 底层代码。模型制造商将 自动更改名称和 所有单位的引用。Modelmaker 的基本功能简单易学。 Modelmaker 就像任何其他好的生产力工具一样 - 你投入的越多,你得到的就越多。 Modelmaker 不是免费的,但可以通过提高生产力轻松收回成本。 我还没有找到更好的工具来重构遗留的 Delphi 代码。他们提供免费试用和一些不错的教程电影。 试试 Modelmaker,祝你好运...
【讨论】:
没有反对 ModelMaker,但你提到的所有东西都是现在内置的。不过,如果您有较旧的 Delphi,请 +1 提供帮助。 谢谢 - 我仍在使用 Delphi 5。我知道 Modelmaker 男孩与 Borland 签订了代码共享协议。 Delphi IDE 中集成了许多 Modelmaker 功能。我想如果所有 Modelmaker 功能都集成在 IDE 中,那么没有人会花 199 欧元购买许可证。 @Kris,实际上集成的重构功能不是来自 ModelMaker,而是来自 Borland Together(这更不友好)。我使用了 Delphi 默认建模,而且 ModelMaker 对于 Delphi 开发人员来说更容易掌握。 +1;请注意,ModelMaker 和 ModelMaker Code Explorer 是两个不同的产品。 ModelMaker 是 UML 工具,ModelMaker Code Explorer 是紧密集成在 Delphi IDE 中的重构工具。它比 IDE 中已经存在的重构工作得更好(一方面,因为它可以对未完全编译的代码进行操作,还因为它有更多更好的重构)。几个世纪以前,ModelMaker 被包含在 Delphi 中(在 Together 集成之前)。我希望他们继续这样做。内置重命名符号重构的好处是:它涵盖了您的整个项目。【参考方案2】:我强烈推荐的另一本书——在我个人看来甚至比 Fowler 的“通用”重构书更合适——是"Working Effectively with Legacy Code" by Michael Feathers。它真正展示了您在进行此类工作时会遇到的主要障碍。哦,还有:重构遗留代码对你来说可能非常困难。我希望你能处理挫折......我喜欢这句话(不记得我从哪里得到它):“上帝能够在 6 天内创造世界,只是因为没有任何遗留代码”。祝你好运。 ;)
【讨论】:
【参考方案3】:我在一个应用程序中遇到了这样的问题,我开始执行以下操作:
-
为代码中的大多数通用逻辑定义主类。
在每个表单中,将处理事件内部业务逻辑的代码作为该表单中的函数/过程移动。
然后将这些函数/过程作为静态方法移动到这些类中。
最后只在表单中编写所需的代码,如验证 UI 和对类的调用。
对于全局变量,尽量省略,只需将值作为参数传递给方法。
我使用了静态方法,因为您可以更轻松地从事件中删除代码并直接调用它们,而无需为每个操作创建/释放对象。最初的设计并不是为了将表单与业务逻辑代码分开。
最终的应用程序不是完整的 OO,但它至少更容易测试方法,而不需要像以前那样与表单和事件进行交互。
有时您会觉得,如果您从头开始重新设计应用程序,会比进行更改以使其成为真正的 OO 设计更容易。
【讨论】:
【参考方案4】:如果我遇到一个表单(或其他类)有太多责任,我通常遵循以下模式:
-
为逻辑定义一个新类。
在表单中创建新类的成员变量。
在 onCreate 中创建类并在表单的 onDestroy 中释放它。
将单个逻辑(例如变量)移动到新类中。
将所有方法移动或创建到新类。
编译和测试。
继续,直到所有逻辑都放入新类中。
尝试将逻辑类与表单类解耦。 (如果您愿意,您甚至可以使用接口)。
存在单个类不够用的情况,所以创建更多类是没有问题的。而且这些类可以有其他类。
通过这些步骤,您可以解决大部分问题。
【讨论】:
不错的步骤,但有一个提示:为了尽可能减少耦合,不要将任何视觉控件传递给您的新类。如果你这样做了,那么你就限制了你换出 UI 控件的能力。如果您必须通过可视化控件(尤其是网格等),则将其全部隔离在另一个没有业务逻辑的类中。 我同意,可见控件是表单的责任。可以使用框架,但我不太喜欢将它们用于生产代码。 所有优点。依赖于特定数据库连接和数据表对象(TTable、ADO 数据集或 datasnap 等)的东西的单元可测试性如何...... @Warren P,使用数据库,您可以模拟整个数据库界面,也可以使用为每个测试设置的特殊测试数据库。我更喜欢后者,但它会减慢测试速度。【参考方案5】:在了解你需要重构代码之后,如果你想要一个 OPF/ORM,我建议Jazz SDK
【讨论】:
【参考方案6】:首先,我强烈建议您阅读 Martin Fowler 的《Refactoring》一书。
这将使您真正了解如何以最佳方式明智地引入对现有(非 OO)代码的更改以提高可维护性。
在您清楚地了解 ORM 会给您的应用程序带来什么好处(如果有的话)之前,我不会查看 ORM。
【讨论】:
以上是关于如何/如果仅使用表单和数据模块重构 Delphi 程序的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Delphi 将数据从 XML 导入 PDF 表单?
将 TForm 分配给一个变量 Delphi 以在其他单元中使用