gpt4 book ai didi

delphi - 如何为 Delphi 创建模块化插件

转载 作者:行者123 更新时间:2023-12-03 15:00:57 24 4
gpt4 key购买 nike

使用Delphi 2010,我需要编写一个程序来支持模块或插件。虽然有点做作,但假设我有一个可以转换数据文件/文本文件的应用程序。它将支持 30 种输入格式和 30 种输出格式。第一个版本可能只会实现其中的一些格式。我的挑战是我想要一个数据驱动的流程。

例如,假设我有一个 PARSE_FILE 例程。如果我的输入数据文件格式是“Format_A”,那么当我调用 PARSE_FILE 时,它应该知道使用 PARSE_FILE_Format_A,而不是其他 29 个不同版本的 PARSE_FILE 例程。

PARSE_FILE 只是一个示例。我可能会有 60 个不同的常见函数,LOAD_FILE、GET_DELIMITER、PARSE_FILE 等,但是对于 30 种不同的格式,这些函数中的每一个都会略有不同。我可以使用什么技术,以便在使用 FORMAT_A 加载文件时,这 60 个不同的常用例程中的每一个都使用这 60 个例程的正确“版本”?

请记住,我一开始只使用 5 种输入格式,稍后将添加其他格式,因此我需要一种集中定义此“映射”的方法,因此无论在何处使用这些例程在我的代码中,即使我调用通用版本,也会使用例程的正确版本。

最佳答案

  1. 定义每个插件所需的一组标准例程在接口(interface)类型中实现的模块。比如说,IFileFormatHandler,其中包含 PARSE_FILE 函数等。
  2. 遵循接口(interface)设计和职责分离的原则,避免将某些实现不感兴趣或无法实现的功能放入接口(interface)中。在单独的接口(interface)中定义可选函数,实现类可以选择实现或不实现。例如,如果您预计您的应用会读取某些文件格式,但由于各种原因无法写入,那么您应该将读取操作放在一个接口(interface)中,将写入操作放在不同的接口(interface)中。
  3. 如果您将在 Delphi 中编写所有插件,则应该使用 BPL 包来共享通用类型。将您的 IFileFormatHandler 接口(interface)类型放在一个 BPL 包(即 Common.bpl)中,以便所有模块都可以引用公共(public)接口(interface)类型。每个插件模块本身也位于其自己的 BPL 包中。 (同一个 BPL 包中可以存在多个文件格式处理程序,但基准示例是每个 BPL 一个)
  4. 如果这是您第一次尝试构建插件架构,请不要尝试同时涵盖多语言支持。现在继续使用 Delphi。在 Delphi 中编写应用程序和模块。在 Delphi 中构建完成一个模块化项目,然后退后一步,花一些时间了解 COM 或二进制接口(interface)要求,以支持用 Delphi 以外的语言编写的模块。
  5. 在通用 BPL 包中,还定义一个全局函数,模块可以调用该函数以使主机应用程序知道它们自己 - 例如 RegisterPlugin(name: string; instance: IFileFormatHandler)。这会在内部列表中注册插件名称和实例,主机应用程序可以使用该列表来查找可用的插件并调用它们。
  6. 对于每个文件处理插件模块,定义一个类来实现共享 BPL 包中定义的公共(public)接口(interface)。在类的单元初始化中,调用RegisterPlugion()函数向宿主应用程序注册该类。
  7. 主机应用程序使用公共(public)包,每个模块包都使用公共(public)包。
  8. 主机应用程序仅通过公共(public)接口(interface)中定义的函数与模块实现进行交互。
  9. 主机应用程序可以使用 IS 来测试特定模块对象实例是否实现可选接口(interface),并使用 AS 来获取该可选接口(interface)。
  10. Delphi 中的接口(interface)采用引用计数,因此只要主机应用程序保留对模块对象实例的引用(例如通过 RegisterPlugin),模块实例就会保持事件状态并保留在内存中。当最后一个引用被释放时,模块实例将被释放。
  11. 主机应用程序需要在运行时使用 LoadPackage 或类似的 fn 查找并加载模块包 bpls。
  12. 在应用程序中共享插件模块实例的列表对于大多数单线程应用程序来说都可以正常工作。如果您预计同时在多个线程中使用这些插件模块,请考虑将此设计转移到工厂模式,而不是在内存中保存模块的单例实例。通过使用工厂在使用线程内按需构造实例来管理多线程,比创建一个必须安全地从多个线程调用的实例要容易得多,通常性能也更高。

关于delphi - 如何为 Delphi 创建模块化插件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15093212/

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