1、什么是软件工程

1.1、定义

最开始:为研究和克服软件危机而生; 官方定义:讲系统化、规范的、可度量的方法用于软件的开发、运行和维护的过程。 抓住定义的本质:用工程化方法去规范软件开发,让项目可以按时完成,成本可控、质量有保障。

想起来在读李智慧老师的《从0开始学大数据》专栏的时候,有一段话印象深刻

不管是学习某门技术,还是讨论某个事情,最好的方式一定不是一头扎到具体的细节里,而是应该从时空的角度先了解它的来龙去脉,以及它为什么会演进成为现在的状态。当你深刻理解了这些前因后果之后,再去看现状,就会明朗很多,也能更直接地看到现状背后的本质。

1.2、演化史

开发软件本质上就像是盖房子一样,是从无到有的创造过程。 工程化的方式,就是你分步骤(过程),采用科学的方法,借助工具来做产品。 于是,参考建筑工程,软件开发过程也被分成了几个阶段:需求定义与分析、设计、实现、测试、交付和维护。

所以读到的重点就是,软件工程的过程划分是参考建筑工程的,所以嘛,对于需求分析就叫需求分析。

1.3、软件工程的核心

一句话总结:软件工程 = 工具 + 方法 + 过程

刚开始看的时候我也只是象征性记了一下这个图和这几个字眼的。

经典教材里给的图,回过头来看真的是很经典的啦~软件工程是应对软件危机诞生的学科,目标就是为了要聚焦于治疗,构建和维护高质量的软件。软件工程的核心就是,围绕软件开发过程,产生的方法学和工具。方法学包含两个部分:过程和方法。
过程:在软件项目的生命周期内,要遵循的步骤。方法:过程中的每个步骤要如何进行。

2、Everything is a project

宝玉老师在这里说到的“掌握工程思维,把每一件事都当作一个工程项目来推进。”给了我更多的向别人安利好用的工具,好的工程方法的理由。

2.1、什么是工程方法

有目的、有计划、有步骤地解决问题的方法就是工程方法。

工程方法通常分成6个阶段:

  1. 想法:定义问题、研究可行性、检查是否有可行的解决方案。
  2. 概念:用图纸、草纸、模型等方式,提出一些概念性的解决方案。
  3. 计划:如何实施。通常包含人员、任务、时间、依赖关系和预算等的资源分配。
  4. 设计:将解决方案进一步细化。设计整体架构、划分功能模块。
  5. 开发:将设计方案变现。
  6. 发布:最终结果的呈现。

2.2、使用工程方法的好处

改变,最有效的方式是改变思想,这往往也是最难的部分。

我们在日常处理事务时,天然地会选择自己感兴趣的、擅长的部分,而容易无视整体和其他部分。更重要的不是是否使用工程方法,而是要站在整体而非局部去看问题。把事当成工程,使用工程方法,有两点显而易见的好处:
有一个被有效论证过的方法论指导你,可以帮助你提高成功概率,也可以提高效率。当你用工程方法去思考的时候,会更多地站在整体而非局部去思考,更有大局观。

工程思维:本质上是一种思考问题的方法,在解决日常遇到的问题时,尝试从一个项目的角度去看待问题,尝试用工程方法去解决问题,站在一个整体而不是局部的角度去看问题。

3、软件工程中的过程模型

就是“软件工程=工具 + 方法 + 过程”的那个过程。 过程是解决软件工程中的混乱,将软件开发过程中的沟通、计划、建模、构建和部署等活动有效地组织起来,两大主流软件过程指导框架:瀑布模型和敏捷开发。

3.1 瀑布模型

边改边写(Code And Fix)模型无法满足复杂软件项目的原因:
整个开发过程不可控,基于这种开发模式做计划太难项目人数上升后难以有效分工协作缺少对需求的有效分析,容易导致后期返工没有有效测试,难以保证程序质量基于此,借鉴建筑工程提出了瀑布开发模型。

3.1.1、定义

瀑布模型将项目划分成六个主要阶段:
问题定义及规划:需求方和开发方共同制定开发目标,可行性研究。输出【需求文档】和【可行性研究报告】。

需求分析:对需求方提出的需求进行详细分析。输出【需求分析文档】。

软件设计:根据需求分析的结果,对整个软件系统进行抽象和设计,包含架构设计、数据库设计等等。输出【框架设计文档】。

程序编码:将架构设计和界面设计的结果转换成计算机能运行的程序代码。输出【可运行程序】。

软件测试:对可运行的结果对照需求分析文档进行测试。输出【测试报告】。

运行维护:正式投入使用后,需要继续维护,修复错误,增加功能。输出【使用说明文档】。

软件生命周期SLC:软件生命周期是软件的产生知道报废或停止使用的生命周期,瀑布模型这样通过把整个软件生命周期划分为若干阶段来管理软件开发过程的方法,叫做软件生命周期模型。

瀑布模型的出现,解决了几个重要的问题:
让软件开发过程有序可控:各阶段任务十分明确。让分工协作变成可能质量有保障。

3.1.2、优缺点

优点:
简单易行可以按照阶段检查,及时发现问题前一个阶段完成后,就可以重点关注下一个阶段有很好的分工协作对质量有保障对着阶段来搞,是会非常清晰的。

缺点:
不能及时响应需求变更。越到后期变更代价越大/最后阶段才能看到结果工作量分布不均衡:前期,开发测试无法参与,后期开发测试又特别忙碌前期进度受阻,会一直压缩后续阶段时间,导致延期或影响质量。

3.1.3、 衍生模型

瀑布模型提供了一个基本模板,但是在不同的实际场景下,完全套用并不适用。在瀑布模型的基础上,衍生了几个代表性的模型。

1、快速原型模型

场景:解决客户需求不明确和需求多变的问题。

定义:先迅速构建一个可运行的软件原型,然后收集用户反馈,再反复修改确认,是开发出的软件能真正反映用户需求。

优点:能快速对用户的反馈和变更作出响应注重和用户的沟通
缺点:质量没有保障

快速原型模型主要是为快速确定用户需求,不一定是最后交付的,所以实际软件项目中对原型的处理有两种策略:
抛弃策略:在确认完需求后,抛弃原型,实际开发阶段重新开发所有功能。

附加策略:在原型的基础上,不断完善,增加新功能新需求,直到达到交付要求。

目前有很多原型工具可以很方便地确认需求,并不需要开发。

2、增量模型

场景:适用于需求比较清楚,能模块化的软件系统,并且能按模块分批次交付。

定义:将待开发的软件系统模块化,在每个小模块的开发中,应用小瀑布模型。

3、迭代模型

场景:按照时间来拆分项目,看单位时间内完成的功能。

定义:每一个迭代结束时,要完成一个可以运行交付的版本。

迭代模型最大的难点在于,规划每次迭代的内容和要达到的目标。

3.1.4 如何选择过程模型

以确认需求为主要目的的项目,不用花太多时间在代码质量上,低成本、高效最重要一个高风险的项目,采用螺旋模型,出现问题及时止损。螺旋模型就是基于增量模型或迭代模型进行开发,每次交付进行风险评估,缝隙过大马上停止开发。一个很长时间加班加点,却一直没办法上线,导致士气低落的项目,可以改成增量模型,然后逐步迭代。

3.2 敏捷开发

因为瀑布模型太重型,周期长,响应慢,所以大佬们总结了一套新的价值观和原则:敏捷。

敏捷开打不是具体方法、框架或过程,是一套价值观和原则。

想解决的问题:用一种轻量的、敏捷的方法来改善瀑布模型中的问题。 软件工程中必不可少的四个阶段,敏捷开发的做法:
需求分析:建立一个个用户故事

架构设计:每个迭代中只做一部分需求,渐进式架构设计。

质量保证:自动化测试,开发的同时编写单元测试和集成测试代码。

发布部署:持续集成。
敏捷开发和迭代模型的区别:
没有严格的阶段划分节奏恒定,产品相对稳定,需求未完成不影响发布
敏捷开发适用条件:
团队要小,超过规模要进行分拆团队成员之间要紧密协作,客户也要自始至终深度配合扁平化的组织结构,更少的控制。有一定比例的自动化测试代码,有好的源码管理和持续集成环境。

3.2.1、一切工作任务围绕Ticket开展

适用看板来跟踪任务状态。

3.2.2、基于Git和CI的开发流程

主要是解决两个问题:
代码不稳定:适用Git枪打的分支管理和灵活的权限控制,可以提高代码的稳定性。具体方法由代码审查自动化测试

部署太麻烦:CI自动部署

3.2.3、部署上线流程

在流程上对上线部署进行控制:
不再部署程序代码,而是Dockers的Image,每次代码合并后CI自动生成新的Image,测试也是基于Image测试部署生产环境前,现在内部的测试环境充分测试部署生产环境前,需要审批确认,有Ticket跟踪。部署时,先部署一部分,监测正常后再全量部署。整个过程都有监控报警,出现问题及时回滚。

3.2.4、每日站立会议

站立会议主要是为了高效沟通反馈,一般控制在半小时内。站立会议的一般流程:
成员轮流发言:介绍昨天任务内容,今天计划内容,工作障碍。会议主持者要及时打断偏离主题的问题,建立问题停车场

检查最新的Ticket:检查新增的Ticket,甄别优先级。

停车场问题:针对之前来不及讨论的问题进行讨论,能在会议时间解决的立马解决,不能解决的另外组织会议或私下讨论。

3.2.5、实践示例

人员:4个程序员(至少一个资深,有架构能力),1个产品经理,1个测试,1个项目经理。

分工:
产品经理:写需求设计文档,将需求整理成Ticket,随时和成员沟通确认需求。

开发人员:每天从看板上按优先级从高到低领取Ticket,完成日常开发任务。

测试人员:测试已经部署到测试环境的程序,发现bug,提交Ticket。

项目经理:保障日常工作流程正常执行,让团队成员可以专注工作,提供必要帮助,解决问题。
每周一个sprint:
周一:部署生产环境

周二:迭代回顾会议,总结上个sprint

周四:迭代规划会议,计划下个sprint工作

周五:分支切割每周轮值:鼓励发挥每个成员的主动性
其中迭代规划会议中,需要对大家一起评估Ticket,可参考的流程如下:

会议组织者阅读Tikcet,同时询问大家对内容是否存在疑问。大家一起讨论Ticket,确保充分理解Ticket每个成员在心中对Ticket进行工作量估算,评分。会议组织者确保同时确认估算结果。如果估算存在分析,最高分和最低分各自说明理由,讨论达成一致。

4、软件项目管理金三角

了解了软件工程的核心,掌握了工程思维,实践中对软件项目的管理需要建立理性的认知,必要时进行合理取舍。 软件项目中有一个平衡关系:
软件质量:产品的质量,客户满意度范围:需要实现多少功能实践:多久可以完成成本:花多少钱

软件工程的目标是要构建和维护高质量的软件。质量高于一切,需要妥协的时候,应该在时间、成本、范围三者之间寻求平衡。

瀑布模型的范围是固定的,时间和成本是变量。出现不能如期完成进度时,通常选择加人或加班。 敏捷开发中,时间和成本两条边时固定的,范围是变量。所以在每个sprint开始之前的迭代规划会议十分重要。