UI 設(shè)計(jì)代碼化:低代碼式設(shè)計(jì)語(yǔ)言——Unflow(ui設(shè)計(jì)代碼簡(jiǎn)單嗎)

UI 設(shè)計(jì)代碼化:低代碼式設(shè)計(jì)語(yǔ)言——Unflow(ui設(shè)計(jì)代碼簡(jiǎn)單嗎)

UI 設(shè)計(jì)代碼化,即將軟件的 UI 設(shè)計(jì)與 UI 交互轉(zhuǎn)換為特定的領(lǐng)域語(yǔ)言,并使用代碼的方式來(lái)進(jìn)行管理。它可以直接將需求轉(zhuǎn)換為 UI 原型,讓設(shè)計(jì)人員基于此進(jìn)行設(shè)計(jì);還負(fù)責(zé)將其轉(zhuǎn)換對(duì)應(yīng)的 UI 代碼,方便開(kāi)發(fā)人員進(jìn)行編寫(xiě)。

在 Uncode IDE 里,設(shè)計(jì)代碼化是由兩部分組成:架構(gòu)設(shè)計(jì)(代碼設(shè)計(jì))代碼化與 UI 設(shè)計(jì)代碼化,這是一個(gè)相當(dāng)復(fù)雜的領(lǐng)域。作為一個(gè)在前端領(lǐng)域的專家,我是在去年完成了 UI 設(shè)計(jì)代碼的第一個(gè)版本的設(shè)計(jì);作為半個(gè)架構(gòu)專家,我則是在最近完成了部分架構(gòu)設(shè)計(jì)代碼化的工作。

在最近 ,我剛使用 Rust 將去年設(shè)計(jì)的 UI DSL 重寫(xiě),于是重新命名為 Unflow。想不到一個(gè)更好的名字,于是將它與 Uncode 進(jìn)行了一個(gè)簡(jiǎn)單的對(duì)應(yīng)。你可以在 GitHub 上看到 Unflow 當(dāng)前(早期)版本的設(shè)計(jì):https://github.com/inherd/unflow 。

在繼續(xù)往下閱讀之前 ,我要做一個(gè)簡(jiǎn)單的聲明:在完成了 Unflow 的設(shè)計(jì)之后,我一直在等待機(jī)會(huì)能與一些用戶體驗(yàn)設(shè)計(jì)師合作,以完善整個(gè) DSL。但是呢,一直沒(méi)有找至一個(gè)合適的機(jī)會(huì)。所以,當(dāng)前的這個(gè) DSL 并不一定接近真實(shí)的設(shè)計(jì)師體驗(yàn)。

所以呢,如果你對(duì)優(yōu)先這個(gè) DSL 有興趣,可以一起參與設(shè)計(jì)。

UI 設(shè)計(jì)代碼化

UI 設(shè)計(jì)代碼化,即將軟件的 UI 設(shè)計(jì)與 UI 交互轉(zhuǎn)換為特定的領(lǐng)域語(yǔ)言,并使用代碼的方式來(lái)進(jìn)行管理。它可以直接將需求轉(zhuǎn)換為 UI 原型,讓設(shè)計(jì)人員基于此進(jìn)行設(shè)計(jì);還負(fù)責(zé)將其轉(zhuǎn)換對(duì)應(yīng)的 UI 代碼,方便開(kāi)發(fā)人員進(jìn)行編寫(xiě)。

為什么需要 UI 設(shè)計(jì)代碼化?

在文章開(kāi)頭里,我們定義了一下:UI 設(shè)計(jì)代碼化。但是呢,為什么我們需要一個(gè)這樣的代碼化工具呢?從整個(gè)云研發(fā)體系來(lái)說(shuō),將 UI 設(shè)計(jì)代碼化,我們要做的這么幾件事:

  1. 用戶交互文檔化。即所有的 UI 交互過(guò)程,以明確的格式記錄下來(lái),并與文檔的形式存儲(chǔ)。

  2. UI 工具無(wú)關(guān)。采用標(biāo)準(zhǔn)化的方式描述 UI 設(shè)計(jì),讓 UI 設(shè)計(jì)與 UI 設(shè)計(jì)工具脫離。

  3. 雙向反饋。即我們的設(shè)計(jì)與 UI 原型、代碼是相綁定的,當(dāng)代碼與設(shè)計(jì)不一致時(shí),我們能即時(shí)得到反饋 —— 要么修改設(shè)計(jì),要么修改代碼。

  4. 連接需求與代碼的膠水。從某種程度上來(lái)說(shuō),這個(gè) DSL 還承擔(dān)著作為需求與代碼連接的膠水。即將需求轉(zhuǎn)換為設(shè)計(jì)的描述,以便于這個(gè)描述轉(zhuǎn)換為代碼。

在云研發(fā)體系中,它是非常重要的一環(huán)。

如何進(jìn)行 UI 設(shè)計(jì)代碼化?

在今天來(lái)看,將 UI 設(shè)計(jì)進(jìn)行代碼化已經(jīng)變得相當(dāng)?shù)暮?jiǎn)單。只是呢,還有一些因素,會(huì)限制我們的代碼化能力:

矢量可編程的 UI 設(shè)計(jì)

UI 工具是整體過(guò)程中最令人頭痛的問(wèn)題。對(duì)于 UI 設(shè)計(jì)而言,如果它產(chǎn)出的內(nèi)容不是矢量圖形,那么它會(huì)限制我們的轉(zhuǎn)換能力 —— 一個(gè)二進(jìn)制文件不適合在代碼庫(kù)中存儲(chǔ)。而,如果一個(gè) UI 工具產(chǎn)生的格式是可直接編程操作的,那么就再好不過(guò)了,比如 SVG。但是呢,SVG 缺少一些引用等的相關(guān)設(shè)計(jì)。不過(guò)呢,Sketch 也是一個(gè)非常不錯(cuò)的工具,它的格式是易于進(jìn)行編程操作的。

UI 元素可編程。

在進(jìn)行 UI 設(shè)計(jì)的時(shí)候,我們會(huì)定義出一套 Design Sytem 或者 UI Guideline,上面充滿了豐富的元素,如組件、字體等。對(duì)于這些元素來(lái)說(shuō),它應(yīng)該是可以由代碼生成,或者直接轉(zhuǎn)換為設(shè)計(jì) DSL。以用于核驗(yàn)代碼中的元素是否真的與設(shè)計(jì)匹配。

對(duì)于交互的抽象。

對(duì)于交互的抽象是一個(gè)煩人的問(wèn)題,但是呢,在我深入研究與探索之后,我發(fā)現(xiàn)這也不是一個(gè)復(fù)雜的問(wèn)題。復(fù)雜度并不高,只是呢,我們要考慮如何與我們的設(shè)計(jì)、代碼進(jìn)行關(guān)聯(lián),形成統(tǒng)一的關(guān)系。

UI 設(shè)計(jì)代碼化要素

綜上所述,我們?cè)趯?duì) UI 進(jìn)行代碼化時(shí),要考慮這么一些要素。

要素 1:代碼反饋設(shè)計(jì)

在云研發(fā)體系里,我們將所有一切代碼化有兩個(gè)原因:

  1. 流程代碼化,并實(shí)現(xiàn)化轉(zhuǎn)換自動(dòng)化。

  2. 借助反饋進(jìn)行自動(dòng)優(yōu)化。

對(duì)于 UI 設(shè)計(jì)代碼化這一步來(lái)說(shuō),我們要:

  1. 尋找合適的 UI 設(shè)計(jì)工具及對(duì)應(yīng)的解析庫(kù),以將解析 UI 設(shè)計(jì),轉(zhuǎn)換為特定的領(lǐng)域語(yǔ)言。

  2. 能解析修改過(guò)后的生成代碼,將代碼實(shí)現(xiàn)與 UI 設(shè)計(jì)進(jìn)行對(duì)比。

  3. 自動(dòng)綁定 UI 設(shè)計(jì)與代碼,自動(dòng)修改、提示不合理的地方。

要素 2:支持增量變更

設(shè)計(jì)與代碼是相似的,在開(kāi)發(fā)過(guò)程中,會(huì)伴隨著需求的變化,影響到 UI 設(shè)計(jì)上的變化。因此,對(duì)于 UI 設(shè)計(jì)產(chǎn)物來(lái)說(shuō),它們應(yīng)該:

  1. 可版本化。與代碼庫(kù)同在,能跟蹤到設(shè)計(jì)的歷史變化。

  2. 可編碼??梢杂尚枨笊稍O(shè)計(jì),由代碼反饋到設(shè)計(jì)。

在有了這兩個(gè)條件的情況下,我們可以進(jìn)行增量變更。

要素 3:抽象交互

盡管,我在本文中提出了一套交互相關(guān)的 DSL,但是它并不是那么完善。除此呢,在不同的公司里,人們也會(huì)自己的一些特定的 UI 設(shè)計(jì)模式等。所以呢,我們還需要設(shè)計(jì)一種抽象來(lái)描述系統(tǒng)對(duì)于用戶的交互。

對(duì)于一個(gè)交互 DSL 來(lái)說(shuō),它需要做兩件事:

  1. 描述用戶交互。

  2. 能與需求進(jìn)行對(duì)應(yīng)。

  3. 能與代碼進(jìn)行對(duì)應(yīng)。

接下來(lái),讓我們看看 Unflow DSL 的設(shè)計(jì)。

Unflow DSL

基于此呢,我們?cè)O(shè)計(jì)了 Unflow,它具備了如下的三個(gè)模式:

  1. 三段式交互設(shè)計(jì):SEE-DO-React

  2. 拆分設(shè)計(jì):原子設(shè)計(jì)

  3. 布局系統(tǒng):AutoLayout 與 Flex 布局

除此呢,還有一個(gè)非常重要的部分:反饋式設(shè)計(jì),我暫時(shí)還沒(méi)有去驗(yàn)證。

模式 1 —— 三段式交互設(shè)計(jì):SEE-DO-REACT

在日常的軟件開(kāi)發(fā)活動(dòng)中,我們經(jīng)常會(huì)看到不同的三段式表達(dá):

  • BDD 里的:Given – When – Then

  • UI 設(shè)計(jì)的:顯示 – 行動(dòng) – 響應(yīng)

  • HTTP 請(qǐng)求的:request – handle – response

  • 代碼的:輸入?yún)?shù) – 處理 – 輸出結(jié)果

  • 測(cè)試的:Arrange-Act-Assert

  • 前端開(kāi)發(fā)的:展示 – 事件 – 響應(yīng)

對(duì)于 UI 設(shè)計(jì)來(lái)說(shuō),也存在類似的元素。我嘗試著從一堆論文中尋找經(jīng)驗(yàn),初始時(shí)我嘗試以 BDD 的三段式來(lái)總結(jié)。直到我看到了 Basecamp 的設(shè)計(jì)師 Ryan 在『A shorthand for designing UI flows』一文中看到幾句話:

  • What the user sees

  • What them do

  • What them see next / what them do next

基于此,添加了一個(gè) REACT 的選項(xiàng),即系統(tǒng)要對(duì)他們做出什么響應(yīng)。于是,有了一個(gè)簡(jiǎn)單的 DSL 原型:

  1. flow 登錄 {

  2. SEE 首頁(yè)

  3. DO 輸入密碼

  4. DO [點(diǎn)擊] \"登錄\".Button

  5. REACT 成功: 展示 \"Login Success\".ToastwithANIMATE(bounce)

  6. REACT 失敗: 展示 \"Login Failure\".Dialog

  7. }

這里的 SEE 對(duì)應(yīng)了用戶的所見(jiàn),DO 則是對(duì)應(yīng)于用戶所做,而 REACT 則是相應(yīng)的可能結(jié)果。我們可以將它與需求代碼化里的 Given-When-Then 進(jìn)行一一應(yīng)對(duì)。稍有區(qū)別的是,這里在 REACT 里進(jìn)行了合并,方便后續(xù)與 UI 代碼進(jìn)行對(duì)應(yīng):

  1. 調(diào)用接口成功的場(chǎng)景下,則顯示 Login Success,然后再往下進(jìn)行操作。

  2. 調(diào)用接口失敗的場(chǎng)景下,則顯示 Login Failure 彈窗(Dialog),然后可以添加其它行為。

上述代碼中的首頁(yè),可以對(duì)應(yīng)到 UI 設(shè)計(jì)的場(chǎng)景、原型上,對(duì)應(yīng)的按鈕(Button) 則是組件使用上的聲明。與此同時(shí),基于上述的一系列關(guān)鍵描述,如 Login Success、Login Failure 還創(chuàng)建了對(duì)應(yīng)的 UI 設(shè)計(jì)上的場(chǎng)景。

模式 2 —— 元素拆分:原子設(shè)計(jì)與元素定義

在設(shè)計(jì)人員與開(kāi)發(fā)人員協(xié)作的過(guò)程中,Brad Frost 創(chuàng)建了原子設(shè)計(jì)的概念:原子設(shè)計(jì)是一個(gè)設(shè)計(jì)方法論,由五種不同的階段組合,它們協(xié)同工作,以創(chuàng)建一個(gè)有層次、計(jì)劃性的方式來(lái)界面系統(tǒng)。

于是,在 Unflow 中,我們依然采用了這個(gè)理念,與之對(duì)應(yīng)的設(shè)計(jì)是:

  • 原子 – library。描述基礎(chǔ)、庫(kù)組件的一些要素。

  • 分子級(jí) – component。描述組件

  • 有機(jī)體 – component。描述組件

  • 模板 – template。

  • 頁(yè)面 – page

這里的 library、component、template、page 都是 Unflow 中的定義。Unflow 的 DSL 只是提供定義,如下是一個(gè)對(duì)于顏色規(guī)范的定義:

  1. library Color{

  2. Primary{

  3. label = \"Primary\"

  4. value = \"#E53935\"

  5. }

  6. Secondary{

  7. label = \"Blue\"

  8. value = \"#1E88E5\"

  9. }

  10. Third{

  11. label = \"Third\"

  12. value = \"#000000\"

  13. }

  14. }

Unflow 定義的是這些要素,隨后結(jié)合其它工具進(jìn)行轉(zhuǎn)換。在早期 ,我們結(jié)合 Node.js 里的 Sketch Constructor 進(jìn)行了轉(zhuǎn)換,它將轉(zhuǎn)變?yōu)閮刹糠郑篠ketch 里的顏色規(guī)范定義,以及前端代碼庫(kù)里的 SCSS 定義。

這種定義方式,對(duì)于 component、page也是類似的。

  1. page HomePage{

  2. LayoutGrid:12x

  3. LayoutId:HomePage

  4. Router:\"/home\"# 由開(kāi)發(fā)定義

  5. }

稍有不同的是,我們?cè)谠O(shè)計(jì)中加入了一個(gè)路由的概念,這個(gè)后期可以由開(kāi)發(fā)人員來(lái)進(jìn)行補(bǔ)充。

順帶一說(shuō),依舊的這只是 Unflow 的第一個(gè)版本,所以在設(shè)計(jì)上會(huì)比較粗糙。

模式 3 —— 布局系統(tǒng):Flex

起先,如果只是站在早期的布局系統(tǒng)的維度之下,我怕是沒(méi)有膽量去設(shè)計(jì)一個(gè) DSL。而隨著不同領(lǐng)域?qū)τ?Flex 布局的統(tǒng)一化程度:

  • 移動(dòng)端框架 Flutter 中的線性布局(Row、Column)

  • 原生 UI 框架 Druid 采用的 Flex 布局

  • 前端領(lǐng)域采用的 Flex 布局

  • Android 端的 FlexboxLayout

  • ……

那么,對(duì)于我們的布局系統(tǒng)來(lái)說(shuō),自然采用的是類似于 Flex 布局。如此一來(lái),我們只需要考慮一下結(jié)合 Apple 的 Auto Layout,就能得到一個(gè)勉強(qiáng)可以用的 UI 系統(tǒng)。

而,我最早對(duì)于 Layout 體系的想法,語(yǔ)法來(lái)源是 autolayout.js。一個(gè)在前端實(shí)現(xiàn)了 AutoLayout 和 Visual Format Language 的布局系統(tǒng),它的語(yǔ)法如下:

  1. H:|[view1(==view2)]-10-[view2]|

  2. V:|[view1,view2]|

雖是如此,我設(shè)計(jì)的第一個(gè)版本的布局系統(tǒng)有點(diǎn)不那么實(shí)用。關(guān)于這一點(diǎn),我還在自我反思 ,為什么會(huì)設(shè)計(jì)出這么難寫(xiě)的語(yǔ)法:

  1. LayoutNavigation{

  2. --------------------------------------

  3. | \"home\"|\"detail\"|Button(\"Login\") |

  4. --------------------------------------

  5. }

在設(shè)計(jì)布局的時(shí)候,想的是:

  1. 以 Flex 作為實(shí)現(xiàn)方式

  2. 以 Table 作為展示形式,方便開(kāi)發(fā)人員維護(hù)

  3. 支持組件上的參數(shù)傳遞

在這種限制的交錯(cuò)之下,就有了現(xiàn)在這種奇怪的設(shè)計(jì)。

其它

Unflow 正在設(shè)計(jì)中,歡迎為 Unflow 提出您的意見(jiàn):https://github.com/inherd/unflow

參考資料:

  • A shorthand for designing UI flows

  • https://github.com/inherd/unflow

  • https://github.com/IjzerenHein/autolayout.js

  • https://github.com/dorostanian/sushi

  • Understanding Auto Layout

相關(guān)新聞

聯(lián)系我們
聯(lián)系我們
公眾號(hào)
公眾號(hào)
在線咨詢
分享本頁(yè)
返回頂部