6.1软件的质量到底是什么

质量是个抽象概念,软件质量也是,因为软件本身就是一个比较抽象的概念,何况是两者的叠加。当软件质量控制比较好的时候,我们很难察觉到它的存在。比如每天正常使用的办公自动化(OA)系统、钉钉、公司微信、淘宝、美团等,感觉不到软件质量的存在。而当软件质量控制不好时,频繁出现缺陷(BUG)时,你就会特别敏感并感到心情不好。想象一下,当你卡着上班点准备打卡时,发现定位不准确;当你中午等外卖的时候,订单位置出了问题;当你使用OA时,工作审批流程出错了。如果你不幸在同一天遇到所有事情,估计离崩溃不远了。

软件质量就存在于每一次需求讨论中、每一念设计斟酌里、每一行代码的敲击时,每一次的测试中……软件质量除了是一个抽象概念,也是一个相对概念,质量好和质量坏没有绝对值,只有相对性。

好比安全感,大家都知道在家中要比在马路上安全,但这是一般情况下,发生某些低概率或者特定事件的时候,比如地震,空旷的马路就比楼房安全。软件质量同样如此,质量的好与坏要看使用的场景、特定的行业和针对的用户群体。也就是说,是否满足这部分特定的用户对软件的需求。

6.1.1 软件质量包含的层面

以上软件质量的两个特性:抽象和相对性,以及我们举的两个例子,我们就可以得出软件的质量包含三个层面。

1. 满足软件质量规定

也就是说,软件必须满足从软件内部结构衡量软件质量的一系列标准、规范和公认应该具备的特性。

我们国内的标准《GB/T16260.1》中,将影响软件质量的主要因素划分为六个特性:功能性、可靠性、易用性、效率、维护性与可移植性。其中,功能性包括适合性、准确性、互用性、依从性、安全性;可靠性包括容错性、易恢复性、成熟性;易用性包括易学性、易理解性、易操作性;效率包括资源特性和时间特性;维护性包括可测试性、可修改性、稳定性和易分析性;可移植性包括适应性、易安装性、一致性和可替换性的六个特征及若干子特征。也就是说,软件质量在第一个层面,就必须符合以上标准、规范和特性,也就是软件质量模型。

2. 满足用户需求

软件产品的需求是来自用户的,软件的最终目的就是满足用户需求,解决用户的实际问题。这个层面就更好理解了,软件开发出来就是为了交付给用户使用的,如果满足不了用户的需求,这个软件产品存在就没有意义。也就是说,软件产品及其功能一定是为了满足部分用户的需求开发出来的,所以是否契合用户的需求也是衡量软件质量好坏的重要标准之一。

很多人认为,既满足了软件质量的标准和模型,又满足了用户的需求,开发出来的软件质量一定非常好。在我看来,满足了前面两个层面开发出来的软件,质量只能说是及格,不至于太好,但肯定不算差。

3. 满足用户的期望(隐藏需求)

如果能够做到这点,通常会极大地提升用户满意度,也就意味着软件质量极大地提高。

举个例子,最早外卖软件下了订单后的状态只有文字信息,比如已下单、待制作、配送中等,但是这是用户想看到的吗?显然不是,用户不仅要看到订单状态的变化,更加希望全程看到自己订单的配送过程。那么,当某个外卖软件上线了基于LBS的配送地图功能后,用户反馈非常好,都觉得这个款外卖软件非常棒。

之前,我们为某个公司开发了一套OA系统,申请某个业务的时候需要填写一个表单,客户就提出来希望把这些数据加密起来。开发人员就开始讨论,用什么加密技术、中间的密钥如何设计、怎么解密,因为业务流程复杂,导致频繁地加解密,不仅严重消耗了资源,每次涉及数据的增删改查时速度特别慢,经常无响应,让用户感觉我们的软件质量特别差。

确实,我们从功能层面上满足了用户的需求:数据的保密。但是仔细想一想,这真的是客户需要的吗?其实,他们只是需要一个权限功能而已,不同的人只需要看到不同的信息而已。而储存在数据库中的数据,因为并不是人人都要查看的,可以从行政上解决这个问题,完全没有必要投入大量的时间和人力做去了一套莫名其妙的数据加密系统。所以,满足用户的隐藏需求,达成用户的期望是提升软件质量不可或缺的一环。

6.1.2 从关注结果到关注过程

很多时候,IT项目经理负责开发一款软件只关注最后的结果,交付的软件是否能够通过质量审查,会不会影响项目验收。但结果并不尽如人意,至少我经历过的几百个大大小小的项目大概率是这样的:只关注结果的时候,结果往往不太好。

为什么会这样?我曾经仔细思考过这个问题,最终找到了答案,那就是我们不仅要关注结果,还要关注过程,因为在这种环境下,好的过程必然产出好的结果。

项目经理应该对五大过程组及其对应的49个过程非常熟悉。可以说,通过学习PMP的知识体系,我们知道如何通过启动过程组、规划过程组、执行过程组、监控过程组、收尾过程组五个过程组去管理并完成一个项目。

PMP也是国际上和国内公认的“适用于绝大多数项目场景的良好实践”,可以说,能够非常好地指导一名项目经理如何交付好项目,而最重要的就是通过一个个过程,保证项目的最终目标能够达成。

项目质量管理也一样,过程非常重要。因为除了项目管理本身就是一系列的过程组成的,软件的开发直到交付本身就是一个过程。从最开始的一个想法,抑或一个业务痛点开始到最后一个成型的软件产品,中间会经历很多活动,包括但不限于以下活动。

图6-1 软件开发生命周期

我们可以看到,软件交付实质上是一个复杂的团体工程活动,包含多个交付活动,活动之间存在极强的关联性,上游不合格的工件很可能成了下游工序的阻碍,也有可能某个工件流经了好几个环节之后才得以发现有缺陷,以至于返工。同样涉及多个角色,角色之间需要沟通,角色之间又由于成长环境、教育背景、工作经历、思考习惯等的差异导致认知上的差异。

对应软件开发生命周期,我们可以看到如下软件质量形成过程。质量在开发的各个环节一步一步建立起来,每个环节都是有可能直接或间接地贡献缺陷。根据业务痛点或诉求、精准的产品定位、正确的需求分析、完备无误的需求实现、全面细致的需求测试等活动,才能构建出一个高质量的产品特性。

在交付中,由于人的认知偏差免不了导致主观或客观的失误,例如具备业务可行性但不具备技术可行性的需求,半年前设计的不具备可扩展性的架构导致性能问题,由于单元测试缺失或不足导致在新特性开发过程中造成的对原有特性的破坏。按照来源分类,缺陷通常会有:需求问题导致的缺陷、架构问题导致的缺陷、设计问题导致的缺陷、编码问题导致的缺陷、测试问题导致的缺陷、发布问题导致的缺陷、集成问题导致的缺陷。不管何种开发模式,我们都必须认清一点,那就是软件交付的任何一个环节都是有可能引入产品缺陷的。

从项目质量管理的视角,从不仅仅关注结果到还需要关注过程的时候,我们就会发现,质量保证需要在软件交付的每一个环节中做到,也就是质量内建。

6.1.3 “技术债”对项目的影响

在关键开发中,我们要面对的就是一个最头疼的问题——技术债。

可能有人有疑问,技术还有债?比如,我们在软件开发中经常采用一些并不合适的架构设计;编码的过程中不够规范、不写注释;经常写一些硬代码,绕过难题采用一些变通方法(workaroud)、缺陷(hard code);测试中覆盖率不够,过于依靠手工测试,缺乏集成和版本管理;缺乏相应经验却硬着头皮开发......这些就是技术债。

也许你也曾是增加技术债中的一员,也许你还没有认识到这是一种债务。但是你听说过“祖传代码”“屎山”这类戏称吧,这就是技术债增加到无法偿还的地步后的一种必然后果,就像经济债务,爆了以后就翻不了身了。软件开发也一样,没人愿意去清理这堆“垃圾”。

技术债的爆发不可预期也不可预测,因为技术债的一个重要特性就是它的增长方式是非线性的。可能在原来的债务上再加上一丁点技术债,就有可能超过那个“临界点”,债务就爆发了,项目也就变得不可管理,整个团队鸡飞狗跳。这种不可预测的非线性债务对项目来说就是一个非常大的风险点,因为我们不知道最后一根稻草什么时候会压垮骆驼,一旦发生,后果不堪设想。

同样,这些债务还会带来大量的BUG,这些BUG盘根错节、互相影响,而我们为开发后面的新功能不得不修复之前的BUG,而修复这些BUG就会占用大量的人力和时间,从而严重影响开发计划,降低开发速度,导致效率急剧下降,直至进入“死亡行军”,陷入两难的境地。

我们不得不修复的BUG会让开发成本和时间急剧上升。然而,我们在项目中通常面对的是固定时间和成本,这就会影响项目的范围。也就是说,当我们无法避免项目成本和时间的急速增长时,很多项目经理就会在项目范围上动脑筋。如减少需求,因为有些功能也可以不做,把有些代码“写死”(指硬代码,意思是本来应放参数,按照传进来的参数计算,但是实际写成如1、2、3的具体数字,所以我们一般口语叫做写死),反过来又会增加技术债,还会影响项目最终交付的功能减少,引起包含甲方在内的各个相关方的不满,甚至还会引起争议,简直就是一场灾难。

随之而来的,就是项目越做越差,因为项目已经陷入“失控”的状态,这时候无法以任何形式进行预测。人们对于结果无法预期,越来越焦虑,团队氛围也越来越紧张,导致团队成员的表现也越来越差。这时候,项目经理已经很难再管理团队了,挫折感四处弥漫,很多人会思考如何离开这个团队。而项目的负责人,只能日复一日、周而复始地硬着头皮应付,精疲力尽,直到耗尽所有人的信任,成为最后的“背锅侠”。