如你所见,在过去的几年里,发生了快速的变化(这句话,我已经说烂了)。好比如说:
在经历了与公司大佬、同事、社区大佬等的一系列的技术讨论之后,以及近年来开始云代码开发,我又有了一些新的顿悟。于是,我就撸了这篇文章。 在你失去继续往下阅读的兴趣之前,让我先说第一个结论: 云开发,是一种生于云上的闭环 + 代码化的软件开发方式。它可以让业务人员、开发人员、运营人员等在同一个云端共同协作、透明化地完成整个软件的生命周期(需求、设计、编码、构建、部署、运营),而非相互隔离,又或者是借助于多个软件才能完成工作。 因此云开发是一种解决方案,它解决的问题是:如何以更高效的方式进行软件开发? 作为 v0.1.0 的定义,我对它的定义可能还不是非常准确,但是重点有这么几个:
你看吧,我们过去解决了一个又一个的线下协作问题,现在构建新的线上协作平台的时机已经逐渐成熟了,是时候开始准备构建你们的云开发平台。 我知道你想说市面上已经有这样的工具,比如 xx 的 xx。但是,一来它朝着一个错误的方向前进,你知道的某公司更懂 2B;二来,它包含了大量的功能,但是却没有闭上环。当然了,我只是从官方的首页看到的功能,一眼得到这个所谓的结论。 PS:只要是它们没办法体现我总结的核心三要素,笑~。套不上我的理论,他们一定是错的,手动滑稽,逃~。 引子 1:核心三要素 这三个要素是软件开发的要素,只有深入要素本身,才能成为真正的云平台。 我不想多说废话了,手疼。 如果基础设施真的已经是基础设施,那么你不应该在云平台强调它们。这就是为什么尽管基础设施很重要,但是却不是核心要素之一。基础设施已经是一个通用域,作为一家时髦的公司,如果你们还没有…… 微架构 微架构,即以模块化的组合方式协同构建大型应用(前端、后端、App 等)的架构方式。每个微应用都可以独立开发、独立部署、独立运行,对应的替换的方式有模块化、子模块的方式,微服务、App 插件化(独立构建、独立运行)、微前端等。 微架构是一个模式,它不是银弹,它以技术的方式拆解了复杂软件架构,适合于复杂场景下的问题,还有人类脑容易不够大的问题。
五年前,Martin Fowler 和 James Lewis 一起写下了那篇《微服务架构》,微服务成为了今天新项目的主流架构之一。最近几年来,它结合着《领域驱动设计》这把锤子,已经成为了一个利器。 作为服务导向架构的一种实现方式,掌握它背后的设计与实现模式,是云开发中不可或缺的重要一环。
两年多以前,我在 GitHub 写下了我的第 N 本电子书《Serverless 架构应用开发指南》,而在最近 Serverless 终于在国内慢慢有一点的热度。两年前,我陆续收到阿里云、腾讯云的 Serverless 尝鲜体验(作为一个 MVP 还是没白混),但是它们并不成熟,甚至于无法调用自己的云服务。而今天,越来越多的云厂商的 Serverless 终于可以跑起来了。 同理于服务导向架构 BAAS (Backend as a service)又或者是 Serverless,也是如此,它们进一步拆解了复杂问题到人能 handle 的范围。
最近几年,对于 App 来说,开发者也探索出了大量的微架构方案。我习惯地称它们为应用即『插件』,因为 App 作为一个基座,提供了各式各样的能力。就目前来说有三种展现方式:
尽管让人们下载 App 的成本越来越高,App 平台化成为了一种趋势。 哪怕 App 的原生仍占很重要的一部分,但是 App 平台的方案 + 应用插件化模式的生态构建,也是云开发要考虑的重要因素。
今年是微前端开始火爆的一年,微前端框架层出不穷:SingleSPA、Mooa、qiankun、ngx-planet,还有诸如于《前端架构:从入门到微前端》这样的书籍。它让越来越多的企业开始思考前端架构的未来,也完善丰富的微前端相关的基础设施。从某种意义上来说,这是组件化的一种方式,只是原先的组件只是简单的 UI 组件,而现在的组件是一个完整功能的应用。只需要设计好对应的 pipe,就能完成一个应用的开发。 而随着 5G 的到来,微 “服务化” 前端应用、Web Component 的体积已经变得让人可以接受。进行功能编排,将成为云开发的一个重要组成——毕竟,插件市场的不断火爆,可以看出一些端倪。 代码化 对于这部分的一句话总结是:
然后,以下大概就是三种完全不同的模式。
起先我只有两种模式,直到月初在公司内部听到了相关的分享,Get 了第三种模式:面向于大型组织的类型流 (https://github.com/notyy/TypeFlow) 开发。 这种方式颇为适合大型组织的软件开发模式,由高级工程师设计出基本的模型与软件架构,生成对应的方法名称,以及其所需要的返回结果。这种模式事实上在过去已经有了,剩下的就是普通的开发人员去填充对应的代码。再结合 Serverless 等基础设施,便可以直接集成上线。 它表面上看它是设计生成的代码,实则设计即代码。
年初,我写下了那篇《无代码编程》,通过这篇文章,我结交了更多无代码/低代码已经有大量的案例表明,这是一种可行的开发模式。 无代码编程的本质是业务模式 + 编程模式的抽象化,以领域特定的场景解决领域特定的问题。所以,低代码编程 / 无代码编程它只能解决领域特定、简单场景的需求,无法解决大部分的问题。 无代码编程做了一件了解不起的事情是,直接对于业务和设计即需求的抽象,实现了直接由需求到代码的直达。
DSL 即 DSL,即把每件事物都变成 DSL。考虑到我正在编写一篇关于 DSL 如何设计的文章,我就不展开详细的讨论:
而代码本身也应该是一种 DSL,才能进一步完成云平台的建议。需求、设计、代码、构建、部署、运营都应该抽象成 DSL,才能完成真正意义上的云平台。 协作设计文化 软件开发是一个集体行为,软件设计也是一个集体行为。所以,一个好的云开发平台应该要融入共同协作的基因。
采用了敏捷,却始终敏捷不起来,有一部分的原因在于:部门墙。对于非互联网公司来说(对于大部分互联网公司也是如此),开发一个软件往往需要在多个部门甩锅:业务部门、技术部门、测试部门、市场部门……
以我多年的读书经验来看,人们采用开发出失败软件的原因,无非就是两点:『缺少协作设计』和『知识传递』。对了,还有技术水平不行,这个反而不是那么重要。 而 《DDD (领域驱动设计)》和事件风暴,正是软件开发文化的一种实践,通过协作设计的方式,传递知识,以妥协出符合大家需要的应用。
可能是我对于中台的误解,我习惯性称中台为『不可清空的垃圾回收站』。但是,它做了一件不可思议的事件,将 “基础设施服务” 化,成为了一个 common 的 common 的 common。好了,调侃到此结束。 随着中台建设的进一步完善,大量的基础设施,将从原先的各个业务部分,统一到了这个 ~~垃圾回收站~~ 大平台。 有了这个基础部分,我们才能迈向下一步。 引子 2:编程的本质 好了,我要继续瞎扯了,首先再次回答那个问题,如何以更高效地方式进行软件开发?那么,首先我们需要找到一个解决方案,以应对那个问题:如何解决人类智商不够的问题? 解决复杂问题 于是,首先,让我们引入 Cynefin 框架来解决复杂问题。 PS:复制和粘贴大法好啊,一时爽一直爽。
有了这个框架之后,我们便来到了第一个结论。对于编程来说,我们的关键性问题在于:如何将复杂问题繁杂化?因为简单的问题便简单,繁杂的问题也容易解决。 复杂问题的应对之道 什么是复杂问题? 引用公司大佬的三句话:
这三个问题的答案暂不免费公开,有意者可以咨询我 —— 其实都在本文里。 看完文章后,回过头来回顾一下这个问题。 大型组织的软件开发模式 为了解决上述的问题,对于大型组织来说,采用的第一个模式就是:拆解。
而就当前而言,这几个部分存在一些割裂。代码反应架构,架构实现代码。缺少相应的架构守护、质量门禁等等,并且诸如于 review 的工作是由机器完成的。 云开发 好了,看到这里不容易。因为剩下的内容已经不重要了。 什么是云开发? 再一次地,让我们看一下定义: 云开发,是一种生于云上的闭环 + 代码化的软件开发方式。它可以让业务人员、开发人员、运营人员等在同一个云端共同协作、透明化地完成整个软件的生命周期(需求、设计、编码、构建、部署、运营),而非相互隔离,又或者是借助于多个软件才能完成工作。 于是乎,它不同于云主机 / 远程主机开发模式,只需要一个浏览器 / 客户端 / IDE,便可以在线完成:
举起我的炒板栗:
它基于这么一些原则:
要的就是这么简单,对于开发来说,只是对应于领域建模、详细设计、填空式开发等。 如何构建云开发平台? 成熟度模型 就定义来说,我们可以将其划分为五个阶段:
第一个阶段。靠人海战术就可以实现了。 第二个阶段。依赖于抽象软件开发模式。 第三个阶段。证明自己,体力劳动。 第四个阶段。进一步抽象软件开发。 第五个阶段。抽象人工部分,智能完成。 所以,嗯,大概要 N 的时间才能完成这个系统的设计。毕竟,云开发是一个复杂问题,我们需要不断拆解系统,结合微架构、代码化、协作设计三个核心要素,以免我们在历史的长河中消失。 云开发平台基石 虽然,我一直在强调实现只是一个细节,但是还是得大致了解一下实现机制。
编码环境 + 设计环境。 微信小程序、支付宝小程序、在线 Web IDE,VS Code / Monaco Editor 几乎已经当前成为了定制编辑器 / IDE 的最好选择。这样一看,JetBrains 再不努力,可能会失去未来,就像当年的 Delphi 一样,笑~。 这方面的技术在业内已经相当成熟了,不就是加一些插件嘛。 不过呢,它们只是在堆砌一些功能,缺乏闭环上的设计:
如你所知的提交信息规范是一种形式,它可以关联到需求;如你所知的领域建模是一种形式,让代码关联到设计上。
尽管,在文章开头的时候,我说了基础设施不重要。但是到真正需要实施的时候,我们不得不强调它的重要性。我们需要的东西有:
而围绕在它背后的是各种模式的提炼。
无论是在哪个行业,值钱的东西在于原则与模式。原则与模式是用来快速提升能力的方式,换句话来说,就是让新手能像以大牛一样的方式工作——尽管会滥用模式。所以:
这些是核心所在,抽象、提取、模式化。
如你所猜想的一样,构建这样一个平台的难点,不在于实现功能,而在于设计。只需要保证在当前阶段的信息,能够传递到下一阶段即可,而不在于你使用什么工具。 你可以使用 Jira、Trello、Mingle 或者基于 Git + DSL 的方式,只需要保证它们能关联到下一阶段,即可。一步步往下,将信息关联到设计、代码、构建、部署、运营,运营再反应到需求上,就能完成上的设计。 So? 原型设计与关键因子 作为模式的拆解,我做了一个简单的分级,以便于一步步实现整个系统: 需求 事实上,采用诸如 Cucumber 一样的 Given-When-Then 三段式设计就够了。所以在我的 story 工具里,利用了注释作为额外的信息扩充。Cucumber 使用的 DSL 已经有丰富的: # id: OGr9CObWR 有了这个设计,我们可以将这个设计结合到我们的下一步设计中。 设计 其实 UML 本身也是一个不错的原型,只需要创建一个 DSL 将其中的一部分转成 UML,再结合一下 UI 上的 DSL 便能实现流程上的设计:
最近,我们在做一个对应的架构设计平台,结合我的 https://github.com/phodal/design 用于代码生成设计,设计转为代码。 代码 代码生成并不是一件新鲜的事物,有大量的人在做大量的事件。编写一个 DSL,用这个 DSL 结合编程语言描述 DSL 来生成不同的编程语言,这便是我最近在做的事情之一。它并不复杂,只是繁琐。 嗯,我花了很多时间在设计这个步骤的两个 DSL,其中一个是生成语言的 DSL,一个则是独立的编程 DSL。 与此同时,对于代码来说,我们关注于:验收标准和适应度函数。 验收标准
适应度函数
借助于此,我们才能承上启下。 构建 对于持续集成来说,需要手动去配置是一个糟糕的事情。所以,我们 Jenkins 使用了 Pipeline as Code 来抽象流水线的构建。但是,它没有真正解决问题,因为现实的软件开发是非常复杂的。对于一个项目来说,它存在过多的分支,不同的构建。所以,真正意义上的持续构建,应该采用诸如于 Pipeline as Pipeline 这样的方式。 部署 事实上,DevOps 技术已经足够的成熟,我们已经能实施相关的步骤:
代码质量的控制,自动化测试,决定了部署成熟度。 运营 这一步,我还不是非常擅长,以我有限的经验来看,现有的工具就够了。唯一要做的事情是,收集数据,抽象模式,构建 DSL,串联起来。
需求 -> 代码 -> 运营,运营反馈需求。 云开发平台成熟度模型 嗯,看标题就够了。
结论 最后,再让我们回到这张图上: 这就是核心所在。 哦,对了,做平台是一件苦逼的事情。 作者简介:黄峰达(Phodal),ThoughtWorks Senior Consultant,CSDN 博客专家。长期活跃于 GitHub、CSDN,专注于物联网和前端领域。出版著作《自己动手设计物联网》,以及《Growth:全栈增长工程师指南》等六本电子书,并译有《物联网实战指南》。 【END】 |
|