最近一直在和团队在做一款服务于软件研发的工具,得以有计划从理论上和实操上重新思考软件研发这件事。接下来想从软件研发本来的样子,怎样更好的开发一款软件两方面谈谈。
软件研发工作本来的样子
一个完整的软件研发流程大致包括市场调查、用户分析、产品定义、交互设计、UI设计、软件开发、测试这几个阶段。一个完整的软件开发团队通常包括项目经理、产品经理、交互设计师、UI设计师、前后端工程师、测试人员这些角色。产品经理会负责市场调查、用户分析、产品定义,交互设计师和UI设计师分别负责交互设计和UI设计,工程师负责软件开发,测试人员负责软件的测试,而项目经理则对项目的质量、成本、工期负责。当然有些成员会身兼数职,比如在敏捷研发中,产品经理通常也扮演了项目经理的角色,而交互设计的工作一般都由产品经理和UI设计师分摊。
在我看来,整个软件开发流程就像沙漏里的沙一样,先汇聚一点,再发散出去,最后落地。为什么这么说呢?首先说明汇聚的那一点代表什么,是产品需求文档。这文档算是软件开发流程中的集大成者。产品需求文档把软件开发流程切割成前后两个部分,前一部分的核心内容是研究怎么做,后一部分的核心内容就是做出来。具体来说,就是产品经理、交互设计师和UI设计师通过市场调查,用户研究,界面设计等工作,研究软件到底怎么做,输出调研报告、原型、设计图等各种文档成果,然后他们把成果汇集整理成一份产品需求文档;之后工程师和测试人员的工作就是根据产品需求文档的指导精神,输出代码、用例、缺陷等,就是在把软件给做出来。要指出的是产品需求文档只是一个信息传达介质,形式是很丰富的。
除了漏斗的形式,软件开发还有不少其他特点。首先是研发流程各阶段的关系特点。虽然流程前后各阶段有强烈的依赖关系,但后一阶段不必等到前一阶段完全完成才开始,经常在前一阶段进行到一个特定时点时就可以开始了。比如测试不能在还没有代码的时候就测试,但可以早早就开始书写用例,一旦有了可测的模块便可以进入测试;UI设计不能在还没有产品原型图的时候就开始设计,但可以在核心页面原型出了后就开始确定风格;诸如此类。
其次,软件开发项目中,对工期的预测和把控是非常困难的工作。这主要由于两个原因造成。一方面是产品经理在产品定义过程中,基本不可能考虑到所有细节,有些因为疏忽大意而漏掉,有些因为认知不到而忽略,这部分内容如果在开发过程中产生比较大的问题,可能就会影响工期。另外就是产品经理、项目管理人员不一定懂技术,和盖房子不一样,代码不像砖头那样直观可见,这样的情况下,开发工作不管顺利与否,都要等到有了成型可见的界面后,才能得到最有效反馈,这种反馈的滞后很容易导致巨大的返工成本。基于同样的原因,项目管理人员在计划工期的时候也常陷入手足无措的境地。
另外,软件研发的成员,很多时候都是多窗口并行工作,输入和输出交错进行。为了能输出正确的东西,需要输入各种不同类型的信息。举个例子,一名工程师,开发时可能要同时打开编辑器、终端进行代码编写,同时也要打开产品需求文档查看产品开发需求,打开文件管理器调用素材,以及不知道多少个浏览器标签页来解决编码中所遇到的问题,此外,还有一个或多个随身预览结果的窗口,可能是浏览器或模拟器。这就是为什么程序员通常都需要两台屏幕,只有这样才能应付这种错综复杂的工作。在这样的情况下,如果不能合理安排窗口,总是来回切换的话,工作效率很低,而且很容易烦躁。
追求更好的软件研发是在追求什么
软件研发的目的很明确,就是开发出质量上层、解决问题的软件来。和任何项目都一样,软件开发也遵从项目三角形的表述,技术、人员等客观条件一定,项目的质量受成本、范围、和时间限制。要开发更多的功能,必然影响到开发周期和开发成本;要降低开发成本,必然影响到开发周期和开发范围;要缩短开发时间也一样。要开发出高质量的软件,必须保证这个三角形的闭合。一个有经验的项目经理,面对项目三角形的时候,通常固定一边,调整一边,投资一边。但我们说这不是更好的软件研发,更好的软件研发不是去调整平衡三条边,而是让三角形整体变大,即相同的任务,现在花更少的时间和成本。而这里面又分为三块,完成常规任务的效率更高,面对高难度任务也能顺利完成,尽量少的犯错误。
如何更高效的完成常规任务,在软件研发中,工作时间是可以分为两部分的,一部分用来独自工作,另一部分用来沟通。要想提高独自工作的效率,就两点,自动化可自动化的流程,复用可复用的组建。复用可复用的组建就要求每个成员在工作中注意积累和总结,因为现在很多项目都不是一锤子买卖,而是小步快跑的方式,所以这样的积累是很有价值,而且价值越来越大的。自动化可自动化的流程,就要求团队善于运用工具,有了工具,切图标志、数据分析、代码编译、版本部署等工作都可以节约特别多时间。
提升沟通效率稍微复杂一点,这要求团队建立顺畅的信息传输和反馈渠道和机制,来保证团队信息同步,需求传达准确,反馈即时有效。在我心中,最理想的软件研发是由一个人完成的:你获得了一个点子,通过问卷、访谈等方法确定了这个点子可行;接着你把看得见的和看不见的问题都想的清楚通彻了,并根据自己理解定义出了软件,还画出了产品设计图;然后你又自己把软件开发了出来,自己测试了一下,觉得没问题就上线发布了。在这个过程中,你对该产品的思考和认知一脉相承,不需要和任何人去面对面沟通、不需要花时间制作任何文档,也不需要考虑标注切图的问题,因为这一切都是你的,不做这些也不会影响你下一步的进行。然而这样的通才并不常见,况且实在赶时间的话,就算一个人什么都会,也做不过来。所以我们还得有个团队。从这个方面来想,一个人工作不涉及到的任务分配、谈话、邮件、会议、各式文档等都是因沟通而存在的。
能提高沟通效率的方式很多,仁者见仁智者见智,但这里我想给你介绍几点工作中觉得特别重要又容易忽视的几点。首先,要明确计划,虽然软件开发中可能遇到各种突发情况,甚至战略方向都会改变,但制定计划依然是必要的,有一份详尽的计划,能按照计划实行当然最好,不能按照计划实行,也能让团队成员对我们在做什么、要去哪、为什么变化了有个谱,可以更容易理解最新的信息,更准确解读接收的需求。其次,要根据成员的特点优化关键文档的展现形式,拿产品需求文档举例,产品经理可以采取各种不同的工具和叙述方式来制作产品需求文档,说不上孰好孰坏,根据团队成员的工作习惯和工作场景,选择让工作更舒服的方式最好。再次,让变更有迹可循,任何文档,当变更了,都需要记下何时何地何人做了何等变更,为什么;人和新需求,要记录何时何地何人提出了这等需求,为什么;任何回忆,也要记录何时何地何人讨论的问题和达成的成果。只有这样,思路才能是完整的,在之后做类似决策时才是有据可考的。最后,要即时反馈即时纠错,现在的软件开发已经在往这个方向发展了,所说的敏捷开发就有此意,但有时候依然不够,如果可能的话,尝试周稳定版本甚至日稳定版本都是有帮助的,毕竟问题总是越早发现,纠错成本越小。
如何顺利完成高难度任务,也是个见仁见智的问题。这里就简单的介绍一下我觉得靠谱的方法。一是工作的形式上,在面对困难任务时,可以改变各顾各的形式,采用结对编程,即两个人用一台电脑编程,在思考和交流中,更容易碰撞出灵感;如果两个人都不行,那可以采用特种部队的方法,这个特种部队可以由不同类型的成员组成,从不同的思路去思考同一个问题,这样的小组专门在特定的时间负责攻克特定的任务,完成任务就可以就地解散。另一种是建立团队资源库,各种各样的问题,在哪里、找谁有可能得到答案,都可以收集起来,这样遇到问题时不至于手足无措。
怎样避免少犯错误呢?错误可分为看得见的错误和看不见的错误。看得见的错误当然有些因为马虎,有些因为确实难解决,前一种坑可以通过评审尽量避免、后一种坑则和前面说的攻克高难度任务差不多。看不见的错误主要因为经验不足,而经验不足就要努力积累经验。可以建立一个公共的的知识库,积累一整套认知论和方法论,然后再通过不断的的总结和复盘去迭代。更重要的是,这个知识库要使用优质的文档管理软件来建立,至少是方便搜索查找的,如果经验积累了却无法提取,也是徒劳。此外,即时收集反馈和纠错也很重要,不仅减少错误,也减少已犯的错误造成的损失。
结语
以上谈了对软件开发的一些理解,随着互联网的发展,这个行业已经发展得挺健全了,我所说的这些认识和方法也不是我这一家的洞察和思考,说到底,能不能开发出更高质量的软件,还得看能不能结合团队特征调节流程、找好工具、认真实行,毕竟一个几十人的团队就已经算得上一个复杂系统,和复杂系统打交道从来就不容易。