從實現原理談談低代碼

我們在低代碼領域探索了很多年,從 2015 開始研發低代碼前端渲染(amis),從 2018 年開研發後端低代碼數據模型,發佈了愛速搭低代碼平臺,這些年調研過了幾乎所有市面上的相關技術和產品,發現雖然每家產品細節都不太一樣,但在底層技術上卻只有少數幾種方案,因此我們認爲不同產品間的最大區別是實現原理,瞭解這些實現原理就能知道各個低代碼平臺的優缺點,所以本文將會介紹目前已知的各種低代碼實現方案,從實現原理角度看低代碼。

1 本文裏的「低代碼」指的是什麼?

在討論各個低代碼方案前,首先要明確「低代碼」究竟是什麼?

這個問題不好直接回答,因爲低代碼是非常寬泛的概念,有很多產品都聲稱自己的低代碼,但我們很容易反過來回答另一個問題:「什麼是低代碼產品唯一不可缺少的功能?」

我認爲這個功能是可視化編輯,因爲非可視化編輯就是代碼編輯,而只有代碼編輯的產品不會被認爲是低代碼,因此可視化編輯是低代碼的必要條件,低代碼其實還有另一個更清晰的叫法是可視化編程。

既然可視化編輯是低代碼的必要條件,那從實現角度看,實現可視化編輯有什麼必要條件?

我認爲可視化編輯的必要條件是「聲明式」代碼,因爲可視化編輯器只支持「聲明式」代碼。

解釋一下什麼是「聲明式」,除了聲明式之外還有另一種代碼模式是「命令式」,我們分別舉兩個例子,如果想繪製一個紅色區塊,用「聲明式」來實現,可以使用 HTML+CSS,類似下面的方法:

<div style="background:red; height:50px"></div>

而換成用「命令式」來實現,可以使用 Canvas API,類似下面的方法:

const ctx = canvas.getContext('2d');
ctx.fillStyle = 'red';
const rectangle = new Path2D();
rectangle.rect(0, 0, 100, 100);
ctx.fill(rectangle);

雖然最終展現效果是一樣的,但這兩種代碼在實現思路上有本質區別:

從可視化編輯器的角度看,它們的最大區別是:

反向推導是編輯器必備功能,比如編輯器裏的常見操作是點選這個紅色區塊,然後修改它的顏色,在這兩種代碼中如何實現?

如果是「聲明式」的 HTML+CSS,可以直接改 style 的 background 值,而基於 Canvas 的命令式代碼則無法實現這個功能,因爲無法從展現找到實現它的代碼,命令式代碼實現同樣效果的可能路徑是無數的,除了前面的示例,下面這段代碼也可以實現一樣的效果:

const ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(50, 0);
ctx.strokeStyle = '#ff0000';
ctx.lineWidth = 100;
ctx.stroke();

甚至有可能這個顏色是多個字符串加隨機數拼接而成,即便通過靜態分析也找不到來源,從而無法實現可視化修改。

「命令式」代碼無法實現可視化編輯,而可視化編輯是低代碼唯一不可少的功能,所以我們可以得到結論:所有低代碼平臺必然只能採用「聲明式」代碼,這也是爲什麼所有低代碼平臺都會有內置的「DSL」。

既然低代碼都是聲明式,那我們可以通過分析其它「聲明式」語言來了解低代碼的優缺點,其實在專業研發裏,聲明式語言在部分領域已經是主流了:

上面這些方案目前都是主流,但它們早期並不被看好,比如十幾年前還曾經爭論過到底是用 B/S 還是 C/S 架構,CSS 2 的功能主要是面向圖文排版,並不適合用來構建應用界面。

SQL 最開始也不被看好,下面引用《硅谷簡史》這本書裏的部分文字:

1970 年,IBM 研究員特德 · 科德(Ted Codd)發表了一篇里程碑式的論文,《大型數據庫的系統模型》,介紹了關係數據庫理論。

當時大多數人認爲關係數據庫沒有商業價值,因其速度太慢,不能滿足大規模數據處理或者大量用戶存取數據,雖然關係數據庫理論上很漂亮而且易於使用,但它的速度太慢。

上面兩段其實說的是 Oracle 的發家故事,可以看到當時關係型數據庫並不被看好,因爲大家都覺得慢,這點很好理解,數據庫在查詢前還得先解析 SQL 語法、估算各種查詢的代價、生成執行計劃,存儲也只能使用通用的數據結構,沒法根據不同業務進行定製。

綜合來看這些「聲明式」語言有以下優點:

而這些語言的缺點是:

1、只適合特定領域,命令式的語言比如 JavaScript 可以用在各種領域,但 HTML+CSS 只適合渲染文檔及界面,SQL 只適合做查詢,所有這些語言都。

2、靈活性差,比如 SQL 雖然內置了很多函數,但想只靠它實現業務是遠遠不夠的,有些數據庫還提供了用戶自定義函數功能(UDF),通過代碼來擴展。

3、調試困難,遇到問題時如缺乏工具會難以排查,如果你在 Firefox 出現前開發過頁面就會知道,由於 IE6 沒有開發工具,編寫複雜頁面體驗很差,遇到問題要看很久代碼才發現是某個標籤沒閉合或者 CSS 類名寫錯了。

4、強依賴運行環境,因爲聲明式只描述結果而不關注實現,因此強依賴運行環境,但這也帶來了以下問題:

  1. 功能取決於運行環境,比如瀏覽器對 CSS 的支持程度決定某個屬性是否有人用,雖然出現了 CSS Houdini 提案,但 Firefox 和 Safari 都不支持,而且上手成本太高,預計以後也不會流行。

  2. 性能取決於運行環境,比如同一個 SQL 在不同數據庫下性能有很大區別。

  3. 對使用者是黑盒,使用者難以知道最終實現,就像很少人知道數據庫及瀏覽器的實現細節,完全當成黑盒來使用,一旦遇到性能問題就不知所措。

  4. 技術鎖定,因爲即便是最開放的 HTML 也無法解決,很多年前許多網站只支持 IE,現在又變成了只支持 Chrome,微軟和 Opera 在掙扎了很多年後也乾脆直接轉向用 Chromium。同樣的即便有 SQL 標準,現在用的 Oracle/SQL Server 應用也沒法輕鬆遷移到 Postgres/MySQL 上。低代碼行業未來也一樣,即便出了標準也解決不了鎖定問題,更有可能是像小程序標準那樣發展緩慢,功能遠落後於微信。

因爲低代碼就是一種聲明式編程,所以這些「聲明式」優缺點,其實就是低代碼的優缺點,瞭解聲明式的歷史及現狀就能更好理解低代碼,因爲:

2 低代碼的實現方案

說完了聲明式,我們就對低代碼有了全面認識,接下來進入正題,開始介紹已知的各種低代碼實現原理,將會分爲前端和後端兩部分。

3 生成代碼的方案算不算低代碼?

在討論各種方案前,有一種方案比較特別,它雖然也有配置規範或 DSL,甚至有可視化編輯,但最終應用運行是通過生成代碼的方式實現的,不依賴依賴運行環境。

這個方案最大的優點是可以和專業開發整合,因此靈活性強、可以使用原有的開發流程,本質上和專業開發一樣。

但也有如下缺點:

因此我認爲生成代碼的方案不算真正的低代碼,本質上它還是一種開發輔助方式,一種高級點的腳手架工具,和大部分 IDE 的生成樣板代碼能力一樣,使用這種方案無法做到持續可視化開發,我還沒見過有人將 HTML+CSS 編譯成 C++ 代碼後二次開發。

4 前端代碼實現原理 - 界面渲染

前面提到前端 HTML+CSS 可以看成一種描述界面的低代碼 DSL,因此前端界面實現低代碼會比較容易,只需要對 HTML+CSS 進行更進一步封裝,這裏以我們的開源項目 amis 爲例進行介紹。

amis 核心原理是將 JSON 轉成自研的 React 組件庫,然後使用 React 進行渲染。

比如下面這段 JSON:

{
  "type""page",
  "title""頁面標題",
  "subTitle""副標題",
  "body"{
    "type""form",
    "title""用戶登錄",
    "body"[
      {
        "type""input-text",
        "name""username",
        "label""用戶名"
      }
    ]
  }
}

可以理解 amis 原理就是轉成了下面這樣的 React 組件樹,最終由各個 React 組件庫渲染 HTML:

<Page title="頁面標題" subTitle="副標題">
  <Form title="用戶登錄">
    <InputText  />
  </Form>
</Page>

雖然也有低代碼平臺直接使用 HTML+CSS 來實現更靈活的界面控制,但這樣做會導致用起來複雜度高,因爲通常需要多層嵌套 HTML 才能實現一個組件,使用者還必須熟悉 HTML 及 CSS,上手門檻過高,因此大部分低代碼平臺都是類似 amis 那樣使用 JSON 進行簡化。

這裏有個小問題,爲什麼大家幾乎全都使用 JSON?我覺得有兩方面原因:

  1. 低代碼平臺編輯器幾乎都是基於 Web 實現,JavaScript 可以方便操作 JSON。

  2. JSON 可以支持雙向編輯,它的讀取和寫入是一一對應的。

第二點怎麼理解?可以對比一下 YAML,它有引用功能,導致了不好實現雙向編輯,比如下面 YAML 示例:

paths:
  root_path: &root
     val: /path/to/root/
  patha: &a
    root_path: *root

轉成了對應的 JSON 數據後,就變成了:

{
   "paths"{
      "root_path"{
         "val""/path/to/root/"
      },
      "patha"{
         "root_path"{
            "val""/path/to/root/"
         }
      }
   }
}

可以看到之前的引用關係沒了,而是複製出了一部分,如果直接基於這個數據進行可視化編輯,編輯器在修改的時候就只會改一處,也沒法再還原成之前的 YAML 了,要想實現 YAML 可視化編輯就不能先轉成 JSON,而是要對 YAML 解析後的樹形結構進行操作,前端界面實現成本很高,因此目前還沒見過 YAML 的可視化編輯器。

但 JSON 的優點就是它的缺點,因爲它的用途是數據交換而不是人工編寫,導致基於 JSON 構建 DSL 不方便編輯,會有以下 3 個問題:

其中我們對這個註釋問題進行了特殊支持,開發了帶註釋的 JSON 解析,存儲的時候將註釋內嵌到一個特殊的字段中,在代碼顯示的時候將它提取出來變成註釋。

另外許多低代碼平臺會將這個 JSON 配置隱藏,只提供界面編輯,但在 amis 可視化編輯器裏提供了直接修改 JSON 的功能,因爲對於熟悉的開發者,直接編寫 JSON 要比在屬性面板裏找半天效率高,還可以直接將 amis 文檔中的示例粘貼進來快速創建。

amis 開始編輯器裏 JSON 編輯模式

前面提到聲明式容易向下兼容,amis 自己就是最好的例子,在 amis 誕生的 2015 年前端框架和現在有大量區別:

而 amis 早期的界面配置現在還能繼續使用,不受框架升級影響。

5 交互邏輯的實現

前面說到前端界面低代碼是比較容易,但交互及邏輯處理卻很難低代碼話,目前常見有三種方案:

先說第一種圖形化編程,這是非常自然的想法,既然低代碼的關鍵是可視化,那直接使用圖形化的方式編程不就行了?

但我們發現這麼做侷限性很大,本質的原因是「代碼無法可視化」,這點在 35 年前沒有銀彈的論文裏就提到了。

爲什麼代碼無法可視化?首先想一想,可視化的前提條件是什麼?

答案是需要具備空間形體特徵,可視化只能用來展現二維及三維的物體,因爲一維沒什麼意義,四維及以上大部人無法理解,所以如果一個事物沒有形體特徵,它就沒法被可視化。

舉個例子,下面是一段 amis 中 代碼,作用是遍歷 JSON 並調用外部函數進行處理:

function JSONTraverse(json, mapper) {
  Object.keys(json).forEach(key ={
    const value = json[key];
    if (isPlainObject(value) || Array.isArray(value)) {
      JSONTraverse(value, mapper);
    } else {
      mapper(value, key, json);
    }
  });
}

雖然只有 10 行代碼,卻包含了循環、調用函數、類型檢測、分支判斷、或操作符、遞歸調用、參數是函數這些抽象概念,這些概念在現實中都找不到形體的,你可以嘗試一下用圖形來表示這段代碼,然後給周圍人看看,我相信任何圖形化的嘗試都會比原本這段代碼更難懂,因爲你需要先通過不同圖形來區分上面的各種概念,其他人得先熟悉這些圖形符號才能看懂,理解成本反而更高了。

代碼的這些抽象思維難以像積木一樣進行拼接,積木拼接這種方式只適合用來實現簡單的邏輯,比如 scratch。

Scratch

而前面圖形化是低代碼唯一不可少的功能,這就使得低代碼不適合做複雜的抽象邏輯處理,這是圖形化缺陷決定的,因此在複雜邏輯處理方面低代碼永遠無法徹底取代專業代碼開發。

但如果是面向特定領域,低代碼平臺可以先將這個領域難以圖形化的算法預置好,讓使用者只需做簡單的處理,比如在 Blender 中將 PBR 算法封裝了,使用的時候只需要調整參數就行。

Blender 中的材質節點編輯

如果真要用節點實現這個算法會非常複雜,大概長這樣:

在複雜邏輯下,圖形中的連線反而變成了視覺干擾,比如下面的例子:

來自 UE4 Blueprints From Hell 裏的一張圖

想象一下假設客戶做出了上面這個圖的複雜邏輯,然後找你排查問題,而客戶的程序是部署在內網的,沒法導出,只能通過微信拍屏幕給你看……

因此我認爲圖形化不適合用來實現業務邏輯,只適合用來做更高層次流程控制,比如審批流,審批流是現實真實存在的,沒有複雜的抽象邏輯,因此適合圖形化。

在愛速搭中,我們除了實現流程功能,還實現了樹形結構的 API 編排功能,它本質上是模仿代碼結構,將會在後面進行介紹。

說完了圖形化編程,接下來談第二種方案:固化交互行爲,這是不少低代碼平臺的做法,我們還是以 amis 爲例進行介紹。

amis 將常用的交互行爲固化並做成了配置,比如彈框是下面的配置:

{
  "label""彈框",
  "type""button",
  "actionType""dialog",
  "dialog"{
    "title""彈框",
    "body""這是個簡單的彈框。"
  }
}

除了彈框之外還有發起請求、打開鏈接、刷新其它組件等,使用固化交互行爲有下面兩個優點:

但這個方案最大的缺點是靈活性受限,只能使用 amis 內置的行爲。

要實現更靈活的控制,還是得支持第三個方案:JavaScript,目前有的低代碼平臺只在界面編輯提供可視化編輯,一旦涉及到交互就得寫 JavaScript,這和 30 年前的 C++ Builder 本質上是一樣的:

RDA Studio 11 的界面編輯

但第三個方案的最大缺點就是無法可視化編輯,因此不算是低代碼。

6 後端低代碼的方案

前端討論完了,接下來是後端部分,後端低代碼需要解決以下三個問題:

1、如何自定義數據存儲?

低代碼平臺需要支持用戶存儲自定義數據,因爲每個應用所需的字段是不一樣的。

自定義數據存儲是後端低代碼最重要的功能,使用什麼方案將直接影響這個產品的適用範圍,目前我們已知有 5 種方案,每種都有自己的優缺點。

存儲的實現方案 1:直接使用關係型數據庫

這個方案的原理是將數據模型的可視化操作轉成數據庫 DDL,比如添加了一個字段,系統會自動生成表結構變更語句:

ALTER TABLE 'blog' ADD 'title' varchar(255) NULL;

這個方案的優點是:

但它的缺點是:

儘管這個方案有很多缺點,但它的優點也很突出,因此愛速搭裏實現了這個方案,因爲我們覺得能連已有數據庫是非常重要的,其它方案都只適合用來做新項目,這個方案使得可以逐步將已有項目低代碼化,不需要做數據遷移。

愛速搭裏的數據庫模型

實現這個方案的關鍵是「動態實體」,在專業開發中實體(Entity)定義都是靜態的,以 Java 爲例,它從 2006 年開始就有專門的 JPA 規範,但這個規範是定義基於 Java 代碼註解,使得需要經過編譯才能使用,畢竟它的定位是面向專業開發,只有寫在代碼裏才能支持代碼提示,提升開發體驗。

而低代碼平臺中需要將這個實體定義抽象成配置,在運行時動態生成實體,如果使用 JPA 就需要生成 Java 代碼後進行編譯,這很容易出錯,不太適合低代碼平臺,所以使用這個方案需要實現「動態實體」功能,是整個方案最大難點。

存儲的實現方案 2:使用文檔型數據庫

文檔型數據庫不需要預先定義表結構,因此它很適合用來存儲用戶自定義數據,這個方案實現起來比較簡單,以 MongoDB 爲例,可以這樣做:

  1. 用戶創建一個自定義表的時候,系統就自動創建一個 collection,所有這個表的數據都存在這個 collection 裏。

  2. 用戶新增字段的時候,就隨機分配一個 fileId,後續對這個字段的操作都自動映射到這個 fileId 上,用 fileId 的好處是用戶重命名字段後還能查找之前的數據,因爲所有數據查詢底層都基於這個 fileId。

  3. 查詢的時候先找到對應的 collection,再通過 meta 信息查詢字段對應的 fileId,使用這個 fileId 來獲取數據。

這個方案的優點是實現簡單,用戶體驗可以做得更好,是目前大部分零代碼平臺的選擇,使用這個方案的產品也很好識別,只要看一下它的私有部署文檔,如果有要求裝 MongoDB 就肯定是。

但這個方案也有顯著缺點:

你可能會問,現在 MySQL、Postgres 等數據庫都支持 JSON 字段類型了,是否可以用這個字段來實現低代碼?

答案是不太行,只適合數據量不大的場景,雖然 JSON 字段可以用來存用戶自定義數據,但無法創建字段索引,比如在 MySQL 要想給 JSON 創建索引,還是得創建一個特殊的字段,這又需要 DDL 權限了,沒有索引會導致這個方案無法支持大量數據查詢。

在愛速搭中我們也實現這個方案,目前是基於 MySQL JSON 字段,後續可能也會支持存儲使用 MongoDB,目前它的使用場景是流程執行過程中的數據存儲,因此數據量不會很大,我們希望流程功能用起來可以更簡單些。

它的最大特點是界面編輯和數據存儲是統一的,當你拖入文本框到頁面後就會自動創建對應的字段,不需要先創建數據模型再創建界面,因此用起來更簡單。

愛速搭裏的表單模型

存儲的實現方案 3:使用行代替列

這是很多可擴展平臺裏使用的技術,比較典型的是 WordPress,它的擴展性很強,裝個擴展就能變成電商網站。而整個 WordPress 只有 12 個表,它是怎麼做到的?方法是靠各種 meta 表,比如用於擴展文章的 wp_postmeta 表結構如下:

CREATE TABLE wp_postmeta (
  meta_id bigint(20) unsigned NOT NULL auto_increment,
  post_id bigint(20) unsigned NOT NULL default '0',
  meta_key varchar(255) default NULL,
  meta_value longtext,
  PRIMARY KEY  (meta_id),
  KEY post_id (post_id),
  KEY meta_key (meta_key)
) DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

其中的關鍵就是 meta_key 和 meta_value 這兩個字段,相當於將數據庫當 KV 存儲用了,因此可以任意擴展字段名及值。

這個方案的優點是實現簡單,但缺點也很明顯:

這個方案主要用於成熟項目的擴展,比如在 CRM 產品中允許用戶擴展字段,但因爲性能較低,並不適合通用低代碼平臺。

存儲的實現方案 4:元信息 + 寬表

早期數據庫不支持 JSON 字段的時候,有些開發者會預留幾個列來給用戶擴展自定義屬性,比如在表裏加上 ext1、ext2、ext3 字段,讓用戶可以存 3 個定製數據,基於這個原理我們可以進一步擴展,通過預留大量列來實現應用自定義存儲。

這個方案最早出現在 force.com,具體細節可以閱讀它架構說明文檔 [1]。

實現它有兩個關鍵點:元數據、預留列,這裏簡單說明一下原理,首先系統預先創建一個 500 列的表,比如就叫 data:

E8usfX

也可以創建更多,但注意有的數據庫對列的數量有限制,比如 MySQL 最多是 4096 列。

上面的 data 表裏主要有 4 類字段:

當用戶給這個表新增一個字段的時候,怎麼知道這個字段放哪?這就需要另一個用於描述字段信息的元數據表,比如增加一個「標題」字段時,使用另一個 table_fields 表來描述這個字段的信息,示例如下:

1fvCah

在這個 table_fields 表裏:

最終在實際查詢的時候需要根據元數據表做一下轉換,比如 select 標題 from blog 要轉成 select value0 from data where tenal_id = 1 and table_id = 1。

要完全實現這個方案還有很多細節問題得解決,由於篇幅原因這裏不詳細介紹,感興趣可以閱讀前面提到的 force.com 技術白皮書,這裏列舉其中幾個問題:

這個方案比前面幾個方案的優點是:

但它也有許多缺點:

愛速搭中沒有實現這個方案,我們曾經考慮過但後來放棄了,我認爲這個方案雖然很適合 SaaS 類的低代碼產品,但它的用戶定位比較尷尬,一方面是有一定複雜度導致不能做到零代碼平臺那樣的易用性,另一方面是有不少限制導致專業研發不喜歡,所以最終是兩邊都不討好,這種產品想做成需要依賴廣泛使用的平臺。

因此 Salesforce 才能做成,而國內類似情況我能想到的唯一成功案例是微信小程序,儘管有很多限制,但因爲微信廣泛使用,所以才成功了,如果是一個獨立的小程序平臺肯定沒人用。

這裏說一段小歷史,在十幾年前,當時雲計算領域最先推出的是谷歌 2008 年發佈的 App Engine,這是谷歌的第一個雲產品,而當時類似 AWS EC2 那樣的虛機產品國內都還沒有,畢竟 KVM 也纔剛發佈。

如果你當時問雲計算的專家,雲計算的未來是 App Engine 還是虛擬機,我聽到不少專家的回答是 App Engine,因爲這看起來更有前景,你只需要寫代碼,不用操心運維,平臺會自動水平擴展,這纔是雲該有的樣子,當時國內不少公司都推出了類似產品。

但 13 年後的今天,國內 App Engine 平臺幾乎都關閉了,而虛機不但是主流,還更進一步出現了物理機產品。這個元信息方案給我的感覺和當年 App Engine 很像,看上去能完成增刪改查的簡單應用,但如果深入就發現缺少很多功高級功能,導致兩邊不討好:

整體而言我不看好這個方案在國內的發展。

存儲的實現方案 5:使用單文件

這個方案目前只在「仿 Excel」的零代碼平臺中見過,它和 Excel 類似,數據全都放一個文件裏,查詢過濾完全靠前端,優點是:

缺點是:

這個方案比較特殊,主要工作量在前端,有大量細節體驗優化,在愛速搭中沒實現,後續可能會考慮。

2、後端業務邏輯的實現

說完了存儲,接下來是第二個問題:如何實現後端業務邏輯?

前面提到過代碼難以圖形化,這在後端也是一樣的,因此大概有這幾種方案:

前面兩種方案之前介紹過了,這裏只討論後面兩種。

後端支持使用 JavaScript 是種常見做法,主要原因是 JavaScript 引擎容易被嵌入,而且啓動速度快,瞭解的人多,比如市值超過 1200 億美元的 ServiceNow 後端自定義業務邏輯就是基於 Rhino 引擎實現的。

簡化 DSL 語言的主要是使用場景是做表達式計算,比如在流程中的分支流轉規則判斷,需要用戶能自定義表達式,比如金額大於多少換成總監審批,這時用公式會比 JavaScript 會更簡單,因爲系統可以自動轉換數據類型,並自動處理異步函數的調用,目前愛速搭的流程裏有實現,同時在 amis 裏也提供了。

另外除了上面提到這四種,我們在愛速搭中還設計了另一個方案:執行樹,它長這個樣子:

左側是樹形結構,右側是點中某個節點時的參數配置,左側的樹形結構其實是直接參考代碼的樹形結構:

爲了方便實現簡單邏輯處理,我們還增加了 JavaScript 節點和 SQL 節點。

但執行樹這個方案目前的定位是聚合多接口,將多個後端接口數據合併後給前端,類似於 BFF 的作用,我們推薦複雜的後端邏輯還是用 Spring Boot 吧,成熟穩定且好招人。

3、流程的實現

接下來是第三個問題:如何實現流程?這是大部分低代碼平臺標配的功能,流程的邏輯不像普通代碼那麼抽象,因此適合用可視化編輯。

流程可視化存在很久了,著名的 BPMN 規範最早版本在 2004 就發佈了,因此大部分產品都會支持 BPMN 2.0 規範。

但 BPMN 本質上是一種圖形規範,它的最大作用是給事件、動作及分支條件這些抽象概念分配了不同的形體,使得熟悉這個規範的用戶有了共同語言。

BPMN 不能解決平臺鎖定問題,在一個平臺開發的流程無法直接遷移到另一個平臺。

流程的核心是實現流程流轉引擎,以愛速搭爲例,流程可視化佈局後最終存儲的格式是有向圖,比如下面這個最簡單流程:

簡化後的存儲數據格式是兩條連線和三個節點:

{
  "lines"[
    {
      "id""d4ffdd0f6829",
      "to""4a055392d2e1",
      "from""e19408ecf7e3"
    },
    {
      "id""79ccff84860d",
      "to""724cd2475bfe",
      "from""4a055392d2e1"
    }
  ],
  "nodes"[
    {
      "id""e19408ecf7e3",
      "type""start",
      "label""開始"
    },
    {
      "id""4a055392d2e1",
      "type""examine-and-approve-task",
      "label""審批節點"
    },
    {
      "id""724cd2475bfe",
      "type""end",
      "label""結束"
    }
  ]
}

流程流轉算法的核心就是根據當前狀態和這個有向圖,判斷出下個節點是什麼,然後執行那個節點的操作。

同時因爲主要面向的是審批流,所以還需要處理審批場景特有的邏輯,比如有的審批是全部通過纔算通過,有的審批是隻需要一個人通過就算通過,還有回退、加簽等功能,並處理各種邊界條件,比如找不到審批人的時候怎麼辦。

雖然目前業界有開源的流程引擎,但這些引擎大多是面向代碼開發,不太好改造成平臺模式,因此在愛速搭裏自己實現了流程引擎,這樣才能更好定製功能。

7 低代碼平臺未來會怎樣?

前面提到了各種低代碼的實現方案細節,這裏拋開具體細節,來整體討論一下未來低代碼平臺會怎樣。

最開始提到過低代碼唯一不可缺少的功能是可視化編輯,這是低代碼的最大優勢,但是低代碼的最大缺陷,因爲可視化難以表達複雜的抽象邏輯,因此長遠看低代碼並不會在所有領域取代專業開發,更多是和專業開發配合來提升效率。

從技術方案上看低代碼平臺主要有兩個方向:

1、偏向零代碼的方案,它的特點是:

2、偏向專業開發的方案,它的特點是:

未來會怎樣呢?我的想法是:

偏向零代碼方案,因爲功能類似支持成本低,可以同時支持很多用戶,容易出現贏者通喫的情況,但由於 toB 領域發展速度慢,所以還是有不少機會。

可以類比 BI 數據可視化產品,BI 這個領域的軟件出現至少 20 年了,比如 Qlik 1994 就發佈了,現在市面上的 BI 軟件在基本功能上都大體相同,但沒有哪個產品佔據絕大部分市場份額,我們的 Sugar 產品雖然兩年前才推出,但依然得到了不少優質客戶,所以只要產品優秀就有機會。

零代碼產品有好幾種形態,和去年一樣,我更看好「在線 Excel」,因爲既然是面向非開發者,類 Excel 是上手成本最低的方案,而且這一年來許多「在線 Excel」的產品都加上了低代碼功能,比如 Airtable 的 Interface,在功能上和表單驅動的零代碼越來越接近了。

而偏向專業開發的方案,因爲支持成本高導致沒法同時支持很多客戶,因此更難出現一家獨大的情況,而偏向研發會導致細節方案有很多區別,沒太多可比性。

以我們的愛速搭爲例,目前產品選擇的方案是偏向專業開發,現有客戶都是知名企業,但也導致了支持成本很高,因爲客戶問的問題都很專業,大多隻有核心研發才能解答,在功能方面我們的特點是前端使用了我們開源的 amis 框架,這個其它家是不會提供的。

8 總結

前面字太多了,總結一下主要觀點:

9 在瞭解原理之後

前面介紹了各種低代碼實現原理,看起來都不難,但真正要實現還需要大量細節工作,以我們的 amis 爲例,從 2015 年啓動至今一直在持續更新,下面是 amis 開源這兩年半來的提交歷史 [2],基本除了春節和國慶之外都在提交:

amis 的 contributors 頁面

但今天 amis 現在仍然有大量功能要做,比如本週將發佈的 1.6.0 版本終於開始初步增強移動端 UI,下面是新版移動端日期選擇:

amis 1.6.0 裏的日期選擇

除了無盡的功能要加,還有許多基礎工作要做,比如組件單元測試覆蓋率只有 40%,此刻還有 360+ issues 要處理,感謝閱讀到這,有什麼問題歡迎留言交流,我要去處理 issue 了……

作者介紹

吳多益,百度智能雲主任架構師,超過 14 年從業經驗,參與過百度貼吧、搜索、空間等產品的研發,曾長期負責百度前端基礎技術團隊,從 2015 年起開始探索低代碼方向,並開源了前端低代碼框架 amis,目前在百度智能雲負責低代碼產品愛速搭的研發。

相關鏈接:

  1. https://developer.salesforce.com/wiki/multi_tenant_architecture

  2. https://github.com/baidu/amis/graphs/contributors

作者:吳多益

來源:https://zhuanlan.zhihu.com/p/451340998

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/Jihxe4Gvvv_u-h9HG81s_A