Blog
Blog
PHODAL

Viewing posts from April, 2020

Serverless 越来越火,无代码编程也提上了议程,还有云开发也在风口浪尖。那么,未来会是怎样的呢?

这篇文章的草稿差不多在我的 todo 列表里躺了一年,直到最近,看到我的同事在吐槽手动创建步骤的繁琐性。我才想起来,我曾经想写一篇这样的文章,但是我在我的博客( https://www.phodal.com ) 上找了好久,也没有发现。然后,我终于在我的 To-Do 应用中看到了它的身影。 虽然说是模式总结,到底只是个人经验。受限于个人经验,可能有些许的不足之处。若是各位读者愿意指出来,那自然感激不尽。 ## 开发过程:IDE 代码片段『精选』 > IDE 代码片段『精选』即在 IDE/编辑器中,通过插件或者内置组件,对特定语言、框架、技术等提供自动化的代码填写。 代码集这个东西,自然比较是比较有意思的。在我们的日常开发中,我们经常会使用到,它的名字有多样多样,如 - AutoComplete - Snippets - 智能感知 - …… 它倒也没有什么特别之处,在我们输入一些词的时候,给我们建议,如在 IDE 里输入 `list.for`,过程中就可以生成如下的代码: ```kotlin for (item in list) { } ``` 嗯,就这么简单,是不是经常使用到。 ## 开发过程:语言、框架抽象 DSL > 语言抽象 DSL,即通过编辑器、IDE 内置对于语言和框架的抽象,使开发人员可以通过编写 DSL 便可以生成特定语言的代码。 它特别适合于编写简单的模板代码,如 HTML、XML 等。作为一个开发人员,那么最常看到的例子就是 Zen Coding/Emmet,这个东西非常炫,输入 `ul>li*5>a[href="#"]`,然后按一下 tab,你就可以快速生成如下的代码: ```html
``` 嗯,它特定适合于编写结构化的代码格式。 ## 创建时:模板化代码生成 > 模板化代码生成,即在代码 or IDE 中内置特定系统、团队的代码范式,随后通过特定的参数,来生成适合于该团队和该系统的代码。 考虑到前端领域创建模板的复杂性,创建的过程中,需要同时创建 `*.component.scss`、`*.component.spec.ts`、`*.compnent.ts`、`*.component.html`,所以在前端领域非常之流行。最简单来说,Angular 开发人员通过 `ng g` 就可以生成各式各样的代码。 事实上,我觉得对应于后端开发也是如此,毕竟创建一个 CRUD API 可能需要 `model`、`repository`、`api`、`service` 等。不过,依我的观察来看,后端开发人员一般都没有 GET 到这项技能,因为 gradle 太 TM 难用了。 尽管,大部分框架都自带了类似的生成器,但是大多数时候,都得自己撸一个适合于架构的模板。所以,这里推荐一下适用于前后端的框架。 ### Angular Schematics > Schematics 是前端开发工作流工具,例如:创建一个组件、变更配置项至当前项目,并且不限制任何语言环境。 ### Plop > Plop 是一个微型生成器框架。它提供了一种以一致的方式生成代码或任何其他类型的纯文本文件的简单方法。 嗯,这两个框架,大家自己了解一下。 ## 创建时:DSL 生成代码 > DSL 生成代码,顾名思义就是通过 DSL 的方式,来生成代码,再集成到系统中开发。 最常见的一个例子就是我最近使用基于 Antlr 编写的 Chapi,便是这种模式。又或者是,对于一些模式化的开发的系统来说,它们也是通过类似的方式来生成大量的模板。 注意:通过这种模式生成的代码,往往是不会进行二次开发的。因为随着引擎的更新,这些代码会被覆盖住,导致难以维护。 如 Antlr 这样的框架,只需要通过: `antlr -Dlanguage=Java -listener -visitor CPP.g4 -o chapi/ast/antlr -package chapi.ast.antlr` 编译生成到指定的目录。于是乎,我们就可以 `import chapi.ast.antlr`,集成到系统中使用。 ## 构建时:DSL / 代码生成代码 > 构建时代码生成代码,即在构建的时候,才进行代码生成。 对于稳定的系统来说,可以只在构建时才运行代码生成。平时的时候,都是通过生成临时代码的方式。嗯,常见的 Angular 框架就是类似的方式运行的。 在开发的过程中,我们都是通过编码 DSL 或者是一种不同于最终运行语言来编写的。 ## 运行时:元编程 > 元编程(Metaprogramming)是指某类计算机程序的编写,这类计算机程序编写或者操纵其他程序(或者自身)作为它们的数据,或者在运行时完成部分本应在编译时完成的工作。 这一点大家都很熟了,我就不再重复描述了。 ## 未来 随着,无代码编程/低代码编程越来越流行,代码生成的基础架构来越来越火。

人的智商不够、又或者是脑容量不足以容纳这么多的知识。所以,对于个人来说,我们工作的时候,依赖于文档、笔记、文章,来帮我们回忆起这些知识;对于组织来说,知识传递是需要知识管理的一个关键因素。

在 Ledge 知识平台 发布的这一周多里,我一直在思考如何让这个项目做得更好。在和 CSDN 编辑的讨论中,我意识到我可以把这个过程中的相关经验分享出来。因为毕竟大部分的开源项目做得不好。

PS:文章仅为个人观点 —— 本文的内容基于我这几年在开源世界的观察得出的结论,并非调查所得到的结果。 上周,我在 GitHub 上发布了 Ledge 知识平台,我以一种“重量级”的方式来运行这个开源项目。换句话来说,以正确的方式运行起了这个项目。因为我知道怎么运作一个开源项目,加上一些外部的原因,我开始思考个人开源和组织开源的一些困境。 开始之前,让我讲个笑话和无奈: 组织开源的四大笑话是:一次性开源、按揭开源、KPI 驱动式开源、社区是什么?(分别代表了国内的几加大公司的开源做法) 不好意思,你们是对开源有什么误解吗? ## 什么是开源 事实上,我们经常混淆了两个概念,那就是开源软件和开源这个行为。 > 开源软件是源代码可以任意获取的计算机软件,任何人都能查看、修改和分发他们认为合适的代码。开源软件依托同行评审和社区生产,皆以分散、协作的方式开发。 —— 红帽官网 换句话来说,你选择一个协议,将你写的代码公开发布,这叫开源一个软件。但是,它并不叫你搞开源。开源源于开源软件,但是它现在已经成为超越软件生产的运行和工作方式。 > 开源源于开源软件生产的运行和工作方式,它是一种基于去中心化、自组织式的软件开发模式运作的工作方式。它以社区作为根基,通过开放、透明、协作几项原则开展的活动。 ## 开源不是公开代码 在那本开源的《GitHub 漫游指南》里,我一直在讲述如何在 GitHub 上开发一个 “成功” 的开源项目。因为开源不仅仅只是说源代码的开源,还包含了设计文档、产品的内容等等,还要以开源的方式来运作。以 opensource.com 对于开源方式的解释来说,需要这么五个维度: 1. 透明度。 2. 协作。 3. 尽早发布、持续发布。快速建立原型,发布第一个版本,并且不断地快速地迭代。 4. 精英制度。根据提出的最佳方案做决定的方式 5. 社区。形成社区,提升社区参与度,转化为社区目标。 也因此,如果只是公开源码的话,那是走到开源的第一步,刚来到开源的起跑线上而已,还没参与到这个游戏中去。 ## 一个开源项目是一个产品 作为一个资深的开源运动参与者,我有一个这样的体会:运营一个开源项目,就好像创业一样。我们需要采用《黑客与画家》作者 Paul Graham 所说的创业公式: 1. 搭建原型 2. 上线运营 3. 收集反馈 4. 调整产品 5. 成长壮大 所以,开源就像是一场小型创业,需要进行竞品分析,需要制定合理的策略。当然了,如果你的东西绝无仅有,那就无需如此。而除了分析市场,针对于开发人员,还要考虑: 1. 作为投资人(技术投资),他们能获得什么?提升技术?找个好工作? 2. 作为潜在的用户,从哪里知道这个项目? 3. 作为贡献者,如何提供不同级别的贡献计划? 4. …… 你并不一定非得去考虑这些问题,只要在持续完善的过程中,这些问题的答案就会浮现出来。只是呢,在你开始之前想好,可能会事半功倍。 ## 开源的重点在于生态建设 对于个人来说,开源的目的可能是找个好工作、为以后找个好工作……;对于一家组织来说,他们考虑开源可能有多种多样的目的: 1. 降低开发、维护成本。由社区来帮助寻找 bug,提出一些观点。 2. 技术影响力招聘 3. 建立技术壁垒。 4. 营造生态。 5. …… 一个好的开源作品,需要连接到上下游,即影响开发者,又影响使用者。慢慢地,它个作品就会成为一个影响行业的存在。尽管会不断有其它的项目冒出来,但是由于稳固的生态建设,将巩固组织在该领域的影响力。 ## 组织需要制定开源策略 从开头的大部分四大难题:一次性开源、按揭开源、KPI 驱动式开源、社区是什么?。我们就会发现:国内大公司的开源策略都是错的。 他们可能,今年发布 Phodal UI,明后发布 Phodal Compiler,后年发布 Phodal OS。然后,中间靠各种公关稿,完成在社区的宣传。 应该是这样的,今年发布 Phodal UI 1.0,年中发布 Phodal UI 2.0,明年发布 Phodal UI 3.0 和 Phodal Compiler 1.0,明年年中 Phodal UI 4.0 + Phodal Compiler 2.0。过程中,需要依赖于布道师来进行闭环: 1. 维护开发者关系 2. 在社区进行宣传 3. 对社区进行支持、收集社区反馈 4. 建立连接内部的通道 5. 促进内部进行改进。 这些组织需要建立一个具备可持续性的开源策略: 1. 明确其带来的业务价值(如人才引进 、生态等) 2. 专职的开发人员进行开源支持 3. 开放式的开源团队组织结构 4. 合理、适当地长期 KPI 考核机制 5. 政策和流程支持。如专项鼓励奖金 6. 明确地专利和知识产权机制 ## 开源到开放式组织 领导力变化,当我们在组织中开发一个软件应用时是以职权影响力为核心构建的;而开源方式,则是以非职权影响力构建的。 社区的每个人都可以提出自己的意见,你可以 say No,但是每个人都可以提出意见。就这一点来说,对于大部分的国内公司来说是一种挑战,大部分的领导希望听到统一的声音 —— 论组织内多样性的重要。 简单来说,大家想来就可以来,想走就可以走。所以,开源的一个难点就在于:如何吸引到人来参与开发。 尽管大部分项目都是围绕个人、团队的中心化开放式组织,如 linus 之于 Linux。但是,开源还可能变成一个中心化的组织,如 Node.js 的 IO.js 出走事件。根据开源协议,人们可以很容易派生出一个新的项目。 ## 结论 开源,就是生态。

> 文档代码化,将文档以类代码的领域特定语言的方式编写,并借鉴软件开发的方式(如源码管理、部署)进行管理。它可以借助于特定的工具进行编辑、预览、查看,又或者是通过专属的系统部署到服务器上。面向非技术人员的文档代码化的一种常见架构模式是:编辑-发布-开发分离』,

最近,我在设计、开发、维护一个基于『文档代码化』思想的平台。因为丰富的 markdown 经验和文档化系统的设计经验,我在这个系统中实施了很多过去的一些想法。系统工作得很好,但是代码却显得一片混乱。而,我突然觉得这是一件好事。 ## 最佳实践很浪费时间 对于敏捷开发来说,我只采纳了持续集成和持续部署的思想,即提交代码便发布到 GitHub Pages。但是,这也浪费了我很多的时间,而且我觉得没有必要,因为我已经有一个本地可以部署的脚本。我只需要在本地运行一下 ``deploy``,那么就会在本地构建,并部署到服务器上。然而,为了最佳实践的理念,我还是花了半天的时间,研究了一下 GitHub Action,然后让它实现自动部署。 系统的 UI 采用的于 Angular 框架,因为我懒得搭建脚手架,而且我还有一些先前的代码可以复用。所以,我 copy / paste 大量的代码,这些代码大部分都是没有测试覆盖的。是的,你很少看到我的开源项目是没有测试覆盖的 —— 毕竟写单元测试也是要花时间的。过去,我们统计过一个相关的数据,在我们日常的开发中,我们差不多有 1/5 的时间花在了单元测试。所以,一周下来,我差不多一天的时间在写测试这件事上。 ## 一个问题,三种方法实现 如开头所说,整个系统的核心是一个基于 markdown 的多功能渲染引擎。这部分的组件可以让你用 markdown: 1. 画出条形图、雷达图、思维导图 2. 画出甘特图 3. 画出特定的四象限 4. 调用 Web Components 5. …… 而为了实现这个功能,一共有三套不同的机制,当然了对于写 markdown 的人来说,它们是无感知的。这三种方法分别有: 1. 创建占位符,渲染完成后,替换占位符 2. 直接生成最后要渲染的 HTML 3. 生成一个 ID,在渲染的过程中,根据 ID 替换元素。 所以,整个过程就相当于,是解决一个问题有三个方法,然后我都用了这三种方法。 ## 起初,我只想创建个原型 起初,我只是想创建一个简单的系统,它只是一个简单的原型。而后,随着越来越多想法的产出,我创建了一个足够复杂的系统。所以,我起初设计的一系列要素都失效了。 我还有一堆糟糕的 SCSS 要管理,因为第一个版本设计的 CSS 体系,无法适用于新的架构。整个系统围绕在 markdown render 上,而这个 render 有大量的样式,就好像早期的多核 CPU 架构,只有一个 CPU 在工作,毕竟有大量的工作。 随着系统越来越复杂,我开始需要一个文档系统来管理这个文档系统,以便告诉我自己:系统里有什么功能? ## 一片混乱,真的很爽 是的,现在,现在虽然看上去界面很美观,功能也很强大。就好多是我们看到的其它软件系统一样,但是内部真的是一片混乱。如果你习惯了这样的系统的代码,那么你可能觉得这不是一个问题。 但是,我习惯了在项目中引用各种最佳实践。看了这样一个系统,觉得非常的爽 —— 大部分系统就是这样的:**同样的时间压力之下,我做得也就那样**。虽然,我的手速可能比大部分人还快,实现的功能可能更多。但是,这些都是无关紧要的。 如果没有充足的时间改善,我们的系统都变得一片混乱。没有符合未来变化的设计,更何况你可能没有时间设计。 ## 好了,是时候重构 所以,经历了一系列的过程之后,我决定挑个合适的时候重建这个系统。 1. 开始重写之前的 markdown converter。 2. 将 markdown render 所有相关的组件提取为框架。 3. 重写系统。 于是,我们就出现了第二个系统,它设计良好。它的灵感都来自于我们在做第一个系统中的感受。如果没有来自于我们第一个系统的经验,我们无法设计出第二个系统。 ## 经验:快速验证概念,创造业务价值 事实上,我们在市面上看到的大部分系统,都是以如此的方式演进的: - 第一个系统,赚了钱,创造了价值,但是缺少各种最佳实践,生存周期短。 - 第二个系统,设计良好,包含了各种实践,生存周期变长,但是慢慢变得臃肿 而我们的第二个系统很快将变成一个臃肿而缓慢的系统。 > 『第三个系统』由那些为 『第二个系统』 所累的人们创建。 —— 《Linux/Unix设计思想》 没有新系统,哪来的 KPI? 感谢您的支持,祝您生活愉快!

过去的几年里,我一直在打造各式各样的编程相关的工具。这些工具有的是用于指导软件开发工作,有的是用来进行编程学习,还有的纯粹是为了提升技术而写的。在我写了越来越多的工具,接触了越来越多的工具思路之后。 我便想写一篇文章,用于记录一下过程中发生的一些变化。

Feeds

RSS / Atom

最近文章

关于作者

Phodal Huang

Engineer, Consultant, Writer, Designer

ThoughtWorks 技术专家

工程师 / 咨询师 / 作家 / 设计学徒

开源深度爱好者

出版有《前端架构:从入门到微前端》、《自己动手设计物联网》、《全栈应用开发:精益实践》

联系我: h@phodal.com

微信公众号: 最新技术分享

存档

分类

标签

作者