
規(guī)?;慕M織,經(jīng)常要面臨這樣的挑戰(zhàn):每個(gè)應(yīng)用的基礎(chǔ)設(shè)施是相同的,部分的代碼也是相同的,甚至于它們可能只是數(shù)據(jù)模型不同而已。結(jié)果卻導(dǎo)致了,他/她們要一次又一次地重新編寫一個(gè)應(yīng)用。對(duì)于一個(gè)新的應(yīng)用而言,它需要對(duì)接大量的三方(非自己團(tuán)隊(duì))服務(wù)。服務(wù)之間的不斷變化 ,導(dǎo)致了對(duì)應(yīng)的使用方也需要發(fā)生變化。不斷變化的業(yè)務(wù),導(dǎo)致了前臺(tái)的設(shè)計(jì)不斷變化。為了應(yīng)對(duì)快速談的的前臺(tái)服務(wù),后臺(tái)便誕生了中臺(tái),以提供快速的響應(yīng)能力。而隨著中臺(tái)進(jìn)一步沉淀,從某種形式上趨于穩(wěn)定,而前臺(tái)仍然需要快速地響應(yīng)能力。
于是乎,作為一個(gè)前端開發(fā)人員,我們不斷提煉和復(fù)用代碼,想著的模式在之前的文章已提到了:
腳手架
組件庫(kù)
模式庫(kù)
模板和模板應(yīng)用
對(duì)應(yīng)的,我們還創(chuàng)建了一系列的 CLI、工具集、編程器插件以及設(shè)計(jì)系統(tǒng),以完成整個(gè)系統(tǒng)的快速開發(fā)。然而,我們還缺少一套有效的工具,來(lái)統(tǒng)一化的管理這些工具。
換句話來(lái)說(shuō),就是:我們需要一個(gè)前端的中臺(tái),它便是無(wú)代碼/低代碼編程。
無(wú)代碼/低代碼是一種創(chuàng)建應(yīng)用的方法,它可以讓開發(fā)人員使用最少的編碼知識(shí),來(lái)快速開發(fā)應(yīng)用程序。它可以在圖形界面中,使用可視化建模的方式,來(lái)組裝和配置應(yīng)用程序。開發(fā)人員可以直接跳過(guò)所有的基礎(chǔ)架構(gòu),只關(guān)注于使用代碼來(lái)實(shí)現(xiàn)業(yè)務(wù)邏輯。
當(dāng)然,從開發(fā)人員的角度來(lái)看,降低代碼量,可能是:
框架本身處理了復(fù)雜性。畢竟?“復(fù)雜度同力一樣不會(huì)消失,也不會(huì)憑空產(chǎn)生,它總是從一個(gè)物體轉(zhuǎn)移到另一個(gè)物體或一種形式轉(zhuǎn)為另一種形式?!?/p>
代碼生成減少了工作量。大量的復(fù)制、粘貼需要更多的時(shí)間。
只是憑借這個(gè)概念,我們是無(wú)法理解無(wú)代碼編程的。于是,我畫了一張圖來(lái)展示相應(yīng)的架構(gòu)和流程:

低代碼編程流
依照我的觀點(diǎn)來(lái)看,我將無(wú)代碼編程分為了兩部分:
用于構(gòu)建 UI 的編輯器——一種在線的拖拽式 UI 設(shè)計(jì)和頁(yè)面構(gòu)建工具
用于編寫業(yè)務(wù)邏輯的流編輯器——通過(guò)流編程的方式來(lái)編寫業(yè)務(wù)代碼(多數(shù)是對(duì)于數(shù)據(jù)的處理)
UI 編程器
為了設(shè)計(jì)出我們的 UI 構(gòu)建器,我們需要準(zhǔn)備好一系列的基礎(chǔ)設(shè)施:
UI 編程器。用于拖拽式設(shè)計(jì) UI。
空白腳手架。一個(gè)帶有完整的應(yīng)用生命周期的項(xiàng)目,但是它是一個(gè)空白的項(xiàng)目——用于我們?cè)跇?gòu)建 UI 的過(guò)程中,隨時(shí)隨地的添加組件和代碼。
設(shè)計(jì)系統(tǒng)。我們需要一個(gè)完整的組件庫(kù),大量的頁(yè)面模板,以及一定數(shù)量的模板應(yīng)用,減少相應(yīng)的開發(fā)工具量。
代碼片段集。它將設(shè)計(jì)系統(tǒng)中的組件庫(kù)進(jìn)一步實(shí)例化成代碼段,在完成編輯后通過(guò) CLI 來(lái)動(dòng)態(tài)編輯代碼。
DSL(領(lǐng)域特定語(yǔ)言,可選)。中間生成物,用于隔離框架與設(shè)計(jì)。
流編程器
流編程器。用于拖拽式、輸入編寫業(yè)務(wù)代碼。
后端服務(wù)。如果不能提供現(xiàn)成的后端服務(wù),則需要擁有一個(gè)標(biāo)準(zhǔn)的 API 規(guī)范,以及相應(yīng)的 mock server。
模式庫(kù)。包含相應(yīng)的業(yè)務(wù)處理代碼,如通用的登錄、數(shù)據(jù)獲取、UI 交互等。
DSL(領(lǐng)域特定語(yǔ)言,可選)。同上
當(dāng)然了,我們還需要能實(shí)時(shí)預(yù)覽構(gòu)建出來(lái)的應(yīng)用。隨后,我們執(zhí)行了構(gòu)建,而后構(gòu)建出了一個(gè)半成品應(yīng)用。開發(fā)人員只需要在它的基礎(chǔ)上開發(fā)應(yīng)用即可。而在開發(fā)人員開發(fā)的過(guò)程中,我們可以設(shè)計(jì)一系列的工具,來(lái)幫助開發(fā)人員更快速地構(gòu)建應(yīng)用。
編輯器插件。包含設(shè)計(jì)系統(tǒng)、模式庫(kù)等的自動(dòng)完成代碼,以及組織內(nèi)部常用的代碼庫(kù)。
調(diào)試工具。對(duì)于混合類型的應(yīng)用而言,我們還需要一個(gè)開發(fā)工具來(lái)快速構(gòu)建應(yīng)用。
從上述的流程上來(lái)看,無(wú)代碼編程還具有以下的特點(diǎn):
拖放式界面。又或者是可視化模型——基于節(jié)點(diǎn)和箭頭。
基于視覺(jué)的設(shè)計(jì)。
可擴(kuò)展的設(shè)計(jì)。如對(duì)于插件、插件商店,社區(qū)等一系列的支持。
跨平臺(tái)功能。支持 PC Web 應(yīng)用開發(fā),支持移動(dòng)應(yīng)用構(gòu)架等。
強(qiáng)大的部署后。即平臺(tái)包含著整個(gè)應(yīng)用的生命周期。
擁有豐富的集成支持。可以隨意的找到需要的組件,以及對(duì)應(yīng)的后臺(tái)服務(wù)。
配置化。它也意味著大量的自定義配置。
自制的領(lǐng)域特定語(yǔ)言(可選)。用于構(gòu)建時(shí)優(yōu)化。
相應(yīng)的,它具有以下的一些優(yōu)點(diǎn):
高效。不用多說(shuō),節(jié)省時(shí)間和開發(fā)成本。
有限的 Bug,安全性。
低成本。其所需的預(yù)算非常有限。
易用(取決于設(shè)計(jì))。
開發(fā)速度更快。
開發(fā)過(guò)程中的 AI 。
維護(hù)成本低。
對(duì)應(yīng)的相應(yīng)的缺點(diǎn)有:
仍然需要編程技能。
受限的自定義能力。
可擴(kuò)展性成了新的問(wèn)題。
集成受限。
就當(dāng)前而言,低代碼開發(fā)平臺(tái)通常分為兩大類:
對(duì)于外部:制作簡(jiǎn)單的產(chǎn)品,如網(wǎng)絡(luò)移動(dòng)應(yīng)用程序
對(duì)于內(nèi)部:為您的團(tuán)隊(duì)或企業(yè)創(chuàng)建業(yè)務(wù)應(yīng)用程序
諸如只使用?CRUD、表單、驗(yàn)證、簡(jiǎn)單聚合、分頁(yè)等簡(jiǎn)易的服務(wù)。最常見的例子就是表單構(gòu)建了,諸如金數(shù)據(jù)這樣的應(yīng)用,便是可以直接通過(guò)拖拽元素來(lái)生成,相應(yīng)的開源實(shí)現(xiàn)有 jQuery Form Builder。
對(duì)于開發(fā)人員來(lái)說(shuō),我們只需要定義好數(shù)據(jù)模型,再通過(guò)拖拽來(lái)決定元素的位置即可。從這種角度來(lái)看,只要能使用 Serverless 構(gòu)建的應(yīng)用和服務(wù),都可以直接使用低代碼開發(fā)模式。
從我們的理解來(lái)看,傳統(tǒng)應(yīng)用的開發(fā)流程是:
分析、設(shè)計(jì)、確認(rèn)、規(guī)劃需求。
設(shè)計(jì)系統(tǒng)架構(gòu)。
搭建前后端項(xiàng)目。選擇技術(shù)棧、從零開始搭建或者從腳手架中創(chuàng)建。
搭建持續(xù)集成。
創(chuàng)建線框圖和高保真原型。
設(shè)計(jì)數(shù)據(jù)模型,定義前后端契約,即 API URI、方法、字段等。
前后端實(shí)現(xiàn)業(yè)務(wù)邏輯。
前端實(shí)現(xiàn) UI 頁(yè)面。
集成第三方后端服務(wù)。
功能需求測(cè)試(DEV、QA、ST、UAT)
跨功能需求測(cè)試(安全性、性能等)
部署到生產(chǎn)環(huán)境。
低代碼開發(fā)流程:
分析、設(shè)計(jì)、確認(rèn)、規(guī)劃需求
選擇需要的第三方 API
在可視 IDE 中繪制應(yīng)用程序的工作流程、數(shù)據(jù)模型和用戶界面。
連接 API——通常使用服務(wù)、函數(shù)發(fā)現(xiàn)。
編寫業(yè)務(wù)邏輯(可選)。手動(dòng)代碼添加到前端或者自定義自動(dòng)生成的 SQL 查詢。
用戶驗(yàn)收測(cè)試。
部署到生產(chǎn)環(huán)境。
從步驟上來(lái)看,無(wú)代碼編程少了幾個(gè)步驟。這些步驟都因?yàn)榇罅控S富的內(nèi)部系統(tǒng)集成,而變得非常簡(jiǎn)單。
就當(dāng)前而言,無(wú)代碼編程實(shí)際上是一種高度的場(chǎng)景預(yù)設(shè)的模式。因此,它存在一定的適用場(chǎng)景:
模型驅(qū)動(dòng)開發(fā)。
快速 UI 構(gòu)建。
極簡(jiǎn)的業(yè)務(wù)功能。
IT 資源受限。在資源受限的情況下,能快速開發(fā)出符合業(yè)務(wù)需求的應(yīng)用最重要。
而從流程上來(lái)看,對(duì)于一部分的應(yīng)用來(lái)說(shuō),我們并不能實(shí)現(xiàn)無(wú)代碼編程——存在一些業(yè)務(wù)上的不同之處。因此,多數(shù)場(chǎng)景之下,只是實(shí)現(xiàn)了低代碼編程。
若是想真實(shí)的無(wú)代碼編程,則需要一些更特定的場(chǎng)景:
設(shè)計(jì)表格(輸入數(shù)據(jù))
創(chuàng)建報(bào)告(組織數(shù)據(jù))
常規(guī)調(diào)度和自動(dòng)化過(guò)程(操縱數(shù)據(jù))
更多的場(chǎng)景正在探索中。
無(wú)代碼編程,除了需要準(zhǔn)備好上述的一系列基礎(chǔ)設(shè)施,還不可避免地會(huì)遇到一系列挑戰(zhàn)。
誰(shuí)來(lái)寫這部分代碼?
客戶端的基礎(chǔ)設(shè)施準(zhǔn)備。
服務(wù)端的服務(wù)平臺(tái)搭建。
統(tǒng)一用戶體驗(yàn)設(shè)計(jì)。設(shè)計(jì)出一系列能便利組合的組件,及對(duì)應(yīng)的模板頁(yè)面。與此同時(shí),它們還能適應(yīng)于不同的風(fēng)格,即有多樣性的主題支持。
DevOps 流水線設(shè)計(jì)。低代碼編程,依賴于一系列的自動(dòng)化工具,以實(shí)現(xiàn)構(gòu)建、調(diào)試、部署以及維護(hù),同時(shí)還包含應(yīng)用的測(cè)試。
領(lǐng)域語(yǔ)言設(shè)計(jì)。
自動(dòng)化測(cè)試。如果我們的前端代碼是自動(dòng)生成的,那么我們還需要對(duì)它們進(jìn)行測(cè)試嗎?這是一個(gè)好問(wèn)題,而如果代碼是自動(dòng)生成的,那么測(cè)試也應(yīng)該是自動(dòng)生成的。畢竟要在平臺(tái)上,編寫大量的自動(dòng)化測(cè)試,以保證平臺(tái)的質(zhì)量。
其中,有一些部分略微復(fù)雜一些,我們大概可以探索一下。
在我們創(chuàng)建這樣一個(gè)平臺(tái)和工具時(shí),我們要考慮的第一個(gè)問(wèn)題是,這個(gè)工具是為誰(shuí)寫的?
沒(méi)有編程經(jīng)驗(yàn)的人。如業(yè)務(wù)人員,他/她們對(duì)于業(yè)務(wù)系統(tǒng)有著非常豐富的經(jīng)驗(yàn)。
有編程知識(shí),但是沒(méi)有經(jīng)驗(yàn)的人。
有一定經(jīng)驗(yàn)的開發(fā)人員。
有豐富經(jīng)驗(yàn)的開發(fā)人員。對(duì)于專業(yè)的人來(lái)說(shuō),自動(dòng)化就意味著缺少靈活度。甚至與自己編寫相比,他們要花費(fèi)更多的時(shí)間來(lái)修復(fù)生成的代碼。
顯然,對(duì)于相當(dāng)有經(jīng)驗(yàn)的開發(fā)人員而言,這個(gè)工具并不一定是他們所需要的。
從我的理解來(lái)看,它適合于快速的 MVP 構(gòu)建,并且生成的代碼還應(yīng)該方便修改,而不是諸如早期的 DreamWeaver 或者 FrontPage 這樣的工具。
而與此同時(shí),由于面向的開發(fā)人員水平不同,我們所需要做的工具也不同:
支持云構(gòu)建和調(diào)試。
GUI 編程應(yīng)用。
代碼生成。
設(shè)計(jì)系統(tǒng)體系構(gòu)建。組件庫(kù)搭建,模板應(yīng)用創(chuàng)建等。
更難的是,容易讓開發(fā)人員能接受代碼生成。
對(duì)于一個(gè)低代碼平臺(tái)而言,它對(duì)應(yīng)的后端應(yīng)該:
大量可用的現(xiàn)有服務(wù)。身份驗(yàn)證、安全性、推送能力、地圖等等。
快速構(gòu)建出后端服務(wù)。若是有內(nèi)部 Serverless 或者 FaaS 方案,可以說(shuō)是再好不過(guò)了。
方便與第三方服務(wù)集成。
靈活性。支持多語(yǔ)言等。
統(tǒng)一的后端服務(wù) API,對(duì)于后端服務(wù)來(lái)說(shuō),我們需要一個(gè)通用的范式。所有的 API 應(yīng)該按照這樣的范式來(lái)設(shè)計(jì)。不過(guò),作為一個(gè) API 的消費(fèi)方,我們可能沒(méi)有這么大的權(quán)力,但是我們可以采用裝飾器模式,即封裝第三方 API 成統(tǒng)一的方式。為此,我們采用的方式,仍然是:
契約。諸如 Swagger UI,它可以直接創(chuàng)建一個(gè)簡(jiǎn)易可用的服務(wù)。
BFF。即我們一一去按我們的需要,去封裝這些第三方應(yīng)用。
查詢語(yǔ)言。與自己編寫 BFF 相比,更簡(jiǎn)單的方式是采用:GraphQL?這樣的后端查詢語(yǔ)言,便捷性更高、模式更加靈活。
在開發(fā)前的設(shè)計(jì)期里,我們需要首先設(shè)計(jì)出對(duì)應(yīng)的領(lǐng)域模型。
低代碼環(huán)境使用(圖形)建模語(yǔ)言來(lái)指定整個(gè)系統(tǒng)、產(chǎn)品的行為。它意味著:
將數(shù)據(jù)結(jié)構(gòu)、領(lǐng)域模式應(yīng)用到程序的各個(gè)層級(jí)中。
將業(yè)務(wù)規(guī)則、決策融入到應(yīng)用中(層級(jí))。
這也就意味著,我們需要設(shè)計(jì)一個(gè)模型語(yǔ)言。而它對(duì)于我們而言,實(shí)際上是領(lǐng)域特定語(yǔ)言(DSL)。如下是一個(gè)簡(jiǎn)單的 DSL 示例,用于描述使用到的組件:
{'style':'','id':?2,'blocks':
[{'content':?{'content':'content','title':'hello'},'type':'card'}]
}
除此,我們還需要設(shè)計(jì)對(duì)應(yīng)的布局 DSL,諸如于:
H:[circle1(circle1.height)]?//?set?aspect-ratio?for?circle1
HV:[circle2..5(circle1)]?//?use?same?width/height?for?other?circles
H:|[circle1]-[circle2]-[circle3]-[circle4]-[circle5]|
V:|~[circle1..5]~|?//?center?all?circles?vertically
最后,我們還需要將流代碼,轉(zhuǎn)換為真實(shí)的項(xiàng)目代碼。三種類型的 DSL 結(jié)合下來(lái),都不是一個(gè)輕松的工具。
寫好現(xiàn)有的組件,通用型接口。如常見的登錄接口,對(duì)于使用登錄接口的業(yè)務(wù)來(lái)說(shuō),它們只關(guān)心三部分的內(nèi)容:
成功登錄。
取消登錄。
登錄失敗。對(duì)于客戶端而言,可以視為取消登錄。對(duì)于服務(wù)端來(lái)說(shuō),則可能是密碼錯(cuò)誤、用戶名不存在、賬號(hào)被鎖定等。
對(duì)應(yīng)于以上情景,又有一些通用的邏輯處理:
登錄成功。保存 Token,并返回歷史頁(yè)面。
登錄失敗。彈出一個(gè)自定義內(nèi)容的提示框。
這些代碼是相似的。
在一些簡(jiǎn)單的前端應(yīng)用里:
模板。只是在使用這些模板,再為這些模板設(shè)置相應(yīng)的屬性,綁定對(duì)應(yīng)的值。
數(shù)據(jù)。其過(guò)程都只是在各種保存變量的值,并 CRUD 這些變量的路上。為此,我們需要一個(gè)數(shù)據(jù)處理的管道架構(gòu)設(shè)計(jì),用于處理這些值。
函數(shù)。事實(shí)上,我們的所有函數(shù)都只是一些管理函數(shù),只用于處理這些對(duì)應(yīng)的邏輯。
這些常見的功能都可以做成一些組件,它們對(duì)于某些應(yīng)用來(lái)說(shuō),代碼相應(yīng)的重復(fù)。
無(wú)限加載頁(yè)面。只需要綁定上 API,再控制一下元素的顯示與隱藏即可。
表單。定義好字段即類型,對(duì)應(yīng)的前后臺(tái)邏輯都有了。除此,我們還需要為它們自定義好常見的規(guī)則,如正則表達(dá)式。而一旦表單之間有聯(lián)動(dòng),那么這個(gè)組件的設(shè)計(jì)就更加麻煩了。
卡片式元素。
表單和表格展示。
常見圖表。事實(shí)上,已經(jīng)有一系列的圖表工具了,我們只是在它們?cè)诨A(chǔ)上,進(jìn)行了二次封裝而已——使得它們可以變成領(lǐng)域語(yǔ)言的形式。
高級(jí)的響應(yīng)式布局。與每個(gè)應(yīng)用獨(dú)立開發(fā)布局不同的是,低代碼平臺(tái)需要提供一套強(qiáng)大的自定義、響應(yīng)式布局設(shè)計(jì)——即要滿足移動(dòng)端的通用模式,還要滿足桌面版的通用模式。如對(duì)于大量數(shù)據(jù)來(lái)說(shuō),桌面端使用的是 Pagination,移動(dòng)端使用的是無(wú)限滾動(dòng)。
事實(shí)上,對(duì)于后端來(lái)說(shuō),低成本平臺(tái)意味著,代碼生成及服務(wù)生成。而服務(wù)本身是有限的,既然是業(yè)務(wù)上發(fā)生了一些變化,后端服務(wù)也可能并不會(huì)發(fā)生變化。
它也意味著:
微服務(wù)化。每個(gè)后端服務(wù)要盡可能的小。
API 規(guī)范化。即采用統(tǒng)一的 API 格式,接受統(tǒng)一的權(quán)限管理
大量的 API 服務(wù)。
快速集成第三方服務(wù)方案。集成第三方服務(wù)是開發(fā)應(yīng)用不可避免的情況。為了應(yīng)對(duì)這個(gè)問(wèn)題,我們需要做準(zhǔn)備好對(duì)應(yīng)的創(chuàng)建服務(wù)邏輯,傳入第三方服務(wù)所需要的參數(shù),便可以直接生成我們的轉(zhuǎn)發(fā)服務(wù)。
那么,問(wèn)題來(lái)了,既然如此,我們是否能提供一個(gè)定制的工具呢?讓每個(gè)人可以創(chuàng)建自己的組件流?
答案,顯然是可以的。
于是乎,在我最近設(shè)計(jì)的 PoC (概念證明)里,采用的是 Anguar 框架。相應(yīng)的基本思想如下:
使用 Material Design 作為組件庫(kù),使用 CDK 的 Drag 來(lái)實(shí)現(xiàn)拖拽功能。每個(gè)拖拽的組件,稱為 Element(元素),由 ElementDispatcher 由根據(jù)數(shù)據(jù)生成對(duì)應(yīng)的組件??赏献У牟糠钟蓛刹糠纸M成:布局?+?元素。
UI 構(gòu)建完后,生成對(duì)應(yīng)的 DSL,目前采用的是 JSON。畢竟數(shù)據(jù)結(jié)構(gòu)是最簡(jiǎn)單的領(lǐng)域特定語(yǔ)言。
借由 Angular Schematics 解析這部分的 DSL,來(lái)生成相應(yīng)的項(xiàng)目代碼。
覺(jué)得不錯(cuò)請(qǐng)點(diǎn)贊支持,歡迎留言或進(jìn)我的個(gè)人群855801563領(lǐng)取【架構(gòu)資料專題目合集90期】、【BATJTMD大廠JAVA面試真題1000+】,本群專用于學(xué)習(xí)交流技術(shù)、分享面試機(jī)會(huì),拒絕廣告,我也會(huì)在群內(nèi)不定期答題、探討。