软件开发与反馈控制系统?这是哪儿跟哪儿呀?你也许会问。我却发现二者之间有很多相似之处。
反馈控制系统是一种最常见的控制系统。在反馈控制系统中,输出信号被检测出,经控制器处理形成反馈信号,与输入信号相减,从而调节被控制系统的输入信号,使输出信号趋于稳定。如果反馈控制器失灵,系统输出值就很容易偏离设定值。
我觉得软件开发实际上是一个复杂的控制系统。用户需求和开发人员的劳动等是输入,代码及各种文档等是输出。软件开发的目标是尽量使开发出的软件符合用户需求。而用户需求也会不断变化,是一个移动的靶子。这也是软件开发难的原因之一。怎样使软件开发在控制之下(under control)呢?
若干年前,我曾参与一个图形编辑软件的开发。开发工具是MSVC 1.0。当时我们对Windows编程已相当了解,对面向对象的编程技术也已有所掌握。同事们的干劲也很高。几个月后,老板已能在展览会上做演示。潜在客户的正面反应使老板很兴奋。他要求我们不断实现新功能,以参加一个接一个的展览。而对发现的错误视若无睹,只要不死机就成。表面看来,软件的开发进展良好。但实际上已问题成堆。功能都实现后,开始修改错误。但修改一个错误往往会引起其它错误。最后我们发现有些关键的错误简直就没办法,除非做很大的改动。挣扎一段时间后,该项目不得不被放弃。想来真是心痛。
究其原因是我们没有及时查错,更没有及时改错。我们没有及时得到反馈,即使有反馈,我们也没有用它来调节我们的行动。有些错误在开发阶段看起来可能并不严重,既没有造成死机,也没有造成数据丢失。但它们有可能是软件结构不合理造成的。这种错误如不尽早解决,将后患无穷。即使软件结构合理并且没有严重错误,就能保证软件是用户所要的吗?未必。
那么在开发过程中能得到哪些反馈呢?怎样才能尽快得到更多的反馈呢?
结构化程序设计建议采用自顶向下、瀑布式的开发方式。这种方法把软件开发分解成分析、设计、编程、测试、发布等几个阶段。结构化程序设计最大的问题在于:它要求你在开始编程前对该软件有全面、正确的理解。但这样的机会究竟有多少呢?所以采用结构化程序设计的软件开发就像一个开环系统,很容易偏离预设的目标。
现在渐进迭代式开发(incremental iterative development)日见普及。方法是在软件开发过程中设置几个里程碑(mile stone),通常是三、四个左右。每到达一个里程碑时,都要交付用户或潜在用户一个可用的初级产品。它可能功能不全,但一定要通过质量控制。这时要听取用户的意见。用户的意见是极重要的反馈,它能保证系统的功能是正确的。每两个里程碑之间,又划分成若干循环。每个循环又由分析、设计、编程、测试等步骤组成。通常开发每个功能(feature)的开发都要经过一个循环。一个循环大约为两个星期。这时的反馈主要来自开发小组和测试小组。反馈的形式包括设计复查(design review)、代码复查(code review)、单元测试(unit test)、功能测试(functional test)等。发现问题及时解决,决不姑息。这些反馈能保证系统结构是正确的。
只有结构和功能都正确,你的软件才能成功。相信大家都学过结构与功能之间的关系。结构决定功能,功能对结构有反作用。通常开发人员更注重结构,而用户则只关心软件的功能。忽视了功能,用户可能不买你的软件。忽视了结构,软件将难于维护与扩展。渐进迭代式开发有助于你兼顾这两方面,因为你能及时得到两方面的反馈。
其实,小到做人,大到治理国家,都需要反馈。没有反馈,就可能走偏、失控。软件开发又岂能例外?