UI 设计代码化:低代码式设计语言 —— Unflow
UI 设计代码化,即将软件的 UI 设计与 UI 交互转换为特定的领域语言,并使用代码的方式来进行管理。它可以直接将需求转换为 UI 原型,让设计人员基于此进行设计;还负责将其转换对应的 UI 代码,方便开发人员进行编写。
在 Uncode IDE 里,设计代码化是由两部分组成:架构设计(代码设计)代码化与 UI 设计代码化,这是一个相当复杂的领域。作为一个在前端领域的专家,我是在去年完成了 UI 设计代码的第一个版本的设计;作为半个架构专家,我则是在最近完成了部分架构设计代码化的工作。
在最近 ,我刚使用 Rust 将去年设计的 UI DSL 重写,于是重新命名为 Unflow。想不到一个更好的名字,于是将它与 Uncode 进行了一个简单的对应。你可以在 GitHub 上看到 Unflow 当前(早期)版本的设计:https://github.com/inherd/unflow 。
在继续往下阅读之前 ,我要做一个简单的声明:在完成了 Unflow 的设计之后,我一直在等待机会能与一些用户体验设计师合作,以完善整个 DSL。但是呢,一直没有找至一个合适的机会。所以,当前的这个 DSL 并不一定接近真实的设计师体验。
所以呢,如果你对优先这个 DSL 有兴趣,可以一起参与设计。
UI 设计代码化
UI 设计代码化,即将软件的 UI 设计与 UI 交互转换为特定的领域语言,并使用代码的方式来进行管理。它可以直接将需求转换为 UI 原型,让设计人员基于此进行设计;还负责将其转换对应的 UI 代码,方便开发人员进行编写。
为什么需要 UI 设计代码化?
在文章开头里,我们定义了一下:UI 设计代码化。但是呢,为什么我们需要一个这样的代码化工具呢?从整个云研发体系来说,将 UI 设计代码化,我们要做的这么几件事:
用户交互文档化。即所有的 UI 交互过程,以明确的格式记录下来,并与文档的形式存储。
UI 工具无关。采用标准化的方式描述 UI 设计,让 UI 设计与 UI 设计工具脱离。
双向反馈。即我们的设计与 UI 原型、代码是相绑定的,当代码与设计不一致时,我们能即时得到反馈 —— 要么修改设计,要么修改代码。
连接需求与代码的胶水。从某种程度上来说,这个 DSL 还承担着作为需求与代码连接的胶水。即将需求转换为设计的描述,以便于这个描述转换为代码。
在云研发体系中,它是非常重要的一环。
如何进行 UI 设计代码化?
在今天来看,将 UI 设计进行代码化已经变得相当的简单。只是呢,还有一些因素,会限制我们的代码化能力:
矢量可编程的 UI 设计。
UI 工具是整体过程中最令人头痛的问题。对于 UI 设计而言,如果它产出的内容不是矢量图形,那么它会限制我们的转换能力 —— 一个二进制文件不适合在代码库中存储。而,如果一个 UI 工具产生的格式是可直接编程操作的,那么就再好不过了,比如 SVG。但是呢,SVG 缺少一些引用等的相关设计。不过呢,Sketch 也是一个非常不错的工具,它的格式是易于进行编程操作的。
UI 元素可编程。
在进行 UI 设计的时候,我们会定义出一套 Design Sytem 或者 UI Guideline,上面充满了丰富的元素,如组件、字体等。对于这些元素来说,它应该是可以由代码生成,或者直接转换为设计 DSL。以用于核验代码中的元素是否真的与设计匹配。
对于交互的抽象。
对于交互的抽象是一个烦人的问题,但是呢,在我深入研究与探索之后,我发现这也不是一个复杂的问题。复杂度并不高,只是呢,我们要考虑如何与我们的设计、代码进行关联,形成统一的关系。
UI 设计代码化要素
综上所述,我们在对 UI 进行代码化时,要考虑这么一些要素。
要素 1:代码反馈设计
在云研发体系里,我们将所有一切代码化有两个原因:
流程代码化,并实现化转换自动化。
借助反馈进行自动优化。
对于 UI 设计代码化这一步来说,我们要:
寻找合适的 UI 设计工具及对应的解析库,以将解析 UI 设计,转换为特定的领域语言。
能解析修改过后的生成代码,将代码实现与 UI 设计进行对比。
自动绑定 UI 设计与代码,自动修改、提示不合理的地方。
要素 2:支持增量变更
设计与代码是相似的,在开发过程中,会伴随着需求的变化,影响到 UI 设计上的变化。因此,对于 UI 设计产物来说,它们应该:
可版本化。与代码库同在,能跟踪到设计的历史变化。
可编码。可以由需求生成设计,由代码反馈到设计。
在有了这两个条件的情况下,我们可以进行增量变更。
要素 3:抽象交互
尽管,我在本文中提出了一套交互相关的 DSL,但是它并不是那么完善。除此呢,在不同的公司里,人们也会自己的一些特定的 UI 设计模式等。所以呢,我们还需要设计一种抽象来描述系统对于用户的交互。
对于一个交互 DSL 来说,它需要做两件事:
描述用户交互。
能与需求进行对应。
能与代码进行对应。
接下来,让我们看看 Unflow DSL 的设计。
Unflow DSL
基于此呢,我们设计了 Unflow,它具备了如下的三个模式:
三段式交互设计:SEE-DO-REACT
拆分设计:原子设计
布局系统:AutoLayout 与 Flex 布局
除此呢,还有一个非常重要的部分:反馈式设计,我暂时还没有去验证。
模式 1 —— 三段式交互设计:SEE-DO-REACT
在日常的软件开发活动中,我们经常会看到不同的三段式表达:
BDD 里的:Given - When - Then
UI 设计的:显示 - 行动 - 响应
HTTP 请求的:request - handle - response
代码的:输入参数 - 处理 - 输出结果
测试的:Arrange-Act-Assert
前端开发的:展示 - 事件 - 响应
对于 UI 设计来说,也存在类似的元素。我尝试着从一堆论文中寻找经验,初始时我尝试以 BDD 的三段式来总结。直到我看到了 Basecamp 的设计师 Ryan 在『A shorthand for designing UI flows』一文中看到几句话:
What the user sees
What them do
What them see next / what them do next
基于此,添加了一个 React 的选项,即系统要对他们做出什么响应。于是,有了一个简单的 DSL 原型:
flow 登录 {
SEE 首页
DO 输入密码
DO [点击] "登录".Button
REACT 成功: 展示 "Login Success".Toast with ANIMATE(bounce)
REACT 失败: 展示 "Login Failure".Dialog
}
这里的 SEE 对应了用户的所见,DO 则是对应于用户所做,而 REACT 则是相应的可能结果。我们可以将它与需求代码化里的 Given-When-Then 进行一一应对。稍有区别的是,这里在 REACT 里进行了合并,方便后续与 UI 代码进行对应:
调用接口成功的场景下,则显示 Login Success,然后再往下进行操作。
调用接口失败的场景下,则显示 Login Failure 弹窗(Dialog),然后可以添加其它行为。
上述代码中的首页,可以对应到 UI 设计的场景、原型上,对应的按钮(Button) 则是组件使用上的声明。与此同时,基于上述的一系列关键描述,如 Login Success、Login Failure 还创建了对应的 UI 设计上的场景。
模式 2 —— 元素拆分:原子设计与元素定义
在设计人员与开发人员协作的过程中,Brad Frost 创建了原子设计的概念:原子设计是一个设计方法论,由五种不同的阶段组合,它们协同工作,以创建一个有层次、计划性的方式来界面系统。
于是,在 Unflow 中,我们依然采用了这个理念,与之对应的设计是:
原子 - library。描述基础、库组件的一些要素。
分子级 - component。描述组件
有机体 - component。描述组件
模板 - template。
页面 - page
这里的 library、component、template、page 都是 Unflow 中的定义。Unflow 的 DSL 只是提供定义,如下是一个对于颜色规范的定义:
library Color {
Primary {
label = "Primary"
value = "#E53935"
}
Secondary {
label = "Blue"
value = "#1E88E5"
}
Third {
label = "Third"
value = "#000000"
}
}
Unflow 定义的是这些要素,随后结合其它工具进行转换。在早期 ,我们结合 Node.js 里的 Sketch Constructor 进行了转换,它将转变为两部分:Sketch 里的颜色规范定义,以及前端代码库里的 SCSS 定义。
这种定义方式,对于 component
、 page
也是类似的。
page HomePage {
LayoutGrid: 12x
LayoutId: HomePage
Router: "/home" # 由开发定义
}
稍有不同的是,我们在设计中加入了一个路由的概念,这个后期可以由开发人员来进行补充。
顺带一说,依旧的这只是 Unflow 的第一个版本,所以在设计上会比较粗糙。
模式 3 —— 布局系统:Flex
起先,如果只是站在早期的布局系统的维度之下,我怕是没有胆量去设计一个 DSL。而随着不同领域对于 Flex 布局的统一化程度:
移动端框架 Flutter 中的线性布局(Row、Column)
原生 UI 框架 Druid 采用的 Flex 布局
前端领域采用的 Flex 布局
Android 端的 FlexboxLayout
……
那么,对于我们的布局系统来说,自然采用的是类似于 Flex 布局。如此一来,我们只需要考虑一下结合 Apple 的 Auto Layout,就能得到一个勉强可以用的 UI 系统。
而,我最早对于 Layout 体系的想法,语法来源是 autolayout.js。一个在前端实现了 AutoLayout 和 Visual Format Language 的布局系统,它的语法如下:
H:|[view1(==view2)]-10-[view2]|
V:|[view1,view2]|
虽是如此,我设计的第一个版本的布局系统有点不那么实用。关于这一点,我还在自我反思 ,为什么会设计出这么难写的语法:
Layout Navigation {
--------------------------------------
| "home" |"detail" | Button("Login") |
--------------------------------------
}
在设计布局的时候,想的是:
以 Flex 作为实现方式
以 Table 作为展示形式,方便开发人员维护
支持组件上的参数传递
在这种限制的交错之下,就有了现在这种奇怪的设计。
其它
Unflow 正在设计中,欢迎为 Unflow 提出您的意见: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
UI 设计代码化:低代码式设计语言 —— Unflow相关推荐
- 如何设计一个低代码平台
编者按:近些年来,低代码发展火热,各种低代码平台如雨后春笋纷纷崛起,这些平台各定位不同,优劣不同,用户的选择空间很大.那么,如果用户想从零开始设计一个低代码平台,该如何做呢? 一.面向领域 低代码的本 ...
- 【APP平台化】APP平台化、低代码平台设计思路与实现
要实现 APP 平台化并支持页面定制化,类似于低代码平台,可以采用以下步骤和方法: 架构设计:从架构的角度出发,将 APP 设计为可插拔的模块化结构,其中包括核心功能模块.界面显示模块和定制化模块.确 ...
- 如何使用低代码平台设计一套请假流程?
在公司的日常运营当中,请假流程几乎是每个公司都普通存在的办公流程.传统办公模式里,都是采用的纸质填单的方式完成,而纸质方式存在保存不便,查询繁琐等问题.而在百数低代码平台里,企业可以把数据完全放到云端 ...
- 小程序中的权限设计_低代码布道师的博客-CSDN博客
日常我们开发小程序的时候,经常需要考虑权限如何设计,比如在我的页面,管理员可以看到一些菜单,而普通用户可以看到另外一些菜单.那如何设计这种带权限的功能呢?本文就以低代码工具为例,看看低代码中是如何设计 ...
- 响应式网页设计教程:展示响应式设计的基本原理
响应式网页设计,毫无疑问地变得越来越重要了.如果你还没听说过响应式设计,可以先看看我之前发的文章响应式网站.对新手来说, 响应式设计听起来可能会有点复杂, 但事实上,它比你想象的简单得多.为了让你能快 ...
- 前端设计 响应式设计_如何响应式设计
前端设计 响应式设计 This guest post about responsive design comes from Krasimir Tsonev! 这个关于响应式设计的来宾帖子来自Krasi ...
- 学习笔记:IDF 移动端UX设计 1.4 响应式设计vs.适应式设计
1.4: Responsive vs. Adaptive Design 响应式设计 vs. 适应式设计 移动端UX设计简介 Mint公司的原顶尖设计师总结:移动端UX设计本质上是情感上吸引人的,高度可 ...
- 毕业设计 c语言编译器的设计开发-字节代码格式设计与实现 开题报告,C语言编译器设计与实现...
C语言编译器设计与实现(任务书,外文翻译,毕业论文20000字,答辩PPT) 摘 要 随着计算机的广泛应用,计算机程序设计语言也从初期的机器语言发展为汇编语言,以及现在的各种高级程序设计语言.而编译技 ...
- 基于SaaS化的低代码平台设计思路(二)
经过多日的整理,数据库结构算是把初版本弄出来了,准备采用DDD的模式进行,类似于金蝶这样的产品,直接通过BOS设计器进行业务单据的开发.摒弃传统的手工一行一行敲代码,将业务进行细化,用业务驱动整个平台 ...
最新文章
- R语言一键批量完成差异统计和可视化
- Loadrunner日志设置与查看
- 网络通信模型(IO模型)
- C#显示相机实时画面
- 迭代器、for循环本质、生成器、常用内置方法整理
- ADO学习(三)Command 对象
- [软件项目管理]从业余人士往专家进军的头几个月
- python执行sqlserver存储过程_python – 从SqlAlchemy调用MSSQL存储过程
- latex中插图心得
- cocos2d-js 热更新具体解释(一)
- java手动切换成独立显卡_JAVA设计模式之调停者模式
- mysql实际应用在哪里_MySQL数据库的实际应用步骤
- Adapter 如果客户需要使用某个类的服务,而这项服务是这个类用一个不同的接口提供的,那么,可以使用适配器模式为客户提供一个期望的接口...
- java 获取域名_Java获取域名,Java从URL地址中获取域名,Java从Request 获取域名
- 55. GridPanel中getSelectionModel详解
- 【Maven使用】IDEA使用Maven进行文件打包+命令含义+错误分析
- 校验和checksum、哈希值是什么?
- 12306中前端验证身份证件(及其他证件号)的方法
- 企业邮箱部署SSL证书
- elastix2.5vtigercrm5.2.1来电弹屏和点击呼叫的配置
热门文章
- 经典CNN卷积神经网络发展史
- win10如何设置定时关机?
- hadoop编程:分析CSDN注册邮箱分布情况
- Chrome 的哪些功能改变了我们浏览网页的方式?
- eclipse新建java项目报错:Failed to init ct.sym for ....../jrt-fs.jar
- PDF格式人工转为Excel
- WIN10 双显示器设置
- android 陀螺仪简单使用,判读手机是否静止状态
- VB创建写字板小程序
- Day3_Pytorch入门——人脸标点绘图(简单)