当前位置: 首页 > 科技观察

跨平台架构模式浅析

时间:2023-03-21 18:46:24 科技观察

跨平台并不是一个新话题,已经讨论了几十年。在最近的一些尝试中,我对跨平台有了一些新的想法。在这个想法真正落地之前,我梳理了一些不同跨平台解决方案的特点,然后我有了它的几种模式。故事的开头是这样的,受cleanarchitecture思想的影响,从2019年开始,我开始了一个适合分享代码的模式。我尝试了几种不同的想法:使用Serverless+TypeScript构建后台应用,通过将领域模型打包成npm包和子模块实现业务共享,使用Golang+WASM构建前后端交叉核心域,尝试Rust+顺便说一下WASM,但是Rust在这两个领域被后端采用的可能性太低了,除非把原来的C++技术栈Kotlin开发后端应用,把Kotlin2js转成前端库供前端使用。此外,还有更强大的Chapi,可以将任意语言Convert成任意语言。当然,你知道我只是YYing。同一种语言说到跨平台,就不得不说到桌面操作系统和移动操作系统。桌面操作系统的跨平台模式与移动端不一样——桌面端可以使用同一种语言。在移动端,Android主要使用Java、Kotlin、NDK进行游戏开发;iOS主要使用Objective-C和Swift,可以直接编译调用C++库。当没有操作系统限制编程语言的时候,我们就是在同一个世界里使用同一种编程语言。1、封装基于library/patternlibrary的patternlibrary,它是一系列可重用代码的集合,如前端组件,通用实用函数等。在我进入web开发之前,我是一个Qt粉丝(Qt是一个跨平台的C++应用程序开发框架。因为,十多年前,桌面应用程序开发没有太多选择,无论是GTK还是Qt。而且我还是个KDE迷,顺便说一句,我也是个OpenSuSE迷,因为我有最稳定的桌面环境,以前CPU的性能没那么好,JavaScript引擎没那么快,还有Web浏览器只是一个辅助工具,如果要开发跨平台的应用,就得从底层库入手,而开发游戏的人,选择Qt、wxWidgets、Gtk+等框架作为应用基础设施。我习惯调用这样的工具模式库,因为它们将各种模式抽象到代码中,否则如何跨平台?1.1IDE封装模式库细节有了IDE之后,我们就不再关注这些底层细节了。但是,我们还是基于这些模式库。2.交叉编译构建交叉编译是指在一个平台上生成可执行代码到另一个平台上。在我的大学校园里,我接触最多的是嵌入式应用程序的交叉编译,所以我一点也不喜欢这个东西。因为不跨平台,依赖于特定的MCU和SoC的IDE,所以我的代码只能在特定的平台上运行。当我穷的时候,我以为我离交叉编译很远——毕竟你需要三台机器来启动一个Windows、macOS、GNU/Linux,或者一个持续集成服务器来做这样的事情。当我只有一台机器的时候,只有卡卡的虚拟机可以解决我的矛盾。直到去年,我用Golang写了Coca,才重新认识了交叉编译。在macOS下,我可以直接编译一个可以在GNU/Linux和Windows操作系统下运行的语言运行环境,通过平台封装细节,然后将该语言作为API提供给外部系统调用。3.操作系统之上:语言解释器其实很容易理解。比如我们日常使用的Ruby、Python等语言都可以归为这一类。它们封装了底层操作系统的各种细节,并提供了各种API抽象。除了一些特定于平台的代码外,您只需拿起源代码并直接在另一个平台上运行即可。对于那些没有解释器的操作系统,可以使用Pyinstaller等包来为目标平台打包可执行文件。4.Embeddedruntime考虑到嵌入式设备的特殊性,我把embeddedruntime看成一个独立的模式。因为要在嵌入式设备上运行语言解释器,你肯定需要一个操作系统。反过来,针对不同的硬件情况,需要定制大量的API。使用此类架构模型的开源应用包括:使用Lua语言的NodeMCU、使用JavaScript语言的IoT.js等。5.基于应用软件毫无疑问,这是一个使用Lua作为脚本的跨平台架构模型游戏领域的语言,也就是在Web世界中被广泛使用的JavaScript。浏览器/ElectronWeb应用程序是我们使用最广泛的跨平台应用程序。甚至,您不需要使用相同供应商的浏览器来运行相同的Web应用程序。而这些正是浏览器提供的JavaScript+HTML+CSS。JavaScript是少数可以直接从记事本中复制代码并运行的语言之一——毕竟操作系统提供了网络浏览器。由于前端技术的快速发展,生态也越来越完善,使得Electron等框架越来越多的公司采用它作为桌面应用开发框架,最具代表性的就是:VisualStudioCode。工具运行时:EmacsPS:Emacs既是最好的编辑器,也是最好的操作系统。除了浏览器,Emacs还内置了一种称为EmacsLisp的文字脚本语言,通过它可以扩展操作系统的功能。毫无疑问,这种模式的主要目的是将平台语言作为一种扩展的开发语言。搭建一个跨语言的跨语言平台并不是一件容易的事。这部分主要讲跨平台移动应用和跨前端前端应用。6.借助DSL/语言封装差异这几年,跨平台的移动应用框架非常火,正在兴起的有:ReactNative和Flutter。虽然这两个框架的运行机制不太一样,但是考虑到都是框架+语言来封装Android+iOS平台的差异,我还是把它们归为一类。PS:顺便说一句,虽然Flutter在架构上更胜一筹,但它那该死的布局只有原生应用开发者喜欢。然而,开发这样的DSL或语言并不是一件容易的事。从某种意义上说,我们至少需要Androidx1+iOSx1+Webx1+AppDevx1。7.语言转换器通过AST进行语言转换,然后使用一系列的包装器对目标语言进行封装,以便达到用A语言开发B语言应用程序的目的。这在Web前端开发领域很常见。直接从A语言转换成B语言问题不大,但是转换的时候需要考虑核心是什么?frameworkwrapper之类的工具太小众了,永远跟不上前端变化的速度。另外,它的写法可能有点奇怪,举个Scala.js-React的例子:valHello=ScalaComponent.builder[String]("Hello").render_P(name=><.div("Hellothere",name)).buildthis...,太丑了。领域模型复用在我最近的Kotlin2js实践中,我发现领域模型的转换可能是语言转换器的核心。也就是说,有一个用Kotlin编写的单独项目,通过其多平台编译将其转换为其他平台的代码。这样就可以轻松实现其他端领域模型的使用。中间格式/语言8.采用虚拟化您知道我说的是JVM,毕竟:编写一次,随处运行。但JVM只是其中之一,除此之外还有.NET、Parrot等。编程语言层面的虚拟化,将一种高级语言翻译成一种叫做Bytecode的语言,再翻译成命令,可以直接通过一个程序执行虚拟机。嗯,编译生成特定的格式后,通过自己的虚拟机翻译成可执行的命令,就是这么简单明了。对于一个开发者来说,我们经常会接触到这样的工具,也写过一些。我们也用它们来做一些GUI应用,比如我经常用到的ClassyShark。9.中间语言等跨平台、跨语言的工具不常用,因为转中间语言再编译,除了微架构,不常用。RegisterTransferLanguage(RTL)这里我们以RTL为例,我没有这方面的经验。我有一种模糊的感觉,在某些情况下需要这样做,但我一直无法找到一个很好的例子来证明它。寄存器传输语言(英文:registertransferlanguage,缩写为RTL),又译为寄存器传输语言,registertransferlanguage,一种中间语言,用于编译器。(set(reg:SI140)(plus:SI(reg:SI138)(reg:SI139)))GCC的前端(frontend)会先将编程语言翻译成RTL,然后使用后端(后端)转换成机器码。WebAssemblyWebAssembly是一个可移植的抽象语法树,旨在提供比JavaScript更快的编译和执行。对于具有高性能要求的应用程序,这是一种非常好的技术。有了这项技术,用原生语言开发的桌面应用程序可以更容易地迁移到Web平台。现在,您可以将用Golang编写的代码编译为WASM,然后将其提供给JavaScript调用。10.代码生成器不知道为什么又提起这个话题。我一直认为人们会使用中间DSL或数据格式作为中间格式。这样就可以达到解耦的目的,以适应未来的变化。但是没想到可能会直接生成对应平台的代码。然后,您获取代码并在每个平台上对其进行编译。没毛病,还不错,而且效率更高。多平台其实相信上面的大部分模式,你都非常迷茫。都太NB了,以至于一般人做不到。因此,我们拥有多平台技术。它利用各种平台提供的能力来帮助自己更好地构建跨平台能力。当然,这也增加了调试的难度。11、双平台/框架移动应用的第一个重大挑战是面临不同移动平台带来的API挑战。于是,Cordova加紧支持了九个平台,现在只剩下五个了。当我们开发基于Cordova的混合应用程序时,我们在WebView+Cordova之上构建我们的应用程序。大家已经很熟悉了,这里就不多解释了。12.多平台/框架是指通过层层框架和平台构建自己的能力。对用户来说可能相当友好,但对开发者未必。举两个例子:Applet应用:微信平台+WebView+applet框架Ionic应用:WebView+Cordova+Ionic框架那么随着层数的增加,调试的复杂度也会增加,越多越好-rounder。结论没有灵丹妙药。