1. 开始的开始

了解开发背景和需求后,先别动手,思考几个问题:

  1. 用户是谁?
  2. 用户在什么场景下,有哪些急需解决的问题?
  3. 软件能把问题解决到什么程度?不应该做什么?
  4. 用户如何使用我的软件?
  5. 如果初恋是用户,做些什么会更好?

无论商业软件还是个人软件,定义的源头是场景和技术手段的混合抽象,通过梳理上面问题,在软件启动之初,反复优化抽象过程的结果,帮助团队准确认知目标的价值、背景和约束,让这些底层逻辑的信仰转化为自然反应,支撑后续的每项工程活动、持续思考和改进,参与者投入情感,逐步打磨出善解人意地解决问题、受人喜爱的软件。

1.1. 自然反应

  1. 你可能穿睡衣坐地铁,但不会冒着扎伤的危险,光脚去上班。那为什么不避免打开太多窗口导致软件失去响应?
  2. 你来不及放下手中咖啡杯,直接用它挡住了飞来的足球。那为什么在检测到即将失去响应时没有提示关闭高消耗功能的操作方法?
  3. 你初次约会时理发、刮胡子。那为什么软件难用,看上去用户下单成功,获取物流状态却不及时,寻找商户电话要点击5个按钮,如同理发不洗头。
  4. 你留给朋友的手机号永远能打通。那为什么耦合设计多个子系统的状态依赖,导致给某个子系统发送命令后有时有响应、有时没响应?

1.2. 情感

人很难对每项工作投入情感,那是因为没有受到专业训练,要想配得上出类拔萃的作品,就得改变自己,做少有人做的事。

你有幸加入了哈尔机器人团队,驾驶飞船登月是哈尔的使命之一,如果设计者没有为哈尔加入任何时候都不可以伤害人类的前提,你照本宣科,轻轻松松写下了一个悲剧。

或者当你得知从事科学的初恋也登上飞船,你开始关注哈尔的用户在漫长星际旅行中的寂寞,在哈尔多媒体系统中为每个宇航员准备一张喜欢的虾米歌单,飞船经过你们的故乡时哈尔给她发送一张风景照。

1.3. 活动

进入工程阶段后,对要解决的问题和技术手段的认识越加清楚,破除了若干错误,对于她们的混合方式也有了新的看法,团队内不同角色并行流水线,每个人的日常活动耽于细节,普遍缺乏回顾和反馈,这可能会导致工程流水线上的一系列活动来不及纠正、渐渐偏离目标,失去做得更好的机会。

所以回答上面问题不仅仅有助于动手之前核对目标,也是行进途中不断给团队这台机器加机油、校准方向。

建议团队在腾讯文档中新建一个表格表格,第一列填写问题,第二列填写答案,第三列填写思考。每天惦记着她们,有新的idea填写到第三列并记录日期,反复咀嚼后再更新第二列的答案,并落实到实际工作中。

2. 问题和程度

2.1. 需求

产品需求来自产品经理,技术需求来自开发者。个人软件的需求则全部来自你自身,比如重写一个HTTP服务器。以敏捷中名词为例,无论需求从哪里来,作为开发者要认真思考需求的描述和验收标准:

  1. 有无隐式的未知前提和约束?
  2. 实现有哪些依赖?
  3. 验收标准有无矛盾?
  4. 如果有明显的多义性如未指明操作系统、浏览器类型、并发数量、响应时间、API实现数量、弹出A或B的顺序,需尽快反馈。
  5. 新功能和现有系统有无矛盾,如何解决?
  6. 实现这些验收标准,需要说明哪些前提、限制约束。
  7. 开发完之后如何测试?

疑惑点要及时反馈给提出者,这个阶段的零星失误都可能导致延期和失败。

2.2. UI和UE

UI/UE充分表达了产品经理满足用户的品味,开发者应反复操作UE,揣摩产品经理的意图,顺应开发,遇到UE表达不充分的场景,自行决策时可以延续设计者理念。

没有UI的软件也需要考虑人机交互,比如命令行帮助、运行时命令交互。

3. 技术选型

先评估要做的软件是Demo,还是正式产品,Demo求快,验证想法第一,稳定性、可靠性和维护性可放后,甚至可以集成使用第三方软件。正式产品考虑要全面。

选型的几项原则:

  1. 主流,简单。
  2. 开源而不是闭源。社区火热,Github的Star数。
  3. 兼顾团队技术栈及发展。
  4. 兼顾遗留系统兼容性。
  5. 够好而不是最好(很难评价),不要炫技。技术为目标服务,先快速迭代检验目标的价值,验证方向,技术选择错误还可以重来,没有价值只有失败。

4. 数据采集

任何软件都要朝着目标来纠偏、改进,设计时考虑代码中采集性能指标、维护指标、运营指标的“探针”,通过日志或时序数据库保存,在离线提取后可通过UI显示分析结果。

比如某功能依赖2个子系统,A是第三方依赖,B逻辑复杂,那么监控A的响应时间、间隔和调用A所在线程的状态等,有助于发生异常时定位问题,B由于是自己开发,故提前要求开发者提供获取其内部各项状态和计数的API,以供外界窥探究竟。

5. 持续集成

参考持续交付与Jenkins实践,至少做到:

  1. 自动构建,执行单元/冒烟测试的自动化脚本。
  2. 自动发布,二进制包归档到Gitlab/Github/FTP/网盘。
  3. 自动部署,覆盖安装到测试环境、自动运行软件及对应测试脚本。

6. 怎么测试?

6.1. 测试用例

需求服务于用户,测试从需求出发,首先要站在用户角度,找出评价软件是否在前提和约束基础上达到以下目标的测试用例:

  1. 是否解决了用户问题。
  2. 问题的解决程度如性能是否符合验收标准。
  3. 软件质量的六大性是否合理。

随后是再开展逐项检验。

6.2. 自动化测试

开发者一定要多采用自动化测试方法,从而节省自己的时间去做更有价值的事,恰好自动化后也更容易回归定量定性的测试,即使放到线上环境也可以继续检验。目前对于UI的自动化测试都有许多方案,非UI软件,起码可以通过脚本模拟软件的输入和输出,并分析运行时日志来统计运行状态。

如果你认为某些需求无法自动化测试甚至无法测试,闲暇不妨看看技术书籍,科技新闻和科幻小说,没有做不到,只有想不到。

6.3. 测试环境

ToC业务的后端软件大多部署在云上,规划好负载均衡、灾备的方案后,具备了实施类似金丝雀测试的基础,再结合自动化测试,不难自动统计出不同版本软件的质量和运营数据。前端软件如手机、PC端也有许多虚拟化手段,故搭建测试环境较为容易。

ToB业务很多非标准化的项目,往往得到用户现场才有测试环境,这对于开发者来说却是很糟糕,但也没有严重到要测试一款号称能在太阳表面运行的软件,试试如下办法:

  1. 争取拿到依赖的第三方软件,在公司内试验。
  2. 准备好软件及配套测试工具、用例,发给现场伙伴帮助检验,测试用例要得出定量、定性的结论,测试工具或日志等要给出明确结论。

7. 最后的最后

新软件如同新生儿,前期是孕育,部署使用后才是第一次亮相。

  1. 开发者是软件的父母,用户是软件的伴侣,谁也不希望自己开发的软件被他的伴侣嫌弃。软件临近发布,你觉得哪里还需要打磨?有了可靠的自动化测试覆盖,你还想要重构下也没问题,告诉大家你的想法。
  2. 阶段性分析性能指标、维护指标、运营指标的数据,不断审视开始的开始中的问题,评价是否达到目标、还可以做哪些让软件更好。