摘要:程序员常会说:我最讨厌别人写的代码没有文档,我也最讨厌自己需要写文档。

有一个很老的梗: 我最讨厌别人写的代码没有文档,我也最讨厌自己需要写文档。

有这种想法的程序员应该算是一个老鸟了,对于大多数程序员来说,对于他们来说: 文档是什么。

对于大规模,超大规模的项目,并且历时很长,需要大量人员协同开发的项目,没有文档简直不可想象。但是由于时间紧,任务重,大多数的项目中的开发者都没时间写文档,而且,文档也不计入考核指标,导致开发者也没有动机写文档。这就造成了很多项目都缺少规范化文档,项目的交接和接口的对齐都是靠口口相传,接口定义准确度低,并且项目的整体开发效率低下。

作为一个文档爱好者的笔者来说,平常很重要的一件事儿就是将自己的工作归纳总结并整理成文档。即便如此,笔者也面临着很多问题:

  • 需求很快就变了,光是改代码就已经耗尽了我的精力了,哪有时间同步文档。
  • 要么先改代码,要么先改文档,总之文档和代码之间存在一个不一致错位期。

除此之外,由于我们主要从事AI相关能力的研发,所以在开发过程中还存在以下特殊的问题:

  • 开发者不得不写大量重复的网络编程相关的业务代码,这些代码的质量通常不高,并且在后期的反复修改中变得越来越臃肿,从而难以维护。
  • 因为重复的业务代码开发工作占比过大,严重压缩智能化研发人员在AI方面的精力投入,这就导致了企业投入大量人力却无法得到好的效果。

经过不断的摸索和实践,AIMS项目组采取了一套文档驱动的开发模式,可以有效地解决上述在项目中广泛存在的问题。

1. AI接口开发的特点

不同于传统API的CRUD接口的开发,AI的开发模式通常包含了以下步骤:

  • 数据清洗;
  • 模型训练;
  • 参数调优;
  • API上线。

前三项都是我们组的强项,也是我们的工作重点。但是在实际工作中,却是API上线消耗了我们的大部分精力。AIMS项目组大都从事的是AI方向相关的工作,对于API的相关库flask、tornado也不是很熟悉,这就导致开发人员需要花大量时间去了解网络编程相关内容,开发出来的程序质量可能也不是很高。而且,在接口开发后,还需要准备一份Swagger UI给前端的开发人员,这又是一项繁重的工作。为了解决如上所述的痛点问题,AI接口开发就需要满足以下两个特点和需求:

  • API的核心函数是现成的;
  • 需要将API开发工作量降到最低。

2. 文档驱动的开发模式

我们发现API的接口文档中已经包含了实现API接口的所有信息。也就是说,API接口文档的信息熵和API接口代码的信息熵是一样的。因此,我们只需要完成代码或者文档中的一项即可,另外一项可以交给框架自动生成,这就避免了把同样一件事情重复做两遍的问题。考虑到文档不论从可读性、易写性还是可维护性都胜过代码,我们决定写文档,然后根据文档生成对应的代码。

我们参考了OpenAPI Specification3.0.1标准,以及JSON Schema定义了一套API描述语言,开发者基于这个API描述语言撰写API文档。当完成文档时,API的开发工作也随之完成,大大节省了API接口的开发工作量。经过初步估计,使用文档驱动模式开发一个API接口,通常可以减少40%–70%的工作量。

3. AIMS框架介绍

为了实现文档驱动的开发模式,AIMS基于tornado实现了一套Web后端框架,如下图所示。

3.1. Application Router组件

每一个API都会有一个路径,即一个正则表达式[1]。一个微服务中的多个API的所有路径会组成一个API路径列表。

当Application Router接收到请求时,会根据请求中的URI在路由表中查找。如果匹配到某一个Request Handler,路由模块会将请求转发给响应的Request Handler。如果所有的路径都不匹配,则返回404结果[2]。

3.2. Request Handler组件

Request Handler处理来自Application Router的响应,是AIMS架构的核心,而Document则是Request Handler的核心。在AIMS架构中,Document是指函数的文档,即__doc__。Request Handler是在服务的启动阶段动态生成的。

事实上,在AIMS架构图中,只有Document是开发者必须写的[3]。其它的组件都是由AIMS提供的,或者是由Document自动生成的,所以AIMS开发模式也被称为文档驱动型开发模式。开发者只需要维护Document即可,从而实现减少开发者工作量的目的。

3.3. Watchman组件

Watchman组件可以通过设置来订阅某些接口的异常,当被订阅接口出现任何异常时,Exception Handler便会触发Watchman组件。

因为Recorder组件记录了Arguments,Watchman甚至可以自动产生一个可以复现该问题的测试用例,方便开发人员定位问题。

3.4. Recorder组件

Recorder是一个采集器,可以采集每一次请求的所有细节信息,包括请求ID、请求参数、远程IP、被调用的接口、响应时间、工作目录和进程号等各种信息。这些数据具有以下两个作用:

  • 系统的维护者可以利用Recorder中的数据快速定位,复现现网问题,可以看做是一个更强大的日志系统。
  • 通过请求ID,训练数据收集系统可以将请求参数、响应数据与用户反馈数据关联起来,这就相当于是一条有标记的数据。

3.5. Logger组件

Logger是AIMS封装的日志模块,用法和python自带的logging.Logger使用方式一致,最大限度地降低开发者的学习成本。

4. 补充说明

我们注意到,在AIMS架构图中,Argument Parser、Schema Checker、Swagger UI和OpenAPI Specification是同源的,即都是来自Document。这就不会出现文档(Swagger UI、OpenAPI Specification)与函数实现(Argument Parser、Schema Checker)不一致的情况。开发者也不需要同时维护Argument Parser、Schema Checker、Swagger UI和OpenAPI Specification相关代码。

以上就是文档驱动开发在AIMS框架中的优势,既降低了开发者的工作量,又解决了一致性的问题。事实证明,自动产生的组件质量也是优于开发者自行开发的代码,并且不易出错,从而提升整体服务的质量以及稳定性。

[1] 在AIMS开发中,这个字段是写在__doc__中的api_path字段中。
[2] 事实上,路由模块会将请求转发给NotFoundRequestHandler,然后由NotFoundRequestHandler进行响应。
[3] 在AI相关微服务开发过程中,Function,也就是核心功能函数,是已经准备好的。

本文分享自华为云社区《文档驱动开发模式在 AIMS 中的应用与实践》,原文作者:zqmillet 。

点击关注,第一时间了解华为云新鲜技术~

文档驱动开发模式在 AIMS 中的应用与实践的更多相关文章

  1. 文档-linux io模式及select,poll,epoll

    文档-Linux IO模式详解 1. 概念说明 在进行解释之前,首先要说明几个概念:- 用户空间和内核空间- 进程切换- 进程的阻塞- 文件描述符- 缓存 I/O 1.1 用户空间与内核空间 现在操作 ...

  2. dzzoffice教程、文档、开发手册等内容地址

    dzzoffice教程.文档.开发手册等内容全部都存放在DzzOffice开发者社区的文集中.搜索引擎收录不到DzzOffice中的应用内容,这里将文集地址提供在这里. 地址:http://dev.d ...

  3. 读取XML文档存入泛型List<T>集合中

    前一篇博文是<泛型List<T>转存为XML文档> http://www.cnblogs.com/insus/p/3277410.html 把一个List<T>集合 ...

  4. 测试计划驱动开发模式 TPDD:一种比 TDD 更友好的开发模式

    相信大部分开发团队都在使用TDD,并且还有很多开发团队都 对外声明 在使用 TDD 开发模式. 之所以说是“对外声明”,是因为很多开发团队虽然号称使用的是 TDD 开发模式,实际开发过程中却无法满足 ...

  5. Expo大作战(六)--expo开发模式,expo中exp命令行工具,expo中如何查看日志log,expo中的调试方式

    简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,将全部来与官网 我猜去全部机翻+个人 ...

  6. 如何真正实现由文档驱动的API设计?

    前言 本文主要介绍了一种新的开发思路:通过反转开发顺序,直接从API文档中阅读代码.作者认为通过这种开发方式,你可以更清楚地知道文档表达出什么以及它应该如何实现. 如果单从API文档出发,由于信息量不 ...

  7. (转)如何真正实现由文档驱动的API设计?

    前言 本文主要介绍了一种新的开发思路:通过反转开发顺序,直接从API文档中阅读代码.作者认为通过这种开发方式,你可以更清楚地知道文档表达出什么以及它应该如何实现. 如果单从API文档出发,由于信息量不 ...

  8. 企业应用开发模式 ERP项目中应用到的技术和工具

    一.基础技术选型 C# .NET 3.5/4.0  这两个版本的.NET已经相当方便(Linq, Lambda,Parallel),语法简洁,配合WCF和WF两项技术,可以满足快速开发,维护方便的目标 ...

  9. 使用freemarker模板引擎生成word文档的开发步骤

    1.准备模板文档,如果word文档中有表格,只保留表头和第一行数据:2.定义变量,将word文档中的变量用${var_name}替换:3.生成xml文件,将替换变量符后的word文档另存为xml文件: ...

随机推荐

  1. PyQt(Python+Qt)学习随笔:QListWidget获取指定项对应行的row方法

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 QListWidget的row方法通过项作为参数,获取到对应项所在行的行号,语法如下: int ro ...

  2. 第一章、PyQt的简介、安装与配置

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 第一章.PyQt的简介.安装与配置 一.引言 当朋友向我推荐PyQt时,老猿才知道有这样一个在Pyt ...

  3. 自动化运维工具之Puppet master/agent模型、站点清单和puppet多环境设定

    前文我们了解了puppe中模块的使用,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/14086315.html:今天我来了解下puppet的master/age ...

  4. IKUN python 反序列化

    题目过程1.一开始提示说要买到V6,观察源码,发现/static/img/lv/lv4.png.注册之后尝试寻找V6.观察url发现/shop?page=2.尝试写脚本匹配一下.发现在第181页. i ...

  5. Thinkphp V5.X 远程代码执行漏洞 - POC(搬运)

    文章来源:lsh4ck's Blog 原文链接: https://www.77169.com/html/237165.html Thinkphp 5.0.22   http://192.168.1.1 ...

  6. Python 常用方法和模块的使用(time & datetime & os &random &sys &shutil)-(六)

    1 比较常用的一些方法 1.eval()方法:执行字符串表达式,并返回到字符串. 2.序列化:变量从内存中变成可存储或传输到文件或变量的过程,可以保存当时对象的状态,实现其生命周期的延长,并且需要时可 ...

  7. Mysql 逻辑架构图及日志系统

    我们经常能看到如下的逻辑架构图,但是往往不能进行很好的记忆,看过就忘记了,也不知道它的实现方式.今天通过简单的画图来简单了解一下mysql到底是如何执行一个select语句,如何update一条语句. ...

  8. VirtualBox安装Centos出现E_FAIL (0x80004005)的解决方法

    问题描述:UUID已经存在 Cannot register the hard disk 'F:\hadoop\VirtualBox-centos\centos6.4\centos6.4.vdi' {0 ...

  9. web移动端css reset

    通用版css reset,pc端使用只需要修改html{font-size: 10px;}为html{font-size: 12px;} @charset "utf-8"; htm ...

  10. 串口数据监视 Serial Port Monitor

    串口数据监视工具 Serial Port Monitor可以在其它应用读写串口时监视串口数据, 很好用,但只有15天试用期.