软件工程教材:百科全书与入门指南

发布时间:2022-09-19 08:22:53 来源:欧宝APP下载地址 作者:欧宝app官网下载

内容简介:  历经一年半,我们这本《现代软件工程基础》教材终于由清华大学出版社出版了。这本教材反映了我们这些年来对于软件工程课程教学的思考以及对于以实践为中心的软件工程教学方法的探索。我将这本书的特点总结为下面四条:  1)在覆盖经典软件工程方法与技术的同时突出体现了现代软件工程在开发过程和技术上的特点,例如开发运维一体化(DevOps)以及持续集成与持续交付、演化式设计、软件开发框架与平台复用、分布式与云原生软件体系结构、敏捷开发需求分析等;  2)按照“做中学”的实践化教学需要以及软件工程师的成长过程进行教学内容编排,从基本的协作开发和编码...

  历经一年半,我们这本《现代软件工程基础》教材终于由清华大学出版社出版了。这本教材反映了我们这些年来对于软件工程课程教学的思考以及对于以实践为中心的软件工程教学方法的探索。我将这本书的特点总结为下面四条:

  1)在覆盖经典软件工程方法与技术的同时突出体现了现代软件工程在开发过程和技术上的特点,例如开发运维一体化(DevOps)以及持续集成与持续交付、演化式设计、软件开发框架与平台复用、分布式与云原生软件体系结构、敏捷开发需求分析等;

  2)按照“做中学”的实践化教学需要以及软件工程师的成长过程进行教学内容编排,从基本的协作开发和编码能力开始,逐渐过渡到更加抽象的软件设计和需求分析等内容;

  3)强化高质量编码与可信软件开发的要求,体现现代软件工程对于软件工程师个人的质量意识和可信软件开发能力的要求;

  4)华为公司软件人员能力提升变革项目团队参与编写,融入华为多年来在信息通信领域积累的软件开发方法、工具与相关实践。

  我大约是从十二三年前开始上本科“软件工程”课程的,此前还上过几年与之相关的“软件实践”课程。最初上“软件工程”课时教材沿用了前一位老师所用的一本国外经典教材,此后还用过另一本国外经典教材。在此过程中,虽然教学内容越来越熟悉,但总感觉讲的不是那么流畅和顺滑,一些内容像是碎片化的堆积。这不是说这两本教材不好。事实上,这两本教材的作者不仅教学经验丰富而且都有大型工业界软件系统的开发经历,书中的内容十分丰富而且反映了软件工程实践的发展。但是这两本书更像是一本软件工程的百科全书,整体内容的选择和编排可能更适合一个成熟的软件工程师遇到问题后去查阅,而不适合初学者作为入门指南。例如,其中介绍的内容可能缺少铺垫、过渡和承接,不少内容的理解可能需要相应的企业软件开发背景。此外,书中对于具体的软件编码和构造实践着墨较少甚至基本没有,这也导致内容较为抽象。

  事实上,网上关于“软件工程”课程的吐槽很多,诸如“像是政治课”、“考试各种概念解释,手都写断了”之类。好多年前我们学院的一位同学还在BBS上抱怨说软件工程似乎就是教一个不会打仗的小兵如何当将军,这显然是把软件工程等同于项目管理了。虽然很多学生工作后从事软件研发相关工作时都会感觉到软件工程很重要,但在学校里学了啥可能都不记得了。这也说明软件工程这门课要上好不容易,因为抽象的原则和方法学指导过多,而具体可掌握的知识点较少,考试经常都是概念性的填空题和简答题。

  软件工程课程的实践性很强,因此一般都会安排配套的课程实践项目。最早我在上“软件实践”课时,课程实践项目配合教学进度,都是先做需求分析然后做设计。这样大半个学期过去了,文档写了好多页,UML图画了好多幅,但代码一共没写几行,学生也不知道这些文档和UML图除了应付检查之外还有什么用。这样一来,学生对于软件工程的理解就是写文档,甚至感觉文档写得越长分数可能越高,由此在眼疼胳膊酸之余对于软件工程就留下了难以改变的负面印象。后来在上“软件工程”课的时候尝试过多种课程实践模式,主要包括课程大项目和系列课程实验两种。其中,课程大项目完整体验软件开发生命周期,需求、设计、实现、测试各环节之间的延续性好,团队协作体验更充分,但是中间过程可见性差,难以激发学生的兴趣和热情。为此也尝试过通过迭代式的过程让学生体验需求变更和增量式开发。而课程实验则结合每个部分的知识点和技能要求精确设计对应的实验内容和要求,包括需求建模、软件设计、编码任务等。这种课程实验受控性好,可以充分体现教学要求,但缺少完整、深入的软件项目开发体验。

  以上的教学模式探索过程虽然也在不断改进但总还是不那么顺。后来感觉主要问题出在我们是从“教”而不是“学”的角度考虑问题。因为我们使用的教材是按照软件过程、需求理解与分析、体系结构设计、组件级详细设计、用户界面设计、软件质量、软件测试这样的顺序编排的,所以我们的课堂教学也是按照同样的顺序进行的,内容也是围绕教材上的知识点进行。相应的课程实践项目也是先做需求分析、然后做设计,接下来留给编码和测试的时间就不多了。

  事实上软件工程的很多概念、思想、方法和技术都来自于软件开发实践中遇到的各种问题以及相应的实践探索。例如,下图这些让开发人员饱受折磨的问题催生了敏捷开发、持续集成、测试驱动的开发、版本与分支管理、松耦合设计、代码评审、质量门禁等软件开发方法、技术和实践,并驱动了相关软件工程工具和平台的发展。由此可见,软件工程知识和技术内容具有很强的实践性以及问题驱动的特性。

  反观修读软件工程课程的学生,一般都是大二或大三本科生。他们之中大部分已经掌握了初步的编程能力,熟悉常用的数据结构和算法。但是,他们对于软件工程知识所对应的问题背景和实践意义却缺乏理解。例如,他们可能会觉得把所有代码都写在一个文件里也没什么,因为程序规模没那么大而且也没有维护和修改的需要;他们没有用过Git版本库,平时都是用微信文件传输或者U盘与其他同学共享代码;他们编程序的时候一向是听懂了要求就打开IDE写代码。

  如果我们从“学”的角度思考问题,那么我们就要考虑如何根据学生的基础为他们提供一份“入门指南”,而首要问题就是为他们创造理解软件工程问题所需要的上下文环境,而这个只能通过课程实践项目来实现。通过课程项目模拟企业软件开发实践,创造问题上下文,让学生对软件工程问题有体验有共鸣。例如,因为有多人合作并行开发,因此会发生代码版本混乱甚至相互覆盖的情况,从而理解版本管理和分支管理的必要性;因为每次迭代结束后都要进行部署运行并由助教验收检查,因此会体验到提交时间之前头一天匆忙集成会导致错误百出,从而体验到持续集成和测试、主分支严格管理以及合并请求审核的必要性;因为迭代化开发过程中需求是以增量化的方式不断提出的,同时还伴随需求变更,因此体会到糟糕的设计以及各种代码坏味道对需求增加和调整带来的巨大影响,从而体验到软件设计思想以及面向对象设计原则和设计模式的意义;因为课程项目涉及前后端并且希望多人协作并行开发,因此很自然会按照前后端进行分工并体会到了接口不明确对于前后端集成带来的重要影响,由此理解前后端分离和接口设计的重要性。

  通过这种方式,学生可以对相关软件工程问题有一定的理解和思考,在此基础上再学习一些具体的方法和工具并在课程实践项目中加以运用,就能更加深刻地掌握相关思想、方法和技术了。此外,我们还可以借助于各种软件开发平台和工具对学生每次迭代所交付的软件以及中间开发过程(如代码提交和分支管理记录、缺陷管理过程记录、软件构建与测试过程记录等)进行分析和测试,从而对效果进行检验并提供针对性的反馈。此外,由于要使用主流的开发框架,例如后端的SpringBoot以及前端的Vue,因此会对框架中所蕴含的各种软件思想有所体验,例如MVC模式、AOP、依赖转置、依赖注入以及各种设计模式等。

  明确了“工程化软件开发入门指南”这一定位和导向后,相应的教学思路就清楚了,那就是按照软件工程师的成长路径重新编排教学内容和进度。如下图所示,软件工程师首先应该具备基本的软件构造能力,包括基本的版本管理、高质量编码、单元测试以及简单的功能测试等。接着,软件工程师应当学会如何与其他同事协作开发,因此需要掌握过程管理、代码评审、问题追踪和配置管理等知识和技能。然后,软件工程师应当学会如何考虑一个软件模块甚至整个软件应用的设计,因此需要理解基本的软件设计思想,并掌握面向对象设计原则、常用的设计模式和开发框架等,并具备持续重构和改进设计的能力。最后,软件工程师可能会对整个软件产品的策划、部署和发布负责,因此需要掌握基本的需求分析和建模以及构建、部署和系统测试能力。

  按照这一思想,我们重新设计了整个课程实践。首先,课程实践按照4人一组进行分组,以小组为单位完成整个学期的课程项目。其次,整个学期的课程实践由一个项目贯穿始终并分五次迭代,每次迭代都会加入新的需求并伴随需求变更。再次,随着迭代过程逐步增加新的实践能力及工具使用的考查点,侧重点从编码能力、设计能力到分析能力逐步进阶。最后,整个课程实践项目全程依托华为软件开发云DevCloud进行,整个开发和协作过程全程留痕。

  按照这种方式重新设计课程实践后,原来的教材和课程教学安排就无法与之相适应了。因为原有的教材和常规的课程教学模式下基本都会按照软件过程、软件需求分析、软件体系结构设计、组件级详细设计、软件测试这样的顺序编排,基本上与课程实践的能力进阶顺序是反过来的。这样一来,学生可能感觉学了大半个学期的内容跟课程实践项目都没啥关系,等到感觉有点关系了,学期基本就结束了。当然,我们也可以让课堂教学与课程实践二者脱钩,但这也加大了作为软件工程入门者的学生的学习难度,难以在课堂教学与课程实践之间形成共鸣同时也会质疑教学内容的价值。

  为此,大概从四年前开始,我开始尝试抛开手里的教材,按照自己的理解重新编排课程教学内容,从高质量编码开始,逐步过渡到更加抽象的软件设计和需求分析等内容,同时紧密围绕课程实践项目开展的需要选取教学内容,去掉一些与课程实践关系不大的内容。这样一来就没有完全对应的教材了,只能在课件的基础上推荐几本相关的参考书。这样的状态持续了两年,终于感觉应该按照这种思路写一本自己的教材了,而且与华为公司的软件人员能力提升变革项目团队一拍即合,双方决定合作编写这本教材。于是在以实践为中心、按照软件工程师成长过程进行内容编排的思想指导下,我们将华为多年来在ICT领域积累的软件开发方法、工具与相关实践融入软件工程课程,并强化了高质量编码与可信软件开发的要求,体现现代软件工程对于软件工程师个人的质量意识和可信软件开发能力的要求。此外,我们还突出了现代软件工程在开发过程和技术上的特点,例如开发运维一体化(DevOps)以及持续集成与持续交付、演化式设计、软件开发框架与平台复用、分布式与云原生软件体系结构、敏捷开发需求分析等。

  如此一来,我们的教学内容与课程实践安排有了更清晰的对应关系,学生可以在概览式地了解计划驱动的过程、敏捷开发、DevOps的基础上,随着课程实践的逐步推进逐渐理解版本与开发任务管理、高质量编码、软件设计、软件需求等部分的内容,同时在实践中贯穿软件复用、软件测试和软件集成与发布相关的内容并进行理解。对于软件体系结构部分,我们在传统的软件体系结构决策、软件体系结构描述和软件体系结构风格等内容介绍的基础上,加入了分布式软件体系结构和云原生软件体系结构的知识,并在课程实践中鼓励一部分小组尝试采用微服务开发和容器化部署。

  今后,我们还将继续以实践为中心的软件工程教学方面的探索。一方面,我们将陆续完善教学视频、自测题等线上教学资源,逐步开展线上线下混合教学和翻转课堂,从而将课堂时间更多用于代码评审、设计研讨等实践化交流讨论。另一方面,我们将继续加强校企合作,与企业合作开展能力认证示范,通过认证结果形成实践化教学反馈。

  本书是软件工程的入门教材,系统地阐述了现代软件开发过程、方法、技术以及相关工具,使读者能够全面掌握现代软件工程的相关基础知识以及软件工程师所需要具备的基本实践能力。

  全书共分为10章,覆盖了现代软件工程的主要内容,特别是需求分析、软件设计、软件构造、软件测试等。本书各章的顺序按照软件工程师的学习和成长过程进行编排,首先围绕高质量编码所需的知识和能力进行介绍,然后逐渐过渡到更加抽象的软件设计和需求分析等内容。第1章介绍软件工程的含义、发展历程和重要思想。第2章介绍软件过程模型、敏捷方法与精益思想以及开发运维一体化(DevOps)。第3章介绍软件版本管理与开发任务管理。第4章介绍代码质量的含义以及高质量编码方法。第5章介绍软件设计的整体内容并具体介绍组件级详细设计方法。第6章介绍组件级、框架级、平台级三个层次上的软件复用方法。第7章介绍软件体系结构的基本概念以及分布式软件体系结构和云原生软件体系结构。第8章介绍软件需求分析方法、敏捷开发中的需求工程以及可信需求的含义。第9章介绍软件测试方法以及相关工具。第10章介绍软件持续集成、发布以及软件构建和依赖管理。

  本书可作为高等院校计算机、软件工程、人工智能、自动化等相关专业的本科生教材,也可供相关领域的专业技术人员参考。

  1. 在覆盖经典软件工程方法与技术的同时突出体现了现代软件工程在开发过程和技术上的特点,例如开发运维一体化以及持续集成与持续交付、演化式设计、软件开发框架与平台复用、分布式与云原生软件体系结构、敏捷开发需求分析等。

  2. 按照“做中学”的实践化教学需要以及软件工程师的成长过程进行教学内容编排,从基本的协作开发和编码能力开始,逐渐过渡到更加抽象的软件设计和需求分析等内容。

  3.强化高质量编码与可信软件开发的要求,体现现代软件工程对于软件工程师个人的质量意识和可信软件开发能力的要求。

  4.华为公司软件人才能力提升变革项目团队参与编写,融入华为多年来在信息通信领域积累的软件开发方法、工具与相关实践。

  游依勇华为技术有限公司软件工程学院院长,在软件开发、产品线总裁、人才培养、产业管理、生态建设等岗位具有20多年的工作经验,曾获得国家科学技术进步奖和中国电子学会科学技术奖一等奖。

  赵文耘复旦大学计算机科学技术学院教授、博士生导师。研究方向为软件工程、企业信息化。曾获国家科技进步二等奖、电子工业部科技进步特等奖、上海市科技进步二等奖、上海市教学成果二等奖等多项国家级和省部级奖项。