19

需求代码化

 3 years ago
source link: http://www.phodal.com/blog/requirement-as-code/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

需求代码化,即将软件开发需求抽象为特定的领域语言,并使用管理代码一样的方式来管理需求,追踪需求的变化 。同时,为通过新的 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 来管理文档。它有这么一些优点:

  1. 高透明性
  2. 高自治性
  3. 不可篡改性
  4. 高安全性

这可不是区块链技术,这是需求代码化技术,【狗头】。当我们的需求变成了代码,那么我们就有了一个去中心化的看板。

需求代码化

好了,现在我们有相同的上下文,让我们回到正题上:

需求代码化,即将软件开发需求抽象为特定的领域语言,并使用管理代码一样的方式来管理需求,追踪需求的变化 。同时,为通过新的 API 来对接版本管理系统,以可视化需求,演变为看板代码化。

它具备这么一些特征:

  1. 使用标记语言编写内容。如 Cucumber
  2. 可通过版本控制系统进行版本控制。如 git
  3. 与编程一致的编程体验,还可以作为测试代码的一部分
  4. 支持集成到现有的看板系统中
  5. 可集成到 IDE 中协作
  6. 支持 Git 转换为 CRUD 接口

为了进一步实现万物即代码,它还具备这么一些特征:

  1. 可对需求进行重构
  2. 可转化为设计语言

或许,聪明的你已经知道了怎么做这样的系统了。

如何实现一个需求即代码和我比主

事实上,我们在五个引子中标明了我们所需要的要素:

  1. 设计需求代码化 DSL
  2. 过渡 API 设计
  3. REST 接口转换 SCM 接口(如 Git)
  4. 静态 API 生成(用于燃尽图等)
  5. IDE 集成看板
  6. DSL 可视化看板
  7. 删除原有的看板系统

稍有不同的是,我们要进一些额外的设计。

最小需求模型

在我们对需求进行建模的时候,我们需要考虑一个需求的最小要素,如下:

  1. ID
  2. 开始时间
  3. 结束时间
  4. 优先级
  5. 状态
  6. 作者
  7. 开发者
  8. 标题

【狗头】,这个是我在设计 phodal/design 时候设计的字段,顺便一提。

重新设计需求的组织形式

现有的看板系统都存在一个问题,只让业务人员写一个标准答案。而缺少中间的过程设计,因此如果想降低编写需求的成本,那么应该重新设计一下需求的组织形式。现有的需求的组织形式,有:『影响地图』和『用户旅程地图』。

其实我们要做的事情很简单,即我们只有最后能可视化出『用户旅程地图』即可,然后往 DSL 添加新的字段即可。

需求 DSL 的要素

如果现有的三段式 DSL 不满足需求,那么可以回过头来看看需求的要素是什么?

  • 目标。系统的业务价值,基于价值确定功能和需求的优先级。
  • 人员。使用系统的人员以及业务流程和目的。
  • 系统。存在什么系统,用户界面是什么样,系统间如何交付,系统的性能怎么样?
  • 数据。三者的关系,从最终用户角度看到的业务数据对象、数据的生命周期、报告中数据对决策的影响。

基于这四要素,我们可以重新设计我们的需求 DSL。

NLP 建模过程

在我们的系统进一步完善之后,我们要采用 NLP(自然语言处理)对需求进行分析,从中提取上述所涉及的四要素,进而将需求转换为代码。

  1. 提取名词
  2. 抽象行为
  3. 关注数据及状态
  4. 建模
  5. 实例化
  6. ……

考虑到写需求的业务人员并不会为难这个系统(譬如写一个多重否定),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. 需求像代码一样管理

  1. 设定需求门禁
  2. 不满足原则时(如 INVEST 原则),无法提交需求

3. 看板即代码

简单来说,就是:

  1. 支持 Git 的 CRUD
  2. 支持将现有的看板对接到 Git API

4. 需求关联设计

  1. NLP(自然语言处理),进行分词的状态转换设计。
  2. 需求建模语言。
  3. 需求的自动化测试

即能从需求中,识别中目标、系统、人员和数据等四个要素。

5. 需求转换代码

需求转换为设计代码 DSL,即我下一步要做的事情。

重构需求

Wow,现在我们已经成功地把文本代码化了,那么下一步就能重构这些代码(需求了)。

结论

参考书籍:

-《软件需求与可视化模型》


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK