This page has moved! The new URL is: http://softwarepractitioner.org/translations/meyer/teaching.shtml. You will be redirected to the new address in five seconds. If you see this message for more than 5 seconds, please click on the link above!
Translated from the original English version and reprinted
with permission, from "Software Engineering in the Academy",
IEEE Computer May 2001. Copyright 2001 IEEE 经IEEE许可,译自"Software Engineering in the Academy", IEEE Computer May 2001。此译文版权属IEEE。 |
教授软件专业的院校有责任培养出能够建造和维护软件系统,并使这些系统的受益者们满意 的软件职业人员。这篇文章提出了一些关于怎样更好地履行这个责任的设想。 |
软件工程目前没有一个统一的定义。对一些人来说,软件工程只是听起来漂亮一点的程序设计。 如果你是一个程序员,你可能会在你的名片上用“软件工程师”的头衔,而不是“程序员”。 另一些人则会对软件工程有更高的期待。一本教材这样定义软件工程为:“一门包括了方法、 工具和技术的,以生产高质量软件为目的的学科”。
撇开强调质量不说,我们可以从软件工程的工业性质上区分开软件工程和程序设计,并可以得到另 一种定义:“软件工程是开发用于生产环境中的、可能很大的系统,这种开发可能费时长久、人员众多、 多次修改”,这里“开发”包括了管理、维护、验证(validation)、文档,等等。
这个领域的先驱者David Parnas 非常强调这个学科的“工程”部分,主张软件工程教育应该根植于传统的 工程教育(包括象材料这样的课程)[1],并应该使其从计算机科学中分离出来, 就象电力工程从物理学中分离出来那样。
因为本文将提供软件工程教育的一个宽阔的视野,我将不拘泥于这些定义的任何一个,而认为它们 在某种意义上都是正确的,并保留它们从自己角度来看待软件的观点。事实上,我不仅只是集中于 许多大学开设的传统的软件工程课程,并且要更一般地讨论如何把软件工程关心的基本问题反映到 整个软件教学大纲中去。
尽管不是每个人都同意对这门学科的定义,但没什么人会怀疑它的重要性。关于软件系统与 社会的关联性,我们希望不要象Y2K(千年虫)这样令人尴尬,但Y2K在公众心中仍然记忆犹新,足以 提醒我们现代社会是如何地依赖于软件系统。对教授软件的院校来说,不管把软件工程作为计算机 科学的一部分,或是一个专门的软件工程专业,就有责任培养出能够建造和维护软件系统、并让 这些系统的受益者们满意的的软件职业人员。
虽然因为软件系统的故障而丧生的人的数量相对较少, 但是一些影响大的案例却足以提醒公众 注意到我们所用的许多方法的随意性。 |
从就业情况来看,现在和将来的毕业生们应该对他们的选择感到高兴。美国 信息技术协会(Information Technology Association of America)在2000年4月 估计在12个月内IT行业缺人850,000[2]。合格人员的缺乏 在欧洲和澳洲也一样。 工资是非常优厚的。项目经理们会在半夜醒来,担心他们最好的开发人员被 猎头公司挖走,或者盘算着他们最近得到的别的公司对自己的开价。
尽管这种趋势在最近的将来还没有减缓的迹象,但是我们不能想当然地 认为就这样长此下去了。经济滑坡会使雇主们变得挑剔起来。此外,更多的人 正在学习编程,目前市场上有很多功能齐全的开发工具使得这种学习变得 很方便。但这样一来,许多开发人员,如估计有六百万之众的Visual Basic 程序员中的很多人,都没有受到过正规的计算机科学教育。这也产生了竞争, 将迫使真正的专业人员站出来。
事实上,与工业界的经理们谈谈就会知道,他们不仅仅是招聘雇员,他们是 在招聘优秀的开发人员。这实在是一种稀少的资源。软件工程文献表明 [3],在一个 项目里,最好的和最差的开发人员的工作质量之比可达20,而这是很普遍的一种 情况。经理们和那些有招聘决定权的人很快就会学会把一个求职候选者 正确地放在这个谱段的哪个位置上。一个优秀的教育计划就是要把学生训练成属于 顶端的人才。
为什么我们目前的生活还这么不错呢?我们可能注意到我们的“选民们”, 即出资建立以及使用我们所建的系统的用户们对我们的不足是多么地 宽容。用户们对软件抱怨归抱怨,但还得用下去。这种情况不会永远 持续下去的。总的说来,因为软件系统的故障而丧生的人的数量相对较少 (近来有几十起这样的事件[4]),这个数字足以 让许多老牌的工程领域羡慕了。但是,一些影响大的案例却足以提醒公众 注意到我们所用的许多方法的随意性。
即使没有这些事情发生,目前的软件问题已足够地严重,使得一些政府当局, 例如德克萨斯州,要求软件人员持有执照。不管你怎样看这些创议 (Parnas 就认为软件工程师的确应该持有执照并注册),它们反映了一个要 把真正的软件专业人员和偶一为之的程序员相区分的大趋势。
这些趋势对大学有重要的影响。仅仅教授一些时髦的工具可能会取悦于学生和 他们的家庭(他们可以把这些技能与就业广告上最需要的技能联系起来),但这样做 对将来的专业人员来说并非是最好的。重要的是要教给他们根本性的思维方式, 这些将伴随他们整个职业生涯并帮助他们在这个多变的领域里成长。最有成就 者是那些能够超越一时的工具而与这个学科同步发展之人。
这并不意味着我们将忽视行业中使用的工具。在任何工程领域里,这些工具是 专业人员“魔术袋”的主要组成部分。但我们必须超越它们而看到根本性的概念, 这些概念在大约30年前这个领域形成时就提出了,从那以后至今就没什么大的改变。 就象硬件设计,技术在不断发展,而概念却保持不变。
一份软件教学大纲应该包含五个相互补充的要素:
软件专业人员应该知道的最重要的是那些反复出现于他们工作中的基本概念。 这些概念多数不是专门的技术。如果它们包含了一项技术,那么它们一般是 超越了这项技术本身,而取其推理模式(原理)。 这些概念威力强大而表述优美,是我们这个领域共有的智慧宝库。 对一个专业软件工程师来说,掌握这些知识,而不仅仅是一些特定技巧, 是最令人振奋的。这些知识一般来说是不可能一朝一夕就能学到手的,而需要 通过试错与辅导(trial,error,and skillful mentoring)来一点一滴地积累。 当我初次发现这些富于智慧的知识 时,我就产生了一种敬畏之感,这种感觉保持至今。它们是我作为一个教师能 传授给学生的主要知识。
下面列出一些基本概念,这个列举可能是不完全的,但是包括了我们需教授的主要部分。 这些概念不是仅通过语言就能教授的,这是一组创造性的概念,在从业余程序员逐步成为 行业大师的过程中一点点掌握的。
对许多现在能影响软件大纲的人来说,在他们开始职业生涯时计算机还是一门 神秘深奥的学科,只是知道如何使用计算机就足以与众不同了。时代变了,象 Dennis Tsichritzis 所言[5], 今天一个软件从业人员可以从早报上就能很好地学到最新的关键进展了。这 实在是有些有辱学科斯文,但也给我们提出了新的挑战:对我们和我们的学生来说, 到底是什么能使我们拥有我们声称的专业地位?
软件工程教学也应该让学生熟悉业界常用的实用技术,这些技术作为行业的一个 关键组成部分,实践证明它们对软件生产很有效。 |
在一个更“世俗的”(mundane)层次上,软件工程教学也应该让学生 熟悉业界常用的实用技术,这些技术作为行业的一个 关键组成部分,实践证明对软件生产很有效。列举如下:
在“应用”这个标题下,我包括了软件技术的传统领域:基本算法和数据结构、 编译器编写、操作系统、数据库、人工智能技术、数值计算。
我在这里把这些科目加到软件工程上,其目的不是要显出一付帝国主义的嘴脸。 恰恰相反,不管这些科目的传统、技术和结果如何,我坚持认为它们是软件学科, 院校可以根据自己对软件工程的观点来决定如何教授这些课程。好处是双方面的: 一是这些学科可以受益于经过良好软件开发方法训练的学生, 因为学生已学过了设计与编程技能,他们在做程序设计项目时可以更集中于应用的领域, 而不是纯粹的编程;二是这些学科也提供了丰富的应用实例,可以帮助软件工程 达到自己的目标。
一个坚实的教育计划必须要抵制把一时的热门技术来作为教学基础的倾向。 |
软件教学不应由一时的时髦工具来决定。Parnas 就强烈反对教授专门的语言和 工具。但是,如果这些方面不是处于教学的中心地位,我们也不应忽略它们。我们必须让 学生了解工业界所用的最新工具。但在学习这些工具时必须具有一种批评精神,要鼓励 学生看到这些工具的益处和局限,并考虑更好的解决方法。
工具这门课不可能、也不应该包罗所有的工具;最好是选择一些编程语言和几个 流行产品,让学生能深入理解它们。如果需要其他工具,他们可以在工作中学习。 但在学校期间,他们必须已见过一些,并一般知道有什么工具可用以及他们将来的雇主 期望什么。
不可避免的是,有些技能在学生毕业的时候就过时了。但是如果工具课只是大纲的 一个部分,不是主要的教学目标,并且只是作为基本原理的一个实例来学习理解的 话,这些工具过时并不是什么大不了的事。当你需要学习新工具时, 你会发现在学校时对老工具的掌握和对它们的局限的了解对学习新工具是很有帮助的。
这些观察特别适用于编程语言的选择。一个坚实的软件教育计划通常会有自己的答案, 1970年代许多院校选择Pascal就是个光辉榜样。如果现在的选择不是业界的主流 语言,那么大纲应包括一些服务性课程(或课程的一部分)来讲授这些主流语言或标准, 这样使学生在他们的求职简历好看一些,并且对业界实际所用的主流方法有了解。 不管怎样,一个优秀的软件工程师应该是能使用多种语言的,因此在用你所选择的 语言/工具来教授学生和在时间允许的情况下让学生接触尽可能多的语言/工具 之间并无矛盾。
一个坚实的教育计划还必须要抵制根据一时的就业广告来为特定的工具或语言设置课程的 倾向,这种压力会来自各方面,其中以来自学生家庭的最大。由于许多大学中“用户驱动” (user-driven)的因素不断增长,这种压力会产生危险的效果。
这是目前的一个趋势。如果这是在25年前,大学绝不会讲授Pascal,因为那时没有就业 广告需要Pascal程序员;工业界大部分人都没听说过Pascal。这种现象已经越来越引起了 许多教授的耽忧,他们知道,今天热门技能(“in” skills)可能就是明天的死路。当然, 在一个民主的环境里,我们必须考虑每个人的利益,因此教育者有责任从学生的利益出发, 不仅仅是短期的利益,更应从有益于学生长期职业生涯的角度,来选择合适的工具,
David Parnas 认为有些科目是属于计算机科学而非软件工程的,符号语义学 (denotational semantics)便是这样一个例子。我对这个问题的观点是基于 我在工业界作为一个软件设计师和项目经理的经历。和Parnas一样,我并不以为 学生应该对语言理论的知识达到博士水平,但是我很看重程序员形式化推理的能力。 尽管一个软件项目不会在日常工作中运用形式化语义,但是编程和编程语言是 受形式化描述影响的数学“怪兽”,知道这一点是一个重要的优势,我已发现这对 一个软件团组来说尤其有用。
这方面的知识水平不一定要很高。在“编程语言理论引论” (Introduction to the Theory of Programming Languages) [6]中,我试图用实用的 语言总结出一般程序员能理解的、我希望我的团组成员能具备的一些形式化语义背景 知识。在我的软件开发工作中,我反复发现那些能够把数学推理应用于软件开发的 学生和那些没有这个能力学生相比具有明显的优势。根据我的观点和经验,作为一个 完全合格的专业开发人员需要掌握象霍尔语义学这样的理论和象在Z或B中展现的 基本技术,这样能够用数学语言来建立软件问题的模型。
这些技能应是一个坚实的大学教学大纲的一部分,因为如果学生已经在工业界生产环境中 浸泡了很长一段时间之后,通过职业培训课程来学习这些技能就很难了。再来看看Parnas 的强调软件工程的工程性观点,从我作为一个为用户建造大系统的生产者的实用角度看, 开发团组成员具备这些能力要比具备材料工程的知识更加重要。说到底,传统工程学科的 一个突出特点是它们具有坚实的数学基础。霍尔语义学及其类似的原理之于软件工程就象 麦克斯韦方程或力学定律之于物理学。
软件教学大纲中的数学教学应该包括通常的课程,如Knuth认为的微积分和离散数学, 但也应提供逻辑学的坚实基础,用非常实用的语言来介绍形式语义学,以及使用象Z或B 这样的现代形式化语言和证明框架的实践。可以肯定,一些学生会在开始时抱怨让他们 学这些材料,但是我们可以期望,随着他们在职业生涯中的成熟,他们会感谢我们让他们 尽早地接触到这些知识。
除了正式课程以外,任何大纲都应包括软件项目。通常来说,它们都不足以应付真正的软件开发 的挑战,因为这些真正的系统一般都很大(而非而学校教育环境下相对来说的小系统),项目组 也较大(而非学校教学项目的小规模团组),修改业已存在的系统(而非从头开始),与用户 打交道(而非与教授和评分者)。
一般来说,大学不可能、也没必要来完全模拟工业界的开发环境。毕竟,学校不是 公司,也不应该是公司。但是,我们必须使我们的学生准备迎接真正的挑战。标准的 课程项目是不足以达到这个目标的。这个项目应是一个长期项目,不是只做三个 月(一学期),而是(至少)要做一年。它应是一个群体项目,包括了分析、设计与实现这些 方面。并且,它应该包括复用、理解/学习、修改和运行已存在的软件。 要达到这个目标的最好方法是设想出一个可运行好几年的项目,这样一个新班 可以接手老班的结果并发展之。这种想法可能开始会让人觉得有些不切实际,但在 Monash大学有一群热心的教师在Christine Mingins的指导下在过去几年中已经这样 做了。结果是一个给人以深刻印象的图形模拟程序,每个新班都要对这个系统加以 改进提高,在这个过程中学到修改别人源码的挑战和技术[7]。
障碍还是存在的,例如如何对这类项目评分,以及如何在标准的教学时间表上安排这种 跨年度的项目。但是有了决心和热忱,我们可以解决这些问题。我认为这种项目的预期结果 应该使它们值得一试。
今天的学生对典型的入门性编程例子不会太有兴趣。 |
实施多年度项目的目的是“投资于”现代软件技术的一个广阔前景:复用。“逆向大纲” (inverted curriculum)(从电力工程教育的辩论中借用过来的 [99])的原则是:学生先作为用户来使用一些工具或部件来建造他们 自己的应用系统,然后逐步揭开这些工具或部件的面纱看看它们是怎么做的,并改一改, 作一些扩展。这个推进过程是从消费者到生产者,但是选择的实例应功能强大,而规模 也足够大。
这样做有几个益处。学生从一开始就能接触到复杂的程序,如图形处理。这种教学 充分利用了“惊叹效应”(wow effect)以及工作上的立竿见影。今天的学生从很 小就在玩电子游戏和PC机了,对典型的入门性编程例子(如八皇后这类)不会太有 兴趣的。引起学生强烈的兴趣是一种教学法(pedagogy),而非蛊惑术(demagogy)。
更进一步来说,学生能学会抓住必要性,能了解抽象与信息隐藏的益处。我们当然可以 抽象地讲授这些概念,但这种讲法对学生来说就象枯燥的布道说教,效果有限。要知道, 讲授这些课程不仅是成年人良好行为的教条,更是介绍了在大型项目中生存下去的基本 技能。如果学生已经使用过或修改过一个软件部件,并且发现它缺乏与实现相分离的规范说明、 缺乏合适的契约以及缺乏如何处理异常情况的合适描述,那么没什么会比这种经验更好了。
我已经在其他一些文章中和一本书的一章中进一步地讨论过这种教学策略。我认为这可以成为 一个教学大纲的一个中心特点。据我所知,这还没有大规模地试验过,所以它 有一定的风险,需要非常仔细的计划、组织和实施;但是,对一个有雄心和创新精神的 院校来说,这并非是遥不可及。这种教学策略可以极大地提升学生的素质。
计算机系除了教授自己本专业的学生,通常还要为其他专业的学生开始软件课程,特别是工程 专业。他们可能会感受到两种趋势的冲突:一是制订出着重于本学科的小型计算机专业大纲, 二是把这些教学做成作为“服务性课程”以准确地满足“客户”的需要,通常是讲授一些特定 的技能、语言和工具。
这个问题需要小心对待,一不留神就会招致双方的批评。对前者的支持者来说,计算机学者 很自然地想要集中于这门学科的科学贡献,并且讲授“十几二十几”个基础概念。 他们对于其他领域的同事们的干涉会表示不满,认为一味强调有使用工具的技能就行是 贬低了计算机学科对科学领域的知识贡献。
几年前,程序设计课程被引入到法国精英工程院校的预科教学,对于教师们的正式要求是 讲授Pascal,但到递归那里止步。而非常有意思的是,大纲的其余部分里数学的分量很重, 包括一些相当抽象的科目,如拓扑学。制订大纲者认为递归不合适,好象担心让这些17岁 的少年们瞥见了无穷性会对社会产生不良影响。他们似乎传递出了明确的信息:“你们干的 计算机就不是一门学科,你们只不过是知道一些窍门而已,在我们的学生准备进入严肃的 专业教育时,你们教教他们这些窍门就行了。”可以理解,并非所有的计算机学者都会同意 这种观点。
但是,我们的客户专业有权要求获得实用技能,我们对此拒绝是不公平的(想想这些行业今后 还得雇佣我们自己的学生呢)。
这个问题的解决方法可能是中庸之道:控制教学的同时,满足客户的要求,既教基础概念 又教实用技能。随着计算机学科的成熟并去掉一些无序繁杂,这种教学任务会变得容易一些。 数学学者也要给其他系开课,但他们似乎能够以他们愿意的方式授课而又能满足他们的市场需要。工业界声称已经广泛的接受了可复用组件(reusable component)的理念, 但是,这些组件没有质量保证,没有标准,没有规则,没有认证机构。 |
在考虑这个领域过去几十年的发展历史的时候,我们不能逃避这样一个可能是不太愉快的事实: 如果说许多1960和1970年代的创新是来自于学术机构的话,那么少数公司和大型企业的实验 室则在1980和1990年代占了主导地位。这是一个大致的总结,应该有例外,这样说可能会 开罪一些读者。但是,今天很难找到能与下面这些相提并论的学术成果:Wirth的Pascal, Dijkstra的THE操作系统,Hoare的monitor和communicating sequential process,Oslo大学 的Simula,以及那个年代的其他重要成果,这些成果取得了广泛成功,显示出大学不仅能提出好 理论,也能做出有影响的系统。
这个变化的部分原因是工业界的产品已占据了主导地位。Wirth的编译器曾使 苏黎世的瑞士联邦技术学院(Swiss Federal Institute of Technology)成为 软件世界一个家喻户晓的名字,但在今天,不管一个编译器多么新颖,都很难想象 它能取得类似的成果。一个大学的课题组要与微软的C++后面的几百个开发人员竞争 是非常艰巨的,甚至也不太可能与GNU GCC编译器竞争,尽管GNU GCC不是商业产品, 但也不是准确意义上的学术产品。
人们,包括学生,期望编译器能带有功能强大的开发环境:图形调试器(visual debugger)、 浏览器(browser)、图形接口设计器(graphical user interface designer)以及 配置管理(configuration management)工具。学术圈对Visual C++和此类工具有不少 的批评,有些批评也很中肯,但这些工具的确提供了丰富的资源和功能(必须承认,有些设计 得非常聪明),达到了很高的标准,很难与之竞争。如果在一个曾经辉煌过的领地不能与工业 界争雄,那么学术界应该寻找另外的阵地来得分了。
我并不想装出一副我知道所有这些新领域的样子,但我发现把“组件开发” (component-based development)与软件质量相结合是很有前景的。工业界声称已经广泛 的接受了可复用组件(reusable component)的理念,但是,这些组件没有质量保证,没有 标准,没有规则,没有认证机构。风险与机会同样巨大。一个有缺陷的组件的一个小缺陷就可以 产生灾难性的结果。这种情况导致了Ariane 5 火箭初射时的失败,其原因是复用一个软件 组件时出问题,结果推迟了一年半,花费了欧洲纳税人100亿美元[10]。
质量是,也应该是,学术界的专长,质量与组件的结合能创造巨大的机会。长期项目, 博士论文,研究论文,业界合作,以及知名程度,可以来自下面这些题目:
这种努力,当然不排除软件工程其他方面的努力,特别是加上 一个与之相互补充的高质量的软件教学大纲, 可以使有进取雄心的计算机系充满活力并帮助它们获得 不可挑战的国际知名度。
对所有讨论“软件工程”的文献来说,包括本文,我们必须承认这个术语仍然部分地停留在 口号上,与它35年前提出时一样。不过,35年来,我们已经有足够的经验教训使我们能为 我们的学生讲授一系列相关联(coherent)的原理和技术,但还有许多并不那么确定, 这点没必要对他们或我们自己隐瞒。
这里我们试图在概念和操作(原理和技术)之间保持一种平衡,因为我认为一个软件教学大纲 应该如此。我也试图说明我们没必要为一方而牺牲另一方,并描述了一个值得应付的挑战: 建立一个严谨坚实、雄心勃勃、吸引学生的教学和研究计划,它具备最新的技术、根植于 行业的实践,同时也是激励人心的科学探索。
C.A.R. Hoare和David L. Parnas为本文初稿提出了重要意见,在此感谢。
Bertrand Meyer is chief technology officer of Interactive Software Engineering, Santa Barbara, Calif., and an adjunct professor at Monash University, Melbourne. His books include Object-Oriented Software Construction (Prentice Hall, Upper Saddle River, N.J., 1997). Contact him at Bertrand_Meyer@eiffel.com.
Bertrand Meyer 是现代软件工程的先驱之一,具有深厚的计算机科学理论素养与 丰富的软件工程实践经验。我觉得这篇文章对院校的软件教学提出了很好的参考意见, 同时也对全面衡量软件从业人员的素质提供了一个参考框架。
此译文中如有所译不当之处,望诸位同行不吝赐教.
2002年3月
胡健
Email: jian4_hu2@hotmail.com
Web:
https://members.tripod.com/jian_hu