假设我用Haskell或Erlang(或任何其他语言,都无关紧要)编写了一个应用程序,我希望它能用更友好的gui语言(我的观点)与我的gui一起工作,比如Python。如何把这两个粘在一起?您将如何在应用程序的这两个部分之间进行通信?做某种服务器什么的?这种解决方案流行吗?我见过SMplayer这样的东西,它是mplayer的gui,运行得很好。你对这种设计有什么想法?
我在Haskell中使用这两种方法(客户端/服务器、本机)编写了应用程序{dis}advantages.我意识到这比你要求的更多,但我已经记录了这两种方法的优缺点,希望它能帮助你做出更明智的决定。
更具体地说,我使用的方法是:
- 使用Haskell作为后端,使用Javascript/HTML作为前端的Web应用程序。通信仅使用JSON完成。后端没有生成HTML或Javascript
- 使用GTK2HS在纯Haskell中原生
第一种方法的优点是:
- 我被迫将GUI代码与后端逻辑分离。这绝对是为了更干净的设计
- Haskell现在拥有高性能的Web服务器[4,5]。如果你想在第三方网络服务器上编写PHP风格的脚本,它还提供了很好的CGI/FastCGI和数据库支持。我使用了后一种方法,效果很好
- UI库现在已经足够好了,用Javascript构建前端是一种非常愉快的体验。我对Qooxdoo[2]很满意,但有几个选项(jQuery、ExtJS…)
- 软件事务性内存[3]使得在服务器端存储并发访问的状态变得微不足道。STM是这种方法可行且有趣的最大原因
- 我喜欢UI的一致性,并且可以轻松地部署到任何可以运行web浏览器的平台上。如果你的应用程序必须在Mac、Windows和Linux上运行,我仍然认为这是最好的方法(详见下文)
第一种方法的缺点是:
- 即使我知道这是一个单用户应用程序,我也必须处理身份验证和会话。现在有一些框架(Yesod、Happstack…)可以帮助解决这个问题,但我认为这是一种偶然的复杂性,可以通过编写本地应用程序来避免
- 我不得不推出自己的客户端/服务器通信协议。扩展协议并确保其正确性在Javascript端是痛苦的,但在Haskell端却是绝对的快乐。我怀疑您选择的任何GUI友好语言/Haskell组合都会出现这种情况
- 我的大部分代码最终只是对JSON数据进行编组和解编组。这现在不那么成问题了,因为我认为有很多Haskell-lib可以实现自动化[1]
- 大多数主机不支持Haskell应用程序
第二种方法的优点是:
- 所有的开发都使用相同的语言,因此测试起来更容易
- Glade是可视化构建GUI的好工具,Haskell集成非常好
- 在Windows和Linux上部署很容易
- GTK2HS是非常好的,完整的和良好的记录
- 绑定还试图镜像GTK本身的OO结构。这有缺点(见下文),但最大的优点是我能够使用其他语言绑定的文档来填补任何文档空白。当我开发的时候,我一直在参考Python优秀的GTK文档
第二种方法的缺点是:
- 在Mac上部署GTK2HS应用程序太可怕了,而且启动起来也很难看
- 在Windows上安装GTK2HS并非易事,在Mac上这是一个开放的研究问题
- GTK2HS要求您编写非常的unidiomatic Haskell。到处都是可变的状态,缺少对象意味着你本质上是在写过程代码
希望这不是TMI。
-deech
[1]http://www.google.co.uk/search?hl=en&as_sitesearch=hackage.haskell.org/2Fpackage&as_q=json
[2]http://www.qooxdoo.org
[3]http://www.haskell.org/haskellwiki/Software_transactional_memory
[4]http://hackage.haskell.org/package/warp-0.3.2.3
[5]http://snapframework.com/
您可以这样做:
- Haskell或Erlang中的核心程序可以在命令行上单独运行,并带有控制台提示等
- 任何语言的GUI都会启动核心程序,并通过核心的stdin和stdout驱动它
gdb(core)/ddd(GUI)使用了这种方法。这使您可以在命令行上轻松地调试内核。使用这种方法,您还可以使用核心、单元测试等轻松地执行批处理脚本。
如果您所说的gui友好语言意味着拥有Visual gui Designer,那么您仍然可以在haskell中执行。两个主要的linux GUI框架,GTK和QT都有可视化设计器,您可以使用它们从haskell生成的GUI文件。
查看gtk2hs或qthaskell库。
Thrift支持Haskell、Erlang和Python:
Thrift是可扩展的跨语言服务发展它结合了一个软件使用代码生成引擎堆栈构建高效工作的服务并且在C++、Java和Java之间无缝连接,Python、PHP、Ruby、Erlang、Perl,Haskell,C#,Cocoa,JavaScript,Node.js、Smalltalk和OCaml。
您有两个明显的选项:
- 将整个应用程序放在一个进程中。这通常涉及Windows DLL(本机、COM、托管程序集等)或Unix共享对象
- 使用IPC机制在应用程序的两个部分之间进行通信
一般来说,如果所讨论的语言是可接受的,则选项1是优选的。
它将取决于您想要为GUI和逻辑使用的确切语言。正如大卫所回答的,你基本上只有这两个选择,它们都有优点和缺点:
把所有东西都放在一个应用程序中是最好的性能,因为当你调用另一种语言时,它不会等到另一个进程获得控制权,然后也不会等到你的进程再次获得控制权才能收到答案。这也是最简单的解决方案,如果你可以将一种语言嵌入另一种语言中,那么它们将在同一过程中运行。
如果您一直在"逻辑"过程中做很多事情,但希望gui仍然具有响应性,那么使用不同的过程可能会很好。(尽管这也可以通过线程在单个进程中实现)。此外,如果你不能嵌入语言,这将是最简单的解决方案。(例如,使用IPC的简单套接字,这些套接字存在于几乎所有的语言中,并且是真正可移植的
因此,这实际上取决于你将选择的语言。