跨平台架构模式

栏目: IT技术 · 发布时间: 4年前

内容简介:跨平台不是一个新的话题,它已经被讨论了几十年了。在最近的一些尝试,让我对跨平台有了一些新的想法。在想法真正落地之前,我梳理了一下不同跨平台方案的一些特征,便有了它的几种模式。故事的开始是这样的,受整洁架构思维的影响,从 2019 年,我便开始一种合适的模式来共享代码模式。我尝试了几种不同的思路:除此,还有更伟大的

跨平台不是一个新的话题,它已经被讨论了几十年了。在最近的一些尝试,让我对跨平台有了一些新的想法。在想法真正落地之前,我梳理了一下不同跨平台方案的一些特征,便有了它的几种模式。

故事的开始是这样的,受整洁架构思维的影响,从 2019 年,我便开始一种合适的模式来共享代码模式。我尝试了几种不同的思路:

  1. 使用 Serverless + TypeScript 构建后台应用,通过将领域模型打包成 npm 包、submodule 实现业务共享
  2. 使用 Golang + WASM 构建跨前后端核心域
  3. 顺带尝试了 Rust + WASM,但是 Rust 在这一两里被后端采用的可能性太低,除非原有的是 C++ 技术栈
  4. Kotlin 开发后端应用,Kotlin2js 转成前端库,提供给前端使用

除此,还有更伟大的 Chapi ,可以将任意语言转换为任意语言。当然了,你知道我只是在 YY。

同一语言

当我们谈论到跨平台的时候,要谈论到桌面操作系统、移动端操作系统。桌面操作系统的跨平台模式和移动端不太一样 —— 桌面端可以使用同一语言。而移动端 Android 主要使用的是 Java 、Kotlin,配合游戏开发等使用的 NDK;iOS 主要使用的是 Objective-C、Swift,它们可以直接编译、调用 C++ 库。

在没有操作系统限制编程语言的时候,我们在同一个世界下,使用着同一种编程语言。

1. 基于库/模式库封装

模式库,是一系列可复用代码的合集,如前端的组件,通用的 工具 函数等等。

在我还没有接触 Web 开发之前,我是一个 Qt 粉(Qt 是一个跨平台的 C++ 应用程序开发框架。因为,十几年前对于桌面应用的开发,你并没有太多的选择,要么 GTK 要么 Qt。而我还是一个 KDE 粉,顺带还是一个 OpenSuSE 粉,因为有着最稳定的桌面环境。

过去,CPU 的性能没有这么好,JavaScript 引擎速度没有这么快,Web 浏览器只是个辅助工具。若是想开发跨平台应用,得从底层库开始。

嗯,所以,开发游戏的人们,选择了Qt、wxWidgets、Gtk+ 等框架,作为应用的基础设施。我习惯于将这样的工具称为模式库,因为它们抽象了各种模式到代码中,否则怎么跨平台呢?

1.1 IDE 封装模式库细节

在有了 IDE 之后,我们已经不关注于这些底层细节了。但是,我们仍然是基于这些模式库。

2. 通过交叉编译构建

交叉编译是指,在一个平台上生成另一个平台上的可执行代码。

在我的大学校园里,我接触最多的就是嵌入式应用的交叉编译,所以我一点儿也不喜欢这个东西。因为它算不上是跨平台的,还依赖于特定 MCU、SoC 的 IDE,我的代码只能运行在特定的平台上。

当我因为贫穷的缘故,我以为我离交叉编译远了——毕竟,你开始一个需要三台机器 Windows、macOS、GNU/Linux,又或者是通过持续集成服务器来做这样的事情。当我只有一台机器的时候,只有卡卡的虚拟机能解决我的矛盾。

直到去年,我使用 Golang 写了 Coca ,我重新认识了一下交叉编译。在 macOS 下,我可以直接编译出可以在 GNU/Linux、Windows 操作系统下运行的

语言运行环境

通过平台封装细节,而后提供语言作为 API 来给外部系统调用。

3. 操作系统之上:语言解释器

这一点实际上是非常容易理解的,比如我们日常使用的 RubyPython 等语言,都能归属于此类。

它们封装了操作系统底层的各种细节,提供了各种 API 抽象。除去部分平台特定代码,只需要拿起源码,便能直接到另外一个平台上运行。

而对于那些没有解释器的操作系统来说,可以采用诸如 Pyinstaller 便可以打包成目标平台的可执行文件。

4. 嵌入式运行时

考虑到嵌入式设备的特殊性, 我将嵌入式运行时,视为一个独立的模式。因为在嵌入式设备上跑语言解释器,你一定需要一个操作系统。反过来,针对于不同的硬件情况,还需要定制大量的 API。采用这一类架构模式的开源应用有:采用 Lua 语言的 NodeMCU,采用 JavaScript 语言的 IoT.js 等。

5. 基于应用软件

毫无疑问,这是游戏领域使用 Lua 作为脚本语言,还是 Web 世界被广泛使用的 JavaScript 的一种跨平台架构模式。

浏览器 / Electron

Web 应用,是我们使用最广泛的跨平台应用了。甚至于,你并不需要使用同一个厂商的浏览器,就可以运行起同一个 Web 应用。而这些正是浏览器提供了 JavaScript + HTML + CSS。JavaScript,是少数几个可以直接抄起记事本就能撸代码,并能跑起来的语言 —— 毕竟操作系统都提供了 Web 浏览器。

而正由于前端技术的速度发展,生态变得日益完善,使得诸如于 Electron 这样的框架,让越来越多的公司采用它来作为桌面应用开发框架,最具代表性的便是:Visual Studio Code。

工具运行时:Emacs

PS:Emacs 即是最好的编辑器,也是最好的操作系统。

除了浏览器之外,Emacs 还内置了一个名为 Emacs Lisp 的直译式脚本语言,通过这个语言来扩展这个操作系统的功能。

毫无疑问这种模式的主要目的是,将平台语言作为扩展的开发语言。

跨语言

构建跨语言平台并不是一件容易的事情。这一部分讲的主要是跨平台移动应用和跨前后端应用。

6. 借助DSL / 语言封装差异

在过去的几年里,跨平台的移动应用框架非常火热,其中呈上升趋势的便是: React Native 和 Flutter。尽管两个框架的运行机制不是很相同,但是考虑到都是框架 + 语言来封装 Android + iOS 平台的差异性,我还是把它们划到同一类。

PS:顺事一吐槽,尽管从架构上说 Flutter 更加优秀,但是它那该死的布局也只有原生应用开发者会喜欢了。

然而,要开发这样一个 DSL 或者语言,并不是一件容易的事情。从某种意义上来说,我们至少需要 Android x 1 + iOS x 1 + Web x 1 + AppDev x 1。

7. 语言转换器

通过 AST 来进行语言转换,再借助于一系列的 wrapper,来封装目标语言上的框架,以实现使用 A 语言开发 B 语言应用的目标。这一点常见于 Web 前端开发领域。

直接从 A 语言转换 B 语言,并没有太大的问题。但是,在转换的时候,我们需要考虑一下核心是什么?

框架 wrapper

这一类的工具过于小众了,而且它永远跟不上前端的变化速度。除此,它的写法可能有些奇怪,举个 Scala.js-React 的示例:

val Hello =
  ScalaComponent.builder[String]("Hello")
    .render_P(name => <.div("Hello there ", name))
    .build

这……,好丑。

领域模型复用

在我最近的一次 Kotlin2js 的实践中,我发现对于领域模型的转换可能才是语言转换器的核心所在。

即存在一个单独的项目使用 Kotlin 编写,通过它的多平台编译,把它转为其它平台的代码。这样一来,便可以轻松地达到领域模型在其它端的使用。

中间格式/语言

8. 采用虚拟化技术

你知道我在说 JVM,毕竟:Write once, run anywhere。不过 JVM 只是其中的一个,除了它还有 .NET、Parrot 等。

程序语言级别的虚拟化,会将高阶语言转译成一种名为位元组码(Bytecode)的语言,透过虚拟机器转译成为可以直接执行的命令。

嗯,经编译完生成特定的格式后,通过自已的虚拟机就可以转译为可执行命令,就是这么简单直接。

对于一个开发人员来说,我们经常接触到这样的工具,也写过一些。我们也通过它们来做一些 GUI 应用,比如我用得比较多的 ClassyShark。

9. 中间语言

这一类跨平台、跨语言工具并不常用,因为转成中间语言再编译的话,除了微架构,并不常见。

暂存器传递语言(RTL)

这里让我们先用暂存器传递语言作为一个示例,我没有这方面的经验。我隐隐约约觉得存在一些情况,需要它,但是我还没有找到合适的例子证明。

暂存器传递语言(英语:register transfer language,缩写为 RTL),又译为暂存器转换语言、寄存器转换语言,一种中间语言,使用于编译器中。

(set (reg:SI 140)
     (plus:SI (reg:SI 138)
              (reg:SI 139)))

GCC 的前端(frontend)会先将程式语言转译成 RTL,之后再利用后端(backend)转化成机器码。

WebAssembly

WebAssembly 是便携式的抽象语法树,被设计来提供比 JavaScript 更快速的编译及运行。对于性能要求高的应用来说,这是一个非常好的技术。有了这一项技术,那么那些使用原生语言开发的桌面应用,就可以更容易地迁移到 Web 平台。

现在,你可以将你的 Golang 编写的代码编译到 WASM,然后提供给 JavaScript 调用了。

10. 代码生成器

我不知道为什么又扯到了这个话题。

我总以为人们会以一种中间 DSL 或者数据格式来作为中间格式,这样一来,可以实现解耦的目的,以适应未来的变化。但是没想到还可能直接生成了对应平台的代码。然后,你拿着代码去各个平台编译一遍。

没的毛病,挺好的,效率更高。

多重平台

事实上,我相信上面的大部分模式,你都是的懵逼。它们都过于 NB,以致于不是一般人能做的。所以,我们就有了多重平台技术。它利用了各种平台提供的能力,以帮助自己更好地构建跨平台能力。

当然了,随之也提升了 debug 的难度。

11. 双重平台/框架

移动端应用的第一大挑战是,面对不同移动平台带来的 API 挑战。所以,Cordova 站了出来,支持了九个平台,现在只剩下了五个。

当我们开发一个基于 Cordova 混合应用时,我们便是基于 WebView + Cordova 之上构建我们的应用。大家都已经很熟悉了,这里就不熟悉说明了。

12. 多重平台/框架

即通过一层层的框架和平台,来打造自己的能力。它对于使用者人员来说,可能相当的友好,但是对于开发者来说,不一定如此。举两个例子:

  • 小程序应用:微信平台 + WebView + 小程序框架
  • Ionic 应用:WebView + Cordova + Ionic 框架

嗯,随着层数的上升,调试复杂度会越来越多,也越需要一个尽可能的全才。

结论

没有银弹。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Beginning iPhone and iPad Web Apps

Beginning iPhone and iPad Web Apps

Chris Apers、Daniel Paterson / Apress / 2010-12-15 / USD 39.99

It seems that everyone and her sister has developed an iPhone App—everyone except you, the hard-working web professional. And now with the introduction of the iPad, you may even feel farther behind. B......一起来看看 《Beginning iPhone and iPad Web Apps》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具