6

这是一个关于软件设计的一般“菜鸟”问题,所以如果它看起来含糊不清,我深表歉意,但我真的很感激你的建议。请注意,下面描述的系统纯粹是一个示例,而不是我想到的特定产品。

我经常需要结合使用不同语言编写的多个库或实用程序的功能。例如,如果我想为桌面编写一个高性能的音频处理应用程序,我会用 C/C++ 编写它。然后,我想添加一个漂亮的 GUI。但我不想学习Qt。我喜欢 Adob​​e Air 的外观和感觉,并希望使用它。后来,我需要访问一个 USB 设备。但是我拥有的 USB 库只有一个 Java 的 API。我如何将所有这些元素结合在一起,以利用它们的相对优势?

显然,我无法将这些不同的元素编译成一个可执行文件。所以我需要分别创建和运行它们,并为它们提供交流的方式。最常见的方法似乎是使用 IPC(进程间通信),例如共享内存或套接字。我更喜欢套接字的想法,因为这些程序可能会在网络上的不同机器上运行。

所以我决定创建一个本地客户端/服务器系统,使用自定义 API,以允许这些元素进行通信。例如,Air 应用程序将收到来自 C 应用程序的消息,告诉它更新它的 UI。在 Java 中运行的 USB 应用程序将使用套接字将音频从 USB 硬件流式传输到 C 应用程序中。

我的问题:以这种方式使用本地套接字是设计这种系统的典型方式吗?性能会比真正的原生应用程序(例如 Java 或 C 中的所有内容,在单个可执行文件中)差很多吗?这种方法似乎也很可能容易出现错误,并且难以维护?

我经常发现自己遇到了现有软件库的限制(例如,具有漂亮、灵活的 UI 但无法访问低级硬件的图形库,或者可以混合许多音频流但不支持的媒体库视频播放),并发现它非常令人沮丧。如果有人能建议像这样组合任意软件库的最佳方法,我将不胜感激。

提前致谢!

4

2 回答 2

6

正如您正确识别的那样,组合来自不同语言或平台的库是很困难的。有几种方法可以做到这一点,但没有一种是理想的。例子:

  • 本机调用接口(例如 JNI / JNA) - 速度非常快,但很难正常工作,而且您遇到的问题是所使用的数据类型通常不能在不同平台之间干净地映射。添加本机依赖项。
  • 带有文本协议(XML、JSON 等)的基于套接字的 IPC - 工作正常,两端可能都支持通用格式,但会增加很多开销。维护自定义模式映射等可能会很痛苦。
  • 带有二进制协议(例如 Google 协议缓冲区)的基于套接字的 IPC - 非常高效,需要大量工作才能使自定义协议在两端正常工作
  • 通过第三个系统(例如数据库、消息队列、文件系统)进行通信 - 大量开销,可能变得脆弱,引入了对第三个系统的主要依赖。

以我的经验,仅仅为了获得一个特定的库或功能而集成一种新的语言/平台通常是不值得的。以您的用户界面为例 - 无论 Adob​​e Air 看起来多么漂亮,我怀疑是否值得尝试将其与现有的 C/C++ 应用程序集成。

即使您让它工作,它也会使您的应用程序的未来维护和开发变得非常复杂。构建变得更加复杂。您需要维护额外的通信/“粘合”代码。您需要管理更多的依赖项。您的用户将受到更多配置问题的影响。测试变得更加困难。教新人整个系统如何工作变得更加困难。您需要在更多语言/框架等方面保持技能。

我推荐以下策略:

  1. 选择主要平台
  2. 每当您需要新的库或功能时,请先在您的主要平台上寻找一些东西。希望(通常?)有一些好的东西可用 - 但即使没有,如果需求非常小,也可能值得自己编写一些东西。
  3. 只有在主平台没有合理选择的情况下,才可以开始考虑整合新的语言/平台

就主要平台而言,我通常建议使用 Java、Scala 或 Clojure 等 JVM 语言,因为 JVM 设计精良、性能出色、可移植性高并且拥有最大/最具凝聚力的库生态系统(其中大部分是开放的)来源)。因此,JVM 可能是最好的“通用”选择,除非您有一些在 JVM 上不太可能实现的非常具体的要求,例如:

  • 如果您正在进行大量需要硬件访问的嵌入式/实时/系统编程,您可能需要使用 C/C++
  • 如果您纯粹为基于 Web 的客户端编写代码,您可能想要使用 JavaScript(如果您也在服务器端编写代码,您可以考虑可以在 JVM 上运行的 JavaScript 代码生成框架/库,例如 Vaadin 或 ClojureScript)
于 2012-08-02T06:34:08.073 回答
2

答案在很大程度上取决于您使用的技术,并且对此没有灵丹妙药的解决方案。

通常,此解决方案将属于以下类别之一:

  • 一些进程间通信技术

  • 语言/平台本身提供的集成

  • 数据库/一些公共存储(甚至文件:))

第一个示例:套接字/管道/操作系统允许的任何内容。CORBA - 允许用不同的语言编写分布式代码。Google protobuf - 允许数据对象的序列化/反序列化及其语言不可知

其次,它实际上取决于您使用的语言/生态系统。java的例子:

  • JNI - Java Native 接口 - 允许在 JVM 之外执行代码 (dlls/so)。
  • JCA - 如果您在企业环境中 - 您可以在其中编写与遗留系统的集成。

对于编译成本机代码的语言来说,它不那么棘手 - 你可以编写和编译一些代码,比如在 Pascal 中,然后在 C 中使用 DLL。

有时当我们谈论 Java 时,有很多语言都有自己的语法和编译器,但它们的编译器编译成可以在 jvm 中运行的 java 二进制代码。因此,如果您的解决方案基于这些语言,则集成会更容易。Scala、Groovy、Closure、Jython 等语言都属于这一类。

最后但并非最不重要的技术是 Web 服务。这是一个非常流行的用于集成不同系统的工具,尽管它更多地用于企业环境。基本上它是对套接字层的抽象,允许在进程/服务器之间以 XML/JSON 格式发送数据对象。XML 和 JSON 都与语言无关,因此在用 C++ 编写的程序中创建 XML 然后在 JAVA 中使用它不是问题。

希望这可以帮助

于 2012-08-02T06:02:32.957 回答