低程式碼平臺中的“不可能三角”

danny_2018發表於2024-01-29

近年來,“低程式碼”這一概念在資本市場上愈發火熱,各種低程式碼平臺專案也紛紛上馬。

然而,此類平臺的設計者與維護者們,或早或晚,終將會面對“低程式碼”與生俱來的一組底層矛盾,而是否能合理地處理這組矛盾,最終決定了此平臺的發展前景。

背景

我們團隊正在維護一套基於DSL(領域特定語言)的表單管理平臺。該平臺由客戶方團隊自建,其中包含了前端UI、資料管理、表單規則管理等模組。設計目標是:讓業務人員以書寫DSL的方式定義表單模板,此後可以直接基於模板生成UI並管理表單資料,從而達到低程式碼甚至零程式碼建立表單的效果。該平臺自建立以來,已經支援了數百個大型表單的成功上線,支援了公司業務的快速成長。然而隨著業務的持續發展,該平臺的疲態也日益凸顯:

難以支援複雜的表單需求(可用的表單元件、資料結構、DSL語法不足,且新增成本過高);

平臺程式碼極度難以維護;

大型表單的效能表現糟糕。

不可能三角

以上案例,生動展現了一款低程式碼平臺的典型生命週期:

前期:平臺能力弱,但業務也簡單。平臺開始起步。

中期:平臺能力趨於成熟,業務逐漸變得複雜但仍在平臺能力範圍之內。平臺支撐著業務快速發展。

後期:平臺觸達能力上限,部分業務需求開始超出平臺能力。

而此類平臺之所以會有如此表現,根本癥結在於其發展受到了“低程式碼”天然自帶的一組矛盾的掣肘,該矛盾可以用不可能三角的形式加以描述:

如圖,該三角的三個頂點分別代表了低程式碼平臺的三個核心設計目標:

Easy to Use - 易於使用

Powerful - (功能)強大

Low Complexity - 低(系統)複雜度

而這三個目標形成了如此一個三角形的結構,意味著在同一低程式碼平臺上,他們永遠不可能同時被滿足:

若一平臺在易於使用的同時功能強大,則必然擁有較高的系統複雜度。

其中,系統複雜度與維護成本成正比,與系統效能成反比。也即,較高的系統複雜度最終會導致平臺擁有較高的維護成本以及較低的系統效能。

例子:人工智慧程式設計。使用者只需使用自然語言描述需求(易於使用),系統就能生成程式碼(功能強大),但該技術至今仍未完全成熟(高系統複雜度)。

若一平臺易於使用的同時保持低系統複雜度,則必然功能受限

例子:Scratch少兒程式設計。使用圖形化介面程式設計(易於使用),指令只需經過簡單翻譯即可執行(低系統複雜度),但功能只能滿足教學目的(功能受限)。

若一平臺功能強大的同時保持低系統複雜度,則必然擁有較高的使用成本

例子:通用程式語言。圖靈完備理論上可以實現任何功能(功能強大),編譯或解釋為機器指令執行(低系統複雜度),但存在較高的專業門檻(高使用成本)。

出路

正所謂,

軟體工程就是trade-off的藝術

對於低程式碼平臺上述的三個目標來說,“我全都要”的結果只能是“全都得不到”,最終勢必會陷入到按下葫蘆浮起瓢的窘境當中。所以,對於任何一款低程式碼平臺的設計者來說,做出合理的trade-off都將是所有工作中的重中之重。

那麼如何trade-off來破解“不可能三角”呢?需要基於以下2個事實:

事實1:易用性與效能/可維護性不可放棄

通常,一款低程式碼產品的宣傳會向我們許諾至少以下兩個承諾:

低程式碼平臺一定會比傳統開發方式更方便/更快速/更易上手

低程式碼平臺的最終產物一定是可執行的商業應用

對應到我們的三個核心設計目標上去,很容易看出:

第1條直接要求低程式碼平臺必須是易於使用的,尤其是相對於傳統方式要有顯著優勢,這是此類平臺的核心競爭力。否則面對同樣需求,客戶為何不選擇更成熟可靠的傳統方案,而要使用低程式碼平臺呢?

第2條則要求低程式碼平臺以及其產物必須是生產可用的。這要求平臺的產物要具有可接受的效能與可維護性,從而要求平臺的複雜度不宜過高。而低效能或不可維護的產品則是斷然無法應用在生產中的。

與之相對的,雖然低程式碼平臺也會將“功能強大”作為其一大賣點,但又往往會特意強調其功能具有特定的應用範圍。常見的有針對企業工作流、報表、ERP等場景設計的低程式碼平臺。

綜上,三個設計目標可以被簡短的總結為:

易於使用是魂,是平臺的意義所在。

低複雜度是骨,是平臺在生產中可用的基石。

功能強大是肉,是平臺價值的組成部分。

事實2:單一方案至多隻能滿足80%場景

我們可以將一款低程式碼平臺所面向的問題域,劃分為封閉問題域與開放問題域兩類,它們之間的區別在於問題空間是否存在確定的邊界。

對於那些專注於解決封閉問題域問題的低程式碼方案,經過精心設計,是有機會做到使用一個通用方案覆蓋100%域內場景的。此類方案中的佼佼者有SQL之於資料查詢領域,可以實現幾乎所有查詢需求。

然而對於一個開放問題域來說,由於不可能窮盡域內所有可能的問題場景,則可以說完全不可能存在有某個單一的“終極方案”,能夠憑一己之力解決域內所有問題。

例如說對於一個To C的低程式碼開發平臺,在UI互動方面,它的問題域就是開放的。

因為終端使用者的互動需求無法窮盡:同樣是展示資料,既可以用文字、表格,亦可以用圖表、3D模型,甚至可以用AR、VR……

也因此,平臺不可能提供一個滿足100%應用場景的UI構建方案。

所以,我們可以化用“二八定律”對這個問題做個略微粗暴的總結(當然這裡的2與8都是虛數):

對於一開放問題域,任何單一方案至多隻能滿足其80%場景。

逃生艙

注:筆者非常喜歡React新版文件中所使用的“逃生艙”(Escape Hatches)這一比喻,因此在此處也借鑑一番。但需要注意的是,這篇文章中的逃生艙與React中的概念並不完全相同,還需讀者自行鑑別。

聊到這裡,其實我們的策略已經不言而喻了。如上所述,已知:

事實1:易用性與效能/可維護性不可放棄

事實2:單一方案至多隻能滿足80%場景

顯而易見,對於平臺設計者來說,他們應該將絕大部分精力投入到服務好平臺最擅長的那80%業務場景當中去,竭盡全力在優勢領域中做到盡善盡美。

至於剩餘的20%邊緣場景,在某些時候,直接放棄或許也是一種可以接受的選項。

當然,對於那些富有野心的平臺來說,這恐怕難以接受。那麼此時的策略便是本節的標題所指:在平臺設計之初,設計者就應該考慮到為將來某些高階使用者提供一個完善的“逃生艙”機制。

這裡的“逃生艙”指的是一種向平臺使用者暴露底層能力的機制。它可以是一組低階API,也可以是一批可供二開擴充套件的整合點,甚至也可以是一套進行定製開發的解決方案。總之,為了滿足從過去至將來100%的業務需求,平臺必須允許使用者在有必要的時候進行“抽象降級”,有機會乘坐逃生艙從平臺規定的條條框框之中逃離。

這樣的設計思想其實在軟體工程領域相當常見,譬如plugin API之於webpack、unsafe之於rust、指標之於C#等等……只不過由於低程式碼平臺本身業務的複雜性,設計出一套優雅的“逃生艙”機制並不容易,因此設計者在平臺設計的早期就必須考慮這個問題。

當前我們團隊遇到的問題,就是由於平臺早期缺乏良好的“逃生艙”設計,導致了面對超出平臺能力的新需求時無從下手:

若在原有架構上修修補補——複雜度爆炸

若把架構推倒重來——工期爆炸

若拒絕支援新需求——PM爆炸

可以用一個詞來形容——積重難返。

小結

如上,筆者將本人在低程式碼平臺上遇到的困難與思考進行了些淺顯總結,斗膽試圖藉此來發現一點架構設計的普遍規律,慚愧慚愧……

文章最後,再試著簡單總結一些由本文觀點得出的建議。

對於平臺使用者

對於使用者來說,最大的啟示是在技術選型的階段最好留個心眼,切勿輕信了平臺銷售對其產品功能的吹噓。尤其是如果有人膽敢宣揚他的平臺無所不能,今天開發明天上線後天解僱程式設計師云云,那你可得小心了。

正如前文所言,任何低程式碼產品的出發點都是為了降低使用者的使用成本,所以如果一個平臺即承諾了易用性,又承諾了功能性,那麼代價是什麼?

經驗來說,反倒是專注於一個特定領域的平臺供應商往往更加務實,也有更大機率做出更成熟的產品。

對於平臺設計者

對於設計者來說,最大的挑戰是在如上不可能三角中取得平衡。對於不同型別的系統設計取向自然也不同,但對於低程式碼平臺這一品類來說,大部分情況下,易用性和系統複雜度還是比功能性重要的多。

因此如果你的產品也具有類似的價值取向的話,那麼作為架構設計者,儘早地規劃“逃生艙”的設計和落實才是負責任的做法。

來自 “ DevOps ”, 原文作者:DevOps;原文連結:https://mp.weixin.qq.com/s/Lb0p2AOTaY89HcUcFGekJQ,如有侵權,請聯絡管理員刪除。

相關文章