图书前言

前 言

本书起因

从事软件系统研发二十余年,什么是软件系统的非功能需求,到底有多少个“-bility”,它们之间的关系是什么—这些问题一直困扰着我。带着这些问题不断地查阅软件工程、需求工程相关的专著、文章与标准,试图找到一个确切的答案。但令人费解的是:在浩如烟海的资料中,除了包括大量的“-bility”,观点和组织方式也是百家争鸣、百花齐放,再加上各种裁剪的原则,更加使人眼花缭乱,不知所措!

经过长时间、多方面的搜寻,不知不觉中,积累了大量软件系统需求方面的资料,林林总总、良莠不齐,但已然包罗软件需求之万象。

风云际会、恰逢其时。2019年底,接手了一个代码逾1000万行、团队超500名工程师、时间跨越36个月、满足国家等保3级要求、需7×24小时不间断运营的高等级软件系统的研发任务。当时面对的关键问题是:面对如此代码规模超大、运营等级超高、质量控制超严、计划要求超紧的软件系统研发任务,应以谁为抓手、以何为方法来推进目标实现?

以此问题为导向,经过对项目管理、软件系统生命周期模型、领域知识、核心技术难题的深入研究,确定以“需求”为抓手,以“行为驱动开发”(Behavior Driven Development,BDD)为方法,最终成功攻克了这一工程难关。

现在看来,这是明智与正确的选择,任务团队于2022年年底成功完成了整个系统的研发,并在多个年吞吐量超千万旅客的机场顺利投产,持续支撑了民航旅客顺畅、高效、平稳、安全的出行,完全解决了该领域的软件系统“卡脖子”问题。这一成果超出了大部分人当初的预期。

事后总结:要想“多快好省”地研发软件系统,不但要“做正确的事”(Do the right thing),而且还要“把事情做对”(Do the thing right)。以“需求”为抓手,牵住软件系统研发的“牛鼻子”,最有利于这两个目标协调一致、互相促进、共同达成。

也正是这次实践,让我重新研究了软件系统需求的方方面面:经济性、功能性、质量、约束等,也促使我从更高的视角去看待、从更深的内涵去思考软件系统的需求和与其相关的理论、实践。进而,由于在研究这些问题时,没有在收集的任何资料中找到一个完整、全面的答案,于是,就想把自己在此过程中对需求的理解与思考、积累的经验、应用的方法、整理的资料汇集成册,也庆幸清华大学出版社愿意出版此书。期望本书能够对从事软件系统研发,特别是对从事需求发掘、定义、分析的读者有所帮助。

本书定位

读者既可以把本书作为一本自学资料,也可以作为一本指导工程实践、包含完整需求知识的应用手册。

我们熟知学习一门知识的三个阶段:学薄、学厚、再学薄。为了方便自学,在本书的组织上,首先,有一个非常清晰的大纲,方便读者学薄;其次,对于需求设计的方方面面进行了深入的分析和说明,有利于学厚;最后,对于书中应用的各种方法和框架,尽量起一些形象的名字,例如口袋书(POCKET MANUAL①)、决策流程等,有助于再学薄。

需求是专门的一个工程门类,本书尽可能包含与其相关的内容。又因为本书来源于作者的工程实践,因此,也希望读者能够沿着书中的道路,不但能够了解需求相关的、全面的知识,而且能够完成自己的工程实践。在书中我们一方面力求讲清楚相关知识;另一方面也说明了与该知识点相关的国家标准、国际标准、其他优秀资料等,便于读者能够查阅更详细的内容,把书读得更厚。

本书特色

1.内容完整

正如在本书起因中所言,我们在学习和研究需求的过程中,在查阅中外各种相关书籍、专著、标准等资料后发现,软件工程相关资料是把需求当成软件工程中的一个活动,往往只注重需求的分析环节;需求方面相关资料又大多关注它的一个侧面和相关细节,竟然没有一份资料完整地包含需求相关的所有内容(从挖掘、分析、定义到实现)。

这里绝没有贬低这些好书的意思,我们从中学习到了很多有用的内容和好的方法,也正是在深入学习的过程中,才有了写这本书的想法,只是在书的组织方面,关注内容的视角不同而已。

本书从“纵”“横”两个方面,涵盖需求相关的所有内容和活动。

在“纵”的方面,涵盖需求从创意、实现、管理到归档的全生命周期。跟着本书的思路,读者可以体验需求开发的整个过程,需求从如萌芽般的市场机会被发掘,到在如迷宫一样的业务流程中被发现,到归类整齐的操作功能被编制,再到不折不扣地被实现,最终作为宝贵的资产被归档。

在“横”的方面,涵盖经济性、必要性、可行性三大需求根本要素,全面回答软件系统为什么(Why)研发的问题。业务需求向投资者揭示这里有钱可赚;利益相关方需求向用户说明用了这个软件可以提高效率,降低工作强度;系统需求不但向技术团队传递需要什么样功能的信息,还向他们传递如何实现一个符合约束条件的、健壮的软件系统。

2.实践性强

在软件系统研发过程中,研发团队最担心、最不情愿,也是最无法摆脱的问题就是需求变更。经统计,大约50%没有成功完成的软件项目与需求变更相关!因为对于软件系统研发而言,需求代表了正确的事,如果已经做的事情不是正确的事情,那么投入的努力越多,返工的代价越大,所以,在实践中,要想让项目成功,只是“把事情做对”远远不够,更重要的是“做正确的事”。本书就是沿着这一思路组织内容的。

首先是“做正确的事”。在错误的方向上投入的努力越多,越背离目标,离成功越远。在软件系统研发中,用什么来证明做的是正确的事呢?需求从两个层次上证明所做的是正确的事:①通过发掘业务需求,向投资者证明,目标领域是值得投入的领域,能够获得期望的利润回报;②通过定义利益相关方需求,向客户证明,所被推荐的软件系统符合他们的工作要求,能够提升他们的工作效率,降低他们的劳动强度。只有在客户的业务领域中实现了被期望的价值,客户才有意愿为软件系统买单,投资方的回报才能够兑现,也才能形成软件系统利益相关方多赢的结果,才是做了正确的事。

其次是“把事情做对”。选择了正确的方向,只有保证在过程中不偏离、不走样,才能以最优路径抵达目的地。在软件系统的萌芽期,各类技术“大牛”的灵感是驱动软件系统发展的主要动力,因此,技术是那个时期软件系统演进的决定力量。随着“软件危机”出现,人们呼吁以工程的方式进行软件系统研发过程管理,瀑布模型应运而生,需求作为驱动设计、开发、测试、运维等活动的龙头地位也逐步彰显。事物总是在形成模式、突破模式循环中螺旋式进步。由于软件系统无实体和易于变更的特性,瀑布模型的强过程管控模式又导致软件系统“研发完成即过时、无法满足现实需要①”的问题。随之而来的敏捷方法,从软件工程发展的角度看,是对前期工程实践反思的结果,着重强调需求的不可预测性和频繁变化,打着“反文档”的旗帜,总是或多或少地站在反“需求”的立场上。但是,从软件系统全生命周期的角度看,没有完备、准确文档的软件系统是不具有生命力的!针对敏捷方法的矫枉过正,业界专家提出了“活文档”概念,以技术的突破解决技术发展带来的问题。从理论上,“活文档”又否定了许多不“写”文档的理由,甚至,有的专家提出了“文档驱动开发”的理念,这里的文档指的就是需求文档—用自然语言描述的格式化的应用场景,并以技术手段为支撑,形成了从用户需求开始、经过软件系统实现、到用户使用结束的价值闭环流动,从而确保软件系统研发是在正确地做事。这就是BDD方法论的核心精髓:以原汁原味、符合当前实际的需求为抓手,驱动软件系统的研发。

3.深入浅出

在软件系统研发中,需求是一项“跨界”的活动。它一方面要能够让投资人、客户等非技术人员理解一群天天盯着计算机的工程师在干什么,是否在做自己想要的产品;另一方面要能够让研发工程师、测试工程师等技术人员知道用户一天三变的原因,是在为软件系统能够更符合客观实际需要努力,不是没事找事。因此,高水平需求分析师不仅要有技术方面的背景,而且也要懂一些经济方面的知识,还要知道如何与直接用户打交道。这也决定了有关需求的学问是“杂学”,在需求的知识体系中,包含了经济学、心理学、UX、IT技术等各方面内容。要想从零零碎碎、看似毫无关联的众多信息点中整理出完整、系统的需求,需求分析师必须使自己成为一个“杂家”。

但是,每一个需求分析师或想成为需求分析师的学习者都有自己的专业背景,要么来自IT技术团队,要么来自其他非技术团队,所以,对于需求中的某些内容可能感觉陌生。这是正常现象,本书的内容组织充分考虑了这一客观现实。由于本书着眼于对需求全貌的梳理,希望包含其方方面面的内容,所以在整体结构和内容的组织上,首先对于每一个知识点,尽量找到当前权威或流行的定义,使书中的内容能够反映当前软件需求工程领域前沿的成果,避免读者拘泥于过去的传统知识;其次,对于每一个知识点都做了深入的分析和说明,尽我们的最大努力把它从理论层面讲清楚;第三,通过设计一个贯穿全书的例子,展示各个知识点如何在具体软件系统的需求开发过程中实现,以更具体的方式演绎知识的应用;最后,在本书的行文中,力求使用业界通用的术语,减少读者的理解歧义。

4.图文并茂

虽然软件系统最大的特征是“无形”(Non-tangible),但是,无论如何,它最终能够编译成可执行文件或函数库,对于确定的输入一定会有确定的输出,经得起测试验证;然而,传统需求开发方法中却没有刚性的测试验证手段。这也是自然语言描述的需求存在的最大问题。那么该如何消除歧义?

在实际中,针对这个问题,仿真系统应运而生,以可见的方式增强沟通的有效性。在本书中也借鉴了这种办法,每一章的开篇用一幅贴切的图,点出这一章的内涵;对于每一个知识点,都配以尽量贴切、能展示知识内涵的图表,以期能够借助具体、可见的方式,使抽象的理论内容鲜活起来,有助于读者理解。

① 英文为具体方法的首字母缩写。

① 为了与经过软件研发团队分析、筛选、格式化后的正式需求相区别,本书把直接反映用户要求的描述称为需要。

本书内容

基于以上目标,本书内容以软件需求工程为依托,根据作者在实践中对软件系统需求开发的经验,首先,期望厘清与软件系统相关的业务需求、利益相关方需求、系统需求等概念,讲解高质量需求应该包含的内容和开发方法;其次,尝试通过应用实例化需求(Specification with example)、活文档等最佳实践,解决软件系统研发过程中需求与代码实现脱节的问题。聚焦以上内容,全书共分为8章(邢统坤编写了第1~5章和第7章,并对全书进行了统稿,楚军编写了第6章,王宇编写了第8章)。除第1章是全书的概述,第2~8章可分为三部分:第2~5章尝试描绘内容丰富、包罗万象的需求全貌和它们的开发方法,包括回答“为什么研发软件系统”(Why)的业务需求,“研发什么样的软件系统”(What)的利益相关方需求和“如何满足期望”(How)的系统需求等内容;第6、7章基于作者在工作中的实践,阐述在软件系统研发过程中如何保证需求能够不折不扣地向开发、测试、运维等后续阶段传递的最佳实践;第8章总结了如何实现需求在软件系统的全生命周期中进行有效管理的方法。每章主要内容如下。

第1章是对本书整体内容的介绍,尝试从定位、作用等方面回答软件系统需求“做正确的事”的问题:什么是软件系统的需求?软件系统需求在软件工程中的位置和作用?软件系统需求包含的内容是什么?

也是在这一章中,介绍需求的三个层次:业务需求、利益相关方需求和系统需求,点明软件系统需求包括的10大核心内容:任务范畴、投资回报、解决方案选择、利益相关方、用例、需求优先级、应用上下文、人机交互界面、质量需求、约束。引入了需求驱动软件系统研发的最佳实践:实例化需求、活文档,并提出了以“需求追踪矩阵”为基础的需求管理方法。这是本书的总纲,将引领后续内容的论述。

第2章回答软件系统研发“为什么”(Why)的问题:为什么要进行软件系统的研发,所面对的市场机会是否为本企业的机遇?分析投入资源的有效性,ROI是正是负?为了进一步提升机会落地的可能性,介绍如何在多个备选方案中选择最佳方案的方法和过程。

这一章涵盖需求10大核心内容中与业务需求相关的三个:任务范畴、投资回报和解决方案选择。本章介绍如何利用“5W1H”方法界定任务范畴和分析投资回报,并提出选择解决方案的“口袋书”方法。

第3章首先回答软件系统研发过程中“谁”(Who)的问题,软件系统的利益相关方有哪些?它们的代表是谁?其次回答“时间”(When)的问题,软件系统研发任务的时间要求是什么,哪一个更优先?最重要的,是要回答软件系统研发“做什么”(What)的问题,所研发的软件系统要满足利益相关方的哪些需要?

这一章涵盖需求10大核心内容中与利益相关方需求相关的三个:利益相关方、用例和需求优先级。在本章中给出分类方法,并对直接与间接利益相关方进行区分,总结出定义利益相关方需求的、包含5个关键活动的“需求定义环”,详细描述软件需求最核心的内容—用例的抽取、定义与细化,并介绍专家经验和问卷分析两类排定需求优先级的方法。

第4章首先回答软件系统研发过程中“何处”(Where)的问题,软件系统的应用上下文是什么?它在什么样的环境中,由什么用户用来完成什么任务?并从软件系统提供的功能方面,回答软件系统研发过程中“如何”(How)的问题,针对第2章提出的业务问题,本章从功能角度给出了如何满足业务需求的答案。

这一章涵盖需求10大核心内容中与系统需求的功能需求部分相关的两个:应用上下文和人机交互界面。本章详细介绍应用上下文的组成和编制,引入系统需求“四兄弟”的概念:人机交互界面、服务接口、质量需求和约束,并详细描述人机交互界面设计的“四

步法”。

第5章从软件系统的非功能特性着手,包括与可用性、可信赖性、安全性、可维护性等相关的质量需求和软件系统实现中不能突破的约束,基于第4章,继续讲解软件系统研发过程中“如何”(How)的问题,在确定的应用上下文中,给业务问题一个有效、快捷、令用户满意的解决方案。

这一章涵盖需求10大核心内容中与系统需求的非功能需求部分相关的两个:质量需求和约束。在本章中介绍软件系统的三个质量属性模型,描述基于质量属性模型定义软件系统质量需求的方法,总结软件系统研发过程中的约束,并介绍分布在四个层次中的约束项。

第6章继续从实践的角度,回答软件研发过程中“如何”(How)的问题。软件系统研发的最大风险,是程序员没有完全掌握需求文的内涵,也就意味着他们无法“把事情做对”。实例化需求提出的“不修改需求的情况下自动化验证”(Automating validation without changing specification)理念,以“可执行的需求”(Executable specification)方式,从理论上消除了需求人员向程序员传递需求的信息衰减。

这一章详细描述“实例化需求”最佳实践,包括它的6类核心产出物:业务目标、范畴、关键实例、实例化需求、可执行需求、活文档和7个关键流程模式:从目标获取范围、协作制定需求规约、举例说明、精细化需求规约、不修改需求规约情况下自动化验证、频繁验证、演化一个文档系统。

第7章针对技术文档和软件代码不匹配、技术文档更新不及时的问题,介绍几种自动生成最新文档的工具,包括Serenity、Cucumber等。同时,通过对书中例子的总结,完整描述软件系统从业务需求到活文档的实践过程。

这一章是有关需求领域专业内容的最后一部分,首先介绍能实时、完整、准确地反映软件代码的行为,又能够被所有利益相关方读懂的“活文档”及其演进过程。其次利用贯穿全书的例子—用户认证与授权系统,对需求领域所有的专业内容进行总结。

第8章针对已经开发完成的需求产出物,提出在需求演进的过程中,如何利用版本、基线、状态、追踪矩阵等方法,保证需求产出物在软件系统全生命周期中完整性和一致性的管理方法。

这一章是比较独立的需求管理知识,在整个大的软件工程领域中属于配置管理领域范畴,也是能保持需求完整、一致等特征不可或缺的部分。

本书读者

因为需求是软件系统建设的起点,所以任何人想从事软件系统相关的工作,都无法绕过对需求的学习和了解,因此,本书的读者对象非常广泛。如果你是需求领域的学习者(包括计算机相关专业的学生、想转行做软件开发的非专业人员等),希望本书通过对需求知识的全面总结,能够帮助你事半功倍地掌握需求的全貌,快速跨过入行的门槛;如果你是需求领域的熟手(专职的需求分析师,需要掌握需求的架构师、设计师、程序员、测试员等),希望通过对需求相关内容的深入描述,能够方便你把本书作为工作手册,在需要时高效查找自己想要的内容;如果你是需求领域的专家(例如软件工程的专家、学者),期望通过需求关键点的发掘,能够激发你灵感的火花。也非常欢迎大家与作者分享探讨,一起推进我国软件需求开发水平的提升。

本书对于读者的技术水平要求不高。即使你没有任何高级语言的知识,只要了解面向对象、用例等一些基础概念,都能顺畅阅读本书。当然,如果你了解Java、C++、Python、JavaScript等任何一门语言的知识,就能更轻松地把握书中的例子,特别是有关“活文档”的内容,毕竟本书的例子是用Java语言实现的。

本书研读方法

在任何情况下,需求都是软件系统研发的基础和起点,并且,由于它对于软件系统研发的重要性,相关专家和从业者已经投入了大量努力进行研究,并形成了一个专门的细分工程门类—软件需求工程,具有系统性、严谨性和专业性的特点,想要全面掌握需求相关的知识,并不是一件容易的事。

为了便于读者全面掌握需求从发掘到实现的内容,书中专门设计了一个“用户认证与授权系统”的例子,从头至尾贯穿所有知识点,以更具体和好理解的方式诠释书中的内容。因此,如果你已经熟悉需求领域,并且能够自主运行程序,建议从第7章入手:一是可以先把例子程序导入IDE中并运行起来,这样可以在阅读其他内容时有针对性地运行程序中相应的部分,以加深理解。二是第7章作为整本书需求领域内容的总结,全面回顾了前面各章的内容,读完它再读其他章,恰如写用户故事中的“3C(Card、Conversation、Confirmation)”原则应用,先确定了Confirmation,然后再读其他章时,思考它们是不是和Confirmation一致,从而形成学习的闭环,有利于高效、深入地掌握书中的理论知识。

如果你对于需求领域的专业知识相对陌生,抑或喜欢按部就班、循序渐进,那么就从第1章开始阅读吧。建议按以下四个步骤阅读。

读薄。第1章是全书的总纲。首先,对于需求的定义、定位、分类进行详细的描述,并介绍需求相关的术语,是全书其他内容的基础,需要在学习其他部分内容之前进行深刻理解;其次,勾画出需求相关知识点的全貌—需求10大核心内容;接着,点明需求实现在当前软件系统研发项目中的最佳实践;最后,引出需求的全生命周期管理方法。书中后续理论和方法都是围绕这一理论展开的,从范畴来讲,没有超出第1章的界定,阅读这一部分建议采用以下两种方法:①高屋建瓴。在本章中,最重要的是要建立起需求的知识体系,如果你习惯用思维导图,那么这里是绘制思维导图的起点,如果不愿意自己动手,建议看一下书的目录。②不求甚解。在阅读本章过程中,一定会遇到很多陌生、理解不透的术语,这是正常现象,如果对于所有的内容都了如指掌,那阅读本书还有什么意义?遇到不懂的就“暂且搁置”,在后续章节再弄清楚。

读厚。第2~5章是本书理论的主体部分,深入讲解三类需求、10大核心内容,是需求内容“横”向的完整体现。这几章力求把所涉及的每一个概念、术语,所用的每一种方法都讲透、讲深、讲彻底,对于更具体、详细的细节和内容,也都指明出处,以便读者能够真正读厚。实际上,作者在研究这一部分的内容时,读的内容更多,为了一个定义、术语或翻译准确,在中外的资料中反复验证、理解,直到能够无缝地嵌入到整个理论体系中。在阅读这几章时,一个重要的工作是回答前面“暂且搁置”的问题,尽力消除所有自己不确定的内容,当你没有“暂且搁置”时,说明你读的厚度够了。阅读这一部分建议的方法是:①不厌其烦。无论是学术的还是工程的,理论总是严谨的、枯燥的,充满了命令式的用语,虽然作者力求淡化强制的色彩,努力“在铁手上戴上天鹅绒的手套”,但是理论就是理论。②实例验证。需求是工程活动,最终目的是在软件系统建设过程中应用,本书在每一个知识点都用实例进行具像化,如果你能够在自己的实践中找到或构思出实例,一定会使你对于知识点的理解升华。

再读薄。第6、7章是需求实现和理论落地相关的内容。学习理论的目的是指导实践,并提升实践的水平。对于软件系统研发而言,无论多么优秀的需求定义,如果无法完全落实到待研发的软件系统中,都是废纸一堆。“垃圾进,垃圾出”(Garbage in,Garbage out)的反面如果是“垃圾进,珍宝出”,那么珍宝进入后,出来的是什么呢?软件系统研发是工程,工程首要的是可控,不可控能够成功是偶然,可控才是持久成功的保证。这一部分把需求丰富的理论内容落实到“实例化需求”和“活文档”等最佳实践中,使理论有了具体化、可操作的实现,确保工程过程受控。建议阅读这一部分的方法是:①充满好奇。这里有些内容可能超出了你以往实践的范围,作为技术人员,一定要对新鲜事物充满好奇心,不要被看似严格的规则吓住,其实它们一点都不难掌握。②亲力亲为。“纸上得来终觉浅,绝知此事要躬行”,在软件系统研发领域,有时候想了两周都很费解的一些事情,一段程序的运行就能令人豁然开朗,本书提供一个全面验证各个知识点的例子,强烈建议读者把它运行起来。

管控。第8章是需求管理、控制部分的内容。需求是软件系统的核心资产,是软件系统发布版本的基准,在软件系统的全生命周期中需要严格的管控。由于变化是需求的本质特征,所以对于需求的管控,一方面是对已经固化成果的管理,这是版本管理的范畴;另一方面是对需求变更的控制,不但需求如何实现可明明白白追踪,而且代码实现的是哪个需求也要100%可回溯。阅读这一部分建议的方法是:①触类旁通。需求管控属于软件系统配置管理的范畴,把对需求的管控和软件系统其他资产的管控统一起来,能够起到事半功倍的效果。②借助工具。需求管控是与软件系统研发进程对应的一个动态过程,变化的频度和范围依软件系统研发而不同,但是,极大概率会超出手工管控的能力边界,即使手工管控勉强可行,使用工具也会大幅提高管控的效率和精确程度。

以上只是作者建议的常规方法,也许你有自己的“独特武器”,那就应用它们吧。只要有助于提升阅读、学习的效率,有什么方法不能用呢?

本书例子

在软件工程理论相关的书籍中,好的例子往往能起到画龙点睛的作用。本书精心选择了软件开发人员比较熟悉的、大量软件系统常用的“用户认证与授权系统”领域作为例子的业务范畴,并用一个例子贯穿始终。其目的:一是这个领域软件开发人员比较熟悉,不需要再花精力理解例子的业务;二是使用一个例子符合工作中的实际,就像我们在推进一个项目一样,从头到尾、一步一步、层次推进,有利于知识的理解和积累;三是人总是容易记住具体、有意义、系统化的内容,通过一个例子把全书的知识串起来,就可以把它作为一个线索,促进读者对于书中内容的理解和记忆。

在“用户认证与授权系统”的实现中,作者选用了当前流行的Java作为实现语言,辅之以常用的Spring、Cucumber、Junit、Serenity、Selenium、Sqlite、geckodriver等框架和工具,以Maven按照POM的模型对整个工程进行管理。它的好处在于在Maven的配置文件中能完成工程所依赖的所有jar包的配置,读者需要运行时,只需要通过Maven的工作台或者导入自己的IDE,就可以直接运行起来,极大地减少了运行例子程序的障碍。

本书PPT

为了方便读者阅读,我们就本书的内容制作了PPT。很难说是先有书中的文字内容还是先有PPT,因为PPT是每一章内容的大纲,包含了其中的每一项关键内容。对于读者而言,先浏览一遍PPT,可以对本书内容先建立一个大概的印象,也有助于对相关内容的深入领会。如果本书作为教材使用,PPT也可以直接作为课件。

你不是一个人在战斗

软件系统研发不是一个人的战斗,同样,需求的学习和实践也不是你一个人在战斗。孔子曰:“学而时习之,不亦说乎”,任何理论的学习都需要经过仔细的阅读、反复的研究、独立的思考,才能把外部的知识内化为自己的能力。但是,在此过程中,如果有一二良友不断切磋,一群志同者持续研讨,定会起到互相启发、交替引领、共同进步的效果。非常期待你的加入,正如孔子曾说的“有朋自远方来,不亦乐乎”。

本书案例 本书课件