目录

软件工程生命周期,虽然大部分团队的产品项目生命周期都不一样,有的是名称不一样但含义一样,有的根据实际项目删减了个别环节或合并了个别环节,但是软件工程的大体生命周期是客观存在的,这个生命周期像是一个流程模板,根据实际项目情况套用流程模板,定义自己的生命周期。

一般软件工程的生命周期大体是:问题的提出及定义、系统规划与分析、需求整理与分析、概要设计与详细设计、编码与测试、运行与维护。

问题的定义

软件产品就是为了解决问题,解决什么问题,如何定义这个问题?

定义问题就是理解现实世界中出现的问题及用户的需要(痛点),并且初步提出满足用户需要可解决痛点的解决方案。

准确定义问题需要深入分析问题,对问题有更深层次的理解,不停留在需求的表象,要透彻理解用户本质需要,为什么会有这个需要,目的是什么。

提倡的问题定义过程:

  • 团队要在问题定义上达成共识

    有统一的认知,才能把精力用在刀刃上。

  • 深入理解问题的本质

    本质,这词有点玄,透过表象深入本质,理解问题背后的问题,找到用户的真实需要。比如用户说想要在系统里卖商品,本质就是电商;比如用户说想要个论坛,其实用户只是想要发布一些营销内容,那我们可以建议企业门户或CMS快速解决。

  • 确定相关人

    比如产品、设计、开发、运营、测试等负责人,甚至行业专家。

  • 确定系统边界

    避免无休止无目标,尽快出mvp并可快速迭代。

  • 考虑系统实现的约束

    每个解决方案都会存在一定的限制约束,不论是功能还是非功能需求(其他质量属性)

系统规划分析

  • 必要性分析

    必要性:确认问题是否值得解决

    是否已有系统(竞品)可满足需要,是否可以使用其他方案代替,是否有必要规划设计一个新系统来解决这个问题。可以从时间、空间、资源等方面综合考虑。

    商业项目解决问题,并预期能盈利

    公益项目解决问题,并预期能可维持

  • 可行性分析

    可行性:问题是否能够解决

    有些书籍里可行性包含必要性与可能性。这里把必要性从可行性单独拿出。

    可行性可以从三个方面去考虑:

    • 技术可行性:现有技术是否能实现系统。
    • 资金可行性:开发成本及效益分析考虑。
    • 操作可行性:是否可操作、法律版权方面等考虑。

    必要性与可行性都要求团队在尽量短的时间里花最少的代价去确认问题是否值得解决及问题是否能够解决。

需求整理与分析

需求整理与分析也是一项工程,并不仅仅是简单的坐在桌子边冥思苦想。

需求开发

需求按照自顶向下,逐步分解,对问题不断的分解与细化。

需求一般从3个方面归类:功能需求、非功能性需求(性能、安全、高可用等质量属性)、设计约束。

我们还可以从另外一个角度将需求细分归类为:业务需求、用户需求、系统需求。业务需求需要行业领域专家从更高的角度来理解需求,而根据用户实际使用场景理解需求就是用户需求,系统需求是从开发的角度来理解用户需求附属的一些隐性需求。

  • 需求获取

    • 用户访谈及调查
    • 实地考察体验
    • 历史经验及竞品经验
    • 内部讨论会
  • 需求分析

    • 关注业务流程
    • 关注数据流图
    • 关注数据字典
  • 需求设计

    • 文档说明
    • 原型设计
  • 需求验收

    团队可以补充需求验收环节,提供给相关人,由相关人对需求提出建议或意见,多次对需求迭代完善

需求管理

需求开发得到一系列需求后,团队产品需要跟踪需求动态,了解需求状态及及时更新需求变更,保持需求满足用户需要且合理有效。

  • 需求跟踪
  • 需求变更
  • 需求基线

现在大部分团队在需求阶段会产出需求文档说明及原型设计,提供设计阶段的评估与参考。

概要设计

概要设计,设计环节中也被成为顶层设计,主要包括软件结构设计,并确定模块组成及其之间的关系。

产出系统各大模块的结构图。

中小公司团队,在概要设计阶段会基于需求、资源、技术、目标、未来考虑架构整体方案,确定一些主要业务环节模块大概输入输出与逻辑设计方向,确定大致的底层数据结构。

详细设计

  • 界面交互设计

    如果系统有界面有交互,在详细设计阶段甚至在概要设计阶段,需要做界面交互设计,产出界面设计图稿等

  • 数据设计

    数据结构对系统上层设计与实现过程有比较大的影响,好的数据结构设计会使得上层程序设计与模块划分更加自然清晰易理解,降低逻辑过程复杂度。一般采用E-R图描述定义数据。

  • 架构详细设计

    架构设计的目标就是让系统模块化,将程序与数据相结合。

  • 接口设计

    不论是系统内部还是系统之间或外部,都需要接口实现信息的输入与输出。

  • 过程设计

    每个模块或功能的逻辑结构设计,可以清晰的展示数据流自顶向下,处理数据,从底部数据流出整个业务逻辑过程。

编码与测试

  • 编码

    不论是面向过程或是面向对象,都绕不开模块化。

    编码设计多方面,比如语言选择、框架选择、工具选择、编码规范、设计模式、数据结构、算法等,而如果仅仅关注编码方面的话,不论是面向过程或对象的语言,目前都会围绕以下关键词展开编码:

    抽象化模块化封装信息隐蔽继承泛化多态自顶向下逐步求精

    • 抽象化

      一般抽象是对过程、数据、控制机制的抽象。过程的抽象将一个具体场景抽象化支持一系列相似场景过程,数据的抽象将具体场景数据结构进一步抽象支持一系列相似场景的数据结构,业务一般包含逻辑过程+数据结构,结合控制支持业务间的联系。

      抽象化,是发现每个具体场景之间相同或类似的规律,结合规律进一步归纳抽象其具体的操作、数据,使得操作、数据结构定义像是模板定义,提高代码复用率与质量

    • 模块化

      模块化是很重要的概念,每个模块完成一个相对独立的子功能服务,且与其他模块联系简洁,即模块内部高内聚、模块之间低耦合。

      模块化要注意:模块大小适中,模块尽量单入口与单出口,功能明确可预知,调用深度不宜太深,使得模块更多次的被直接调用等

    • 封装&信息隐蔽

      封装是模块化的常使用的法则,尽可能少的暴露内部处理过程,将内部操作细节、逻辑、数据结构、决策等细节隐蔽在内部,通过封装信息隐蔽可以提高软件的可扩展可修改可移植性。

  • 单元测试

    单元测试在(国内)开源项目及大公司团队中才会经常用到。

    国内需要的是盈利的产品项目系统,要求的是降低成本、快速盈利,由于单元测试不利于公司降低成本快速盈利的目标,只能让开发牺牲单元测试,由测试人员完成集成、系统、验收方面的测试。

    但我们提倡单元测试,提高开发效率、协作,提高功能实现完整性。

集成

集成的概念比较宽泛,对于CS、BS项目甚至更大的项目,从模块部件的集成,到构件集成,到服务的集成,从代码上看可以是多个迭代分支的集成,总之集成是一个持续的过程,形成多个临时版本,并最终完成整个项目系统的组装与部署。

测试

软件测试教科书上是这么写的:测试是软件质量的保证,软件测试是为了发现错误而执行程序的过程,一个好的测试用例是能发现至今没有发现的错误,而成功的测试是发现了至今没有发现的错误。

当然没有发现错误的软件测试也是有价值的测试,完整的测试是评定软件质量的一种方法。

测试方法

  • 动态测试

    动态测试,动态的意思就是运行程序进行测试并发现错误

    • 黑盒测试

      黑盒测试,把程序当做一个黑盒,不考虑程序内部结构,一般是功能测试、界面测试等,以下是一些常用的黑盒测试方法:

      • 等价类划分
      • 边界值分析
      • 错误推测发
      • 因果图法
    • 白盒测试

      白盒测试对象基本是源代码,必须了解程序内部结构及逻辑

  • 静态测试

    相对与动态测试,静态测试就是不运行程序,对程序进行检测。

    • 开发自测

      由开发人员自行检查自己实现的功能,通过编译、单元测试、代码分析等方法

    • 代码审查

      代码审查,可以是由团队成员互相做code review,也可以通过会审的方式阅读讨论,也可以由团队更高阶开发负责code review,目的都是发现开发自己没有发现的编码错误或风险,也能促进相互沟通学习及团队协作,避免编码重复,提高代码复用率。

  • 性能测试

负载测试与压力测试都属于性能测试,压力测试是通过确定一个系统的瓶颈来获得系统可提供的最高服务能力,负载测试是通过逐步增加负载来获得当前工作负载下系统的性能,两者可以结合进行。

性能测试的目标都是为了进一步优化提升系统性能效率,降低服务成本。

测试阶段

测试是伴随着软件开发周期的,从需求分析开始,测试就可以逐步介入,了解需求及目的,设计维护测试用例,开发自测(含单元测试),集成测试,产品验收测试。

大部分团队的测试可以分为4个主要阶段:

  • 单元测试
  • 集成测试
  • 确认测试
  • 系统测试

运行与维护

对于近10年的项目都倾向于移动互联网项目,运行我们也可以理解为上线、发布。

  • 运行

    上线发布,传统的方式一般由开发团队负责,在内部产品验收评审通过之后,开发团队提前准备上线方案,通过内部评审,并安排上线发布。一般会涉及到源码或程序部署、数据库更新、静态资源更新、App/小程序提交审核、版本更新、开关设置等等。由于各个环节的上线存在前后依赖关系,稍微复杂的项目都需要提前准备上线方案。

    最近几年,行业的频繁迭代需求催生了持续集成CI、持续交付持续部署CD解决方案,解决了传统手动维护分支,提高了开发团队仓库分支管理效率,持续交付将部署到预生产环境,并完成测试,持续部署则在通过自动测试后,将自动部署到生产服务器。CI/CD的前提是要求自动化测试,减少手动测试,尽量小改动提交,确保测试环境与生产环境部署一致。有了CI/CD,开发团队只需要完成代码提交,后续可以交给项管或测试团队测试处理,但需要随时跟踪,直到被部署到预生产环境。

  • 代码仓库维护

  • 系统维护

[待进一步完善]


@tsingchan