需求代码化
需求代码化,即将软件开发需求抽象为特定的领域语言,并使用管理代码一样的方式来管理需求,追踪需求的变化 。同时,为通过新的 API 来对接版本管理系统,以可视化需求,演变为看板代码化。
为了解决某种需求/需要,我们计划设计一个软件系统。通过与利益相关者进行交流之后,确认了新的系统是有必要存在的。于是,我们产生了一系列的概念和想法,并通过诸如愿景梳理、用户分析等一系列的想法,我们将这些想法明确下来。
在开始软件开发前,我们定义好了产品是什么,随后梳理出了用户故事地图。我们定义了在什么场景下,需要哪些用户,在哪里做些什么事情,并对这些行为做出响应。有了这些定义之后,我们作为这个系统的架构设计师,便开始思考需要保存、显示哪些数据,才能完成这个业务目标。
在进入开发之前,这些想法设计等,都被明确为软件需求,简称为需求。
软件需求指为用户解决某一问题或达到某一目标所需的软件功能;系统或系统构件为了满足合同、规约、标准或其他正式实行的文档而必须满足或具备的软件功能。
为了进入万物代码化的世界,首先我们得准备一堆机制,以将物理世界的目标转换为软件问题。即我们要将软件需求,转换为代码。
引子 1:需求关联对应代码
事实上,关于这部分的内容已经存在了很久了。
早期,我们在项目上使用 Atlassian Bamboo + Atlassian Jira 时,它们已经可以非常好地配合在一起。你可以从持续集成上,直接跳转到需求处。
另外一种模式,则是透明的开源模式。如 GitHub 的 issue 与提交信息的关联,使得我们可以通过 done #123
or fixed #123
的形式来关联一个 issue(可能是需求),并关闭这个 issue。
反之,我们可以通过一个需求,来找到对应的代码提交。
引子 2:提交信息规范化
作为一个懒散的开源项目造轮子工程师,我习惯性地采用了社区规范的提交信息,以便于生成项目的 ChangeLog。诸如于:docs(changelog): update change log to beta.5
,它遵循的是如下的示例:
<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
如下是部分类型的示例:
- build: 影响构建系统或外部依赖关系的更改(示例范围:gulp,broccoli,npm)
- ci: 更改我们的持续集成文件和脚本(示例范围:Travis,Circle,BrowserStack,SauceLabs)
- docs: 仅文档更改
- feat: 一个新功能
- fix: 修复错误
- perf: 改进性能的代码更改
- refactor: 代码更改,既不修复错误也不添加功能
- style: 不影响代码含义的变化(空白,格式化,缺少分号等)
- test: 添加缺失测试或更正现有测试
为了这套提交信息模板,我们就可以结合 git-cz
这样的工具,在本地进行提交信息的规范化。同时,在 Git 服务器里,设置对应的提交信息门禁——即如果提交信息不满足规范,则代码无法提交到服务器中。
与之更为相似的一个概念是:
代码门禁能够确保每一个进入主分支的commit都达到了一定的质量标准,例如:编译必须通过,单元测试和接口测试必须通过,新代码的覆盖率不能低于某个水平,静态代码扫描必须通过。
引子 3:行为驱动开发语言
BDD 这个东西,大家都比较熟了。这里就不详细介绍了:
行为驱动开发(英語:Behavior-driven development,缩写BDD)是一种敏捷软件开发的技术,它鼓励软件项目中的开发者、QA和非技术人员或商业参与者之间的协作。
流行的 BDD 工具 Cucumber 背后是一个名为 Gherkin 的 DSL,它用于描述需求及测试。
功能:
场景:
假设:
当:
并且:
那么:
换句话来说,它可以作为我们的需求描述语言规范。
引子 4:三段式结构
三段式,大家都比较熟悉,我们可以按自己的需求,将所有的东西都转化为三段式:
- BDD 的:Given - When - Then
- UI 设计的显示 - 行动 - 响应
- 前端开发的:展示 - 事件 - 响应
- HTTP 请求的:request - handle - response
- 代码的:输入参数 - 处理 - 输出结果
- 测试的:Arrange-Act-Assert
- ……
如果不熟悉的话, 可以简单地看一下我之前设计的一个设计语言示例:
SEE HomePage
DO [Click] "Login".Button
REACT Success: SHOW "Login Success".Toast with ANIMATE(bounce)
就这么简单。
引子 5:源码控制管理而非数据库
在上一篇文章《文档代码化》中,我们已经建议了开发人员使用像代码一样的文档语言,使用 Git 来管理文档。它有这么一些优点:
- 高透明性
- 高自治性
- 不可篡改性
- 高安全性
这可不是区块链技术,这是需求代码化技术,【狗头】。当我们的需求变成了代码,那么我们就有了一个去中心化的看板。
需求代码化
好了,现在我们有相同的上下文,让我们回到正题上:
需求代码化,即将软件开发需求抽象为特定的领域语言,并使用管理代码一样的方式来管理需求,追踪需求的变化 。同时,为通过新的 API 来对接版本管理系统,以可视化需求,演变为看板代码化。
它具备这么一些特征:
- 使用标记语言编写内容。如 Cucumber
- 可通过版本控制系统进行版本控制。如 git
- 与编程一致的编程体验,还可以作为测试代码的一部分
- 支持集成到现有的看板系统中
- 可集成到 IDE 中协作
- 支持 Git 转换为 CRUD 接口
为了进一步实现万物即代码,它还具备这么一些特征:
- 可对需求进行重构
- 可转化为设计语言
或许,聪明的你已经知道了怎么做这样的系统了。
如何实现一个需求即代码和我比主
事实上,我们在五个引子中标明了我们所需要的要素:
- 设计需求代码化 DSL
- 过渡 API 设计
- REST 接口转换 SCM 接口(如 Git)
- 静态 API 生成(用于燃尽图等)
- IDE 集成看板
- DSL 可视化看板
- 删除原有的看板系统
稍有不同的是,我们要进一些额外的设计。
最小需求模型
在我们对需求进行建模的时候,我们需要考虑一个需求的最小要素,如下:
- ID
- 开始时间
- 结束时间
- 优先级
- 状态
- 作者
- 开发者
- 标题
【狗头】,这个是我在设计 phodal/design 时候设计的字段,顺便一提。
重新设计需求的组织形式
现有的看板系统都存在一个问题,只让业务人员写一个标准答案。而缺少中间的过程设计,因此如果想降低编写需求的成本,那么应该重新设计一下需求的组织形式。现有的需求的组织形式,有:『影响地图』和『用户旅程地图』。
其实我们要做的事情很简单,即我们只有最后能可视化出『用户旅程地图』即可,然后往 DSL 添加新的字段即可。
需求 DSL 的要素
如果现有的三段式 DSL 不满足需求,那么可以回过头来看看需求的要素是什么?
- 目标。系统的业务价值,基于价值确定功能和需求的优先级。
- 人员。使用系统的人员以及业务流程和目的。
- 系统。存在什么系统,用户界面是什么样,系统间如何交付,系统的性能怎么样?
- 数据。三者的关系,从最终用户角度看到的业务数据对象、数据的生命周期、报告中数据对决策的影响。
基于这四要素,我们可以重新设计我们的需求 DSL。
NLP 建模过程
在我们的系统进一步完善之后,我们要采用 NLP(自然语言处理)对需求进行分析,从中提取上述所涉及的四要素,进而将需求转换为代码。
- 提取名词
- 抽象行为
- 关注数据及状态
- 建模
- 实例化
- ……
考虑到写需求的业务人员并不会为难这个系统(譬如写一个多重否定),NLP 并不会太复杂的。
原型示例
接着,让我们来看我去年写的一个示例,基于 Cucumber + 其注释设计的:
# id: TUgT7FxZg
# startDate: 2019-11-22T01:56:41Z
# endDate: 2019-11-22T02:06:48Z
# priority:
# status: thinking
# author: phodal
# title: image to dsl
# language: zh-CN
@math
Feature:image to dsl
Scenario: 作为设计师,我想直接获得一份草图生成的 DSL
Given 设计
When 当我在设计的时候
Then 我能将草稿转成 DSL
Then 这样我能直接将草图转成 SVG
Then 开发人员可以直接修改代码
通过 CLI 就可以查看对应的情况,诸如于:
+-----------+--------------------------------+----------------------+--------+--------+
| ID | TITLE | DATE | STATUS | AUTHOR |
+-----------+--------------------------------+----------------------+--------+--------+
| CYJlzObWR | add docs to README | 2019-11-21T15:33:50Z | | |
+-----------+--------------------------------+----------------------+--------+--------+
| Dyp0iOxZg | use cucumber tag as file s | 2019-11-21T15:45:47Z | | |
| | group | | | |
+-----------+--------------------------------+----------------------+--------+--------+
并且它作为代码的一部分,贯穿在整个应用的生命周期中。
GitHub:https://github.com/phodal/story
需求代码化成熟度
为了方便大家后期完善这个系统,我决定写一个简单的成熟度模型。
0. 模板化需求
最简单的模式就是采用 Cucumber 的语法,它包含了现成的语法和 IDE 支持等。对于开发人员、测试人员、业务人员也比较熟悉。
1. 需求代码化
如上。
2. 需求像代码一样管理
- 设定需求门禁
- 不满足原则时(如 INVEST 原则),无法提交需求
3. 看板即代码
简单来说,就是:
- 支持 Git 的 CRUD
- 支持将现有的看板对接到 Git API
4. 需求关联设计
- NLP(自然语言处理),进行分词的状态转换设计。
- 需求建模语言。
- 需求的自动化测试
即能从需求中,识别中目标、系统、人员和数据等四个要素。
5. 需求转换代码
需求转换为设计代码 DSL,即我下一步要做的事情。
重构需求
Wow,现在我们已经成功地把文本代码化了,那么下一步就能重构这些代码(需求了)。
结论
参考书籍:
-《软件需求与可视化模型》