那些容易遗忘的非功能性需求

非功能性需求不会给项目带来收益,然而非功能性需求不仅要在需求阶段考虑好,而且在设计与开发过程中也要多加留意,否则都会成为项目的坑……

本文以一个政府的Web应用项目为例,讨论一些容易遗忘的非功能性需求。

易用性

用户界面应当设计友好,操作简洁,而且讲好现代标准汉语。

近些年来,各级政府正在大力推行政务改革,实现“一网通办”,达到“一网受理、只跑一次、一次办成”的目标。我们对用户办件条件进行校验时也要尽量做到“只跑一次”:例如用户不满足3个办件条件,我们尽量一次性把这3个条件都提示给用户,而不是挤牙膏式一项一项提醒,让用户录入三四遍才能成功申报。

团队开发时,每个人负责的功能都应当保持“画风一致”。要是A业务界面风格与操作方式像《喜羊羊与灰太狼》,而B业务的界面风格与操作方式像《熊出没》,这样太“沙雕”了。

可靠性

输入数据要进行有效性检查,并给出准确友好的错误提示。虽然这样说,有些问题还是容易忽略掉,例如:

  • 过度检查:
    • 姓名:有些民族(例如维吾尔族、藏族)的人名中没有姓氏,系统不能强制要求这些人录入姓氏。顺带一提,维吾尔姓名“尼格买提·热合曼”中的“尼格买提”是本人名字,而“热合曼”是他父亲的名字,不是姓氏。
    • 手机号:“虚拟运营商”开始运营之后,中国已有170开头的手机号。2017年底,中国电信又推出了199开头的手机号……
  • 最大长度不够长:
    • 姓名:阿不都热依木·伊盖木拜尔迪
    • 地址:新疆维吾尔自治区伊犁哈萨克自治州塔城地区和布克赛尔蒙古自治县教育学院买依墩卡萨克能科特奈分校(虽然这只是个网上流传的段子)
    • 考虑长度时,不光要考虑字数,还要考虑字节数。例如Oracle里面一个汉字占3字节,设计表结构时要留得足够长。
  • 串号:登录A用户,办完业务之后注销,再以B用户身份登录,结果用户因浏览器窗口没关干净就操作而串号。

为避免误操作造成损失,系统应当对有影响的操作进行一定的控制,例如:

  • 点击申报、删除等按钮时,弹出确认提示框,避免意外提交、丢失数据。
  • 点击查询、保存等按钮之后,立刻让按钮变灰,避免让用户再次点击,否则网速不好的时候用户容易多次操作,导致系统负载增加、产生重复数据等。

需要考虑系统整体的可靠性,以及故障恢复的能力。以缴费为例,假如用户网络出现故障,或者服务器系统故障,而用户实际上未完成缴费,系统需要能够回滚支付状态,不能给工作单标记成“已缴费”,更不能让银行扣用户的钱。

安全性

关于安全,国家有一个专门的安全等保制度要求(可搜索“等保2.0”了解详细情况)。本文只讨论一些容易遗忘的需求。

如果你在做需求,复制粘贴现成模板时,需要留意安全需求部分:2019年12月1日等保2.0正式实施,其范围和细则均发生了较大变化,做需求时要注意按照GB/T 22239-2019 信息安全技术 网络安全等级保护基本要求GB/T 25070-2019 信息安全技术 网络安全等级保护安全设计技术要求等标准规范来调整完善。

抵御常见攻击

系统需要能够抵挡常见的攻击,例如XSS、SQL注入、CSRF、暴力破解口令等。

权限控制

考虑功能需求时,很容易就想到要判断哪些角色能够办理哪些业务。然而以下情况就容易忽略了:

  • 如果用户没有业务办理权限,却知道相应系统功能的URL,那么系统需要防止用户直接在浏览器录入URL来进行操作。
  • 系统需要防止对其他账号(不应该接触到的)信息进行查询和操作,增加业务数据与用户身份关系的校验。举个例子,开发期间大家都用广东的账号来操作,那么你需要确认广西的账号里不会出现这些不该碰到的信息。
    • 接上一条,在URL和<form>层面也要加以防范,否则用户只要修改网址上面的id与页面里的隐藏域就能操作别人的信息了。

审计

系统登录注销、业务办理等操作要有跟踪记录,例如什么人、什么时间、用什么IP(注意预留IPv6支持)做了什么操作,以便在出事之后追查责任人。与第三方公司对接时更要做好日志记录,否则出问题时大家就要互相踢皮球了。

系统需要能够防范一些恶意操作,如猜测密码、频繁查询、构造恶意查询条件(分页每页显示10000条记录)等,例如通过按钮变灰、输入验证码等形式防止用户频繁操作,并自动封禁恶意操作的IP来防止暴力破解。

除应用层面,在数据库层面也要考虑审计记录,例如建立跟踪表,记录数据变化情况。

处理敏感信息

证件号码、手机号等敏感信息应考虑加密,例如“130****5678”,更要防止被人导出。

允许用户生产内容的地方(例如意见反馈)需考虑敏感词过滤和人工审核。假如用户利用你的系统发表了《关于要求xxx同志辞去党和国家领导职务的公开信》,而且还登上了你的系统首页,你就等着被有关部门处理吧。当然,政府项目还好,自己做产品的时候要更加注意。

传输安全

除了输入输出,数据传输过程也要考虑安全,例如HTTP协议是明文传输,无论是GET还是POST请求,用户与服务器之间交互的数据都能被监听和篡改,而HTTPS协议解决了此问题。建议只要有条件就使用HTTPS。

另外还需要注意两点,一是Base64仅仅为一种编码方式,不能当作加密使用,二是MD5安全性不高,其散列码可以用彩虹表或暴力的方式破解。

性能

设计系统时,需考虑性能指标,例如响应时间、并发用户数、资源利用率等,另外也要考虑未来上线之后的业务规模与增长情况,性能和容量(包括网络带宽)都要足够才行。

计算性能需求时,需要留意的是“并发数”和“在线数”的区别。最大在线2000人并不等于最大并发2000,在功能上面的操作时间会“冲淡”并发数。一般场景主要是“最大在线数”,而抢票那种特殊场景要更加注重“最大并发数”。

设计系统架构时,需要考虑是否采用集群部署、负载均衡,考虑采用传统的单应用还是微服务架构,而且上线之前就要想好业务量增长以后该怎么办,不要等系统真的扛不住之后才想起来调整架构。

未来用户数大幅增长,或者会产生高并发时,则要考虑负载均衡、读写分离、分表、分库等机制。这里面每一项都是大坑,早准备少吃亏。

兼容性

以浏览器为例。目前的开发框架基本上都能兼容主流浏览器,然而我们需要额外考虑

  • 老版本IE:有些政府部门的电脑仍然是XP系统、IE6/7/8,我们需要考虑是否兼容这些电脑。
  • 新版本IE:同上。
  • 移动设备:确认是否需要兼容移动设备,例如Android、iOS等。
  • “国产化”:国家已命令各政府部门和公共机构三年内实现国产化替代。对于开发人员来说,这项要求实质上就是“页面能够在龙芯处理器电脑、老版本Linux系统的个位数版本Firefox上正确展示和操作”(没错,我们说的就是中标麒麟。如果连中标麒麟都能正常使用,那么能冲进DistroWatch前十名的深度操作系统就更没问题了)。

兼容性问题必须一开始就考虑好。一旦开始开发,后面就很难再做调整了。

另一个例子是字符编码。字符编码一定要用UTF-8,不要用别的,否则一个名字带生僻字、拒绝去派出所改名(因为改名牵涉人事、财务等诸多问题,很麻烦)而且还经常办业务的人可以让政府部门用户与系统开发人员集体崩溃。

扩展性

系统的硬件资源、软件资源、软件功能等应便于进行扩展调整。

需求不是一成不变的,甲方日后可能会提出需求变更,甚至自己打自己脸,推翻以前提出的需求。设计和开发时要提前考虑提高代码可复用性,降低需求变更成本:能参数化的地方增加参数化配置,能形成组件的东西做成组件,能避免copy-paste的地方就避免copy-paste(封装成公共类或公共函数),这样后面真发生需求变更时你能相对舒服一些。

开发业务系统时,还需考虑到“一网通办”的时代背景,留意未来有可能会与其他政府部门的系统进行对接。想象一下,假如你的业务逻辑代码是通过copy-paste写到不同平台的,而且Controller也夹杂着业务逻辑,没有使用服务,也没有形成公共方法或组件,那么一旦甲方提出需求变更,你就需要挨个检查PC端、移动端、自助服务终端、上海市政府一网通办接口、国家政务服务平台接口的代码然后再考虑如何修改……

容易忽略的真·功能性需求

有一些功能需求,即使用户没提,我们也有必要加以考虑。

查询统计

领导们都喜欢“讲大局”,这样就会产生定期或不定期的统计需求,例如用户注册量、平均访问量、高峰时期访问量、业务办理量、退单率等。实现业务功能时要记得顺便做好信息记录与数据采集,不要等到领导提统计需求时才发现系统连原始数据记录都没有。

待办查询和提醒

很多用户工作繁忙,无法兼顾系统所有业务,而且也有个别用户神经大条,经常健忘。建议为这类用户开发一个“待办事项查询”功能,一个页面展示所有未完成的工作,并且对未及时处理的业务作出提醒,以免遗忘。

系统公告

遇到紧急情况,可通过系统功能向用户发出公告,否则找页面文件、增加alert代码、申请修改生产系统等一系列步骤容易耽误事。