讲授《软件工程》这门课断断续续已经有十个年头了,现在回过头总结一下自己的思考历程,与大家分享。
1、史前
我所在的学校是一所职业技术学校(学院),1997年刚调去的时候,我们计算机系才建系不久,连带系主任总共只有八个人。那时,我刚开始从事计算机教学工作,我能做的无非是把过去在学校学的内容,鹦鹉学舌地搬给学生。教学计划也是系主任参考其他学校的计划,删减而成。但随着教学经验的积累,开始从体系的角度考虑教学内容的内在关系。后来在讨论02级的教学计划时,我力主增设《软件工程》这门课。
2、开始
在02级的第五学期(04年下半年),我开始为他们讲授《软件工程》课,选用的教材是清华大学出版社出版的郑人杰编著的专科版教材,这是一本讲授传统的面向过程为主的教程,有一部分OO的内容(其实,我当时对OO的认识并不是很深,以为学习了OO的语言,就理解了OO)。为了激发学生的积极性,我把这门纯理论教学的课程加入了实践的内容,即我将每个班的学生编为5至8人的项目设计小组,由他们选择我提供的若干项目或自选一个项目为设计课题,作业分为分析和设计两个阶段的文档,另外包括一个数据库设计文档。我一边讲授理论,他们一边用我讲授的理论作分析、设计文档,每个文档都规定了提交时间限制,与成绩挂钩。我用大约整个授课学时的60%左右的时间做讲授,等我讲授完成后,他们用剩余的时间分组在课堂上讨论他们设计文档。没想到这一做法取得了异乎寻常的效果,几乎每个班的讨论都热烈而积极,也取得了一批很好的学生设计成果。这之后,在06级、08级……直到现在14级,陆续讲授很多届学生的《软件工程》。
3、OO
在以后的专业学习中,我陆续读了一些网上介绍的各种名著。大约在05年我逐渐领悟到整个软件领域包含两个复杂的需要人们花费功夫的价值点。一个是解决问题的算法问题,另一个是解决软件本身的复杂性的问题,随着软件规模越来越大,软件的内在结构的合理性已经成为行业的一个价值点。
与我03年初在书店偶然发现《设计模式》、《重构》等名著不同,05年底我在有了上述想法后,就专门去书店有找相关的书籍,很幸运,我一下就找到了Bob大叔《敏捷软件开发》一书,于是就开始迷恋XP,并一度在教学中让成绩较好的学生,演示其中的保龄球计分程序的演练,效果也不错。
这时,由于高职学校强调对外合作办学,我们系开始与北大青鸟开始软件工程师的合作项目,我发现他们的技术培训讲师(高级技术支持),和我那时一样也存在着为模式而模式的过度模式的倾向,尽管我并没有完全看懂GOF的《设计模式》(后来在网上看了李建忠老师的系列讲座,才算真懂了),在内心还是把它们像神一样敬着。
在成为我校的第一批青鸟合作教师之后,开始接触青鸟的教学模式,它最大的特点是将实践引入到教学中。其实,计算机学科本身就是一门实验学科,只是由于早期国家穷,实验条件无法满足教学需要,才不得不偏向理论。当前,在实验硬件条件已经大幅改善的状况下,回归以实践为主的教学已是必然,但由于积重难返,这个过程将持续一段时间。而且,由于没有认真思考计算机理论实践的关系,另一种极端的完全抛弃理论知识,为实践而实践的做法开始泛滥。
在青鸟的培训学习过程中,我开始在青鸟的实践项目中接触三层的软件架构,并以此为开端,陆续学习了胡协刚的培训教程,马丁﹒福勒的《企业应用架构设计》,《Microsoft﹒NET企业级应用架构设计》等关于软件架构方面的书,开始认识到OO软件包括微观、中观、和宏观三个层面。
所谓OO软件的微观层面,就是OOPL的三大语法:封装、继承、多态。能将多态的虚函数实现机制掌握了,就基本算到位了。这一点我在早期看侯捷老师的《深入浅出MFC》的时候就弄懂了,这也使我认为学习了OOPL就学会了OO,并固执了许多年,直到接触设计模式。
OO软件的中观层面,就是建立在对OO原则的深刻认识之上而形成的OO设计模式。主要包括GOF经典的23个以及IOC。它是OO精华的所在,值得学习,也值得欣赏。以它们为基础,进一步实现了规模更大(宏观)的框架和架构。
OO软件的宏观层面就是框架和架构。架构是一个软件全局性的、唯一的框架,而其它的框架则是局部的复用半成品。
4、冲突
在学习胡协刚的软件架构资料的时候,谈到了“不要陷入极限编程的陷阱”,提出对软件的复杂性要有全局的设计,提出软件开发应该从宏观着手的观点。而这一观点与《敏捷软件开发》一书中介绍的XP方法,从中观层面着手的轻量级方法不同。
这使我陷入了一个困局,究竟是从大的方面着手的,还是从小的方面着手,去实现一个教学实例系统呢?
5、释然
直到最近,开始阅读范钢老师的《大话重构》才最终找到答案。原来,当前软件是一个因不断应对新的需求带来的复杂性的提升,而其结构在不断演化的动态过程。
让我们先从软件的来源数学说起,据说,图灵机是图灵对人们使用纸笔进行数学运算的过程进行抽象而得来。所以,用计算机解决问题,就是一个复杂的解题过程。但是,我们的解题算法是如何描述呢?
“目前几乎所有的算法书的讲解方式都是欧几里德式的、瀑布式的、自上而下的、每一个推导步骤都是精准制导直接面向目标的。由因到果,定义、引理、定理、证明一样不少,井井有条一丝不乱毫无赘肉。而实际上,这完全把人类大脑创造发明的步骤给反过来了。看起来是阳关大道,实际上车马不通。”
“算法诞生过程中的思路往往包含了比实际算法更本质得多的知识,实际算法乃至算法的某个特定语言的实现包含了太多表面的不相干知识,它们会阻碍对本质的理解。” (见刘未鹏的博客《知其所以然》)
对软件的结构也是一样,软件模式如果也是如此的精准制导直接面向目标的。就直接使用它们,为模式而模式,堆砌出一个超出我们需要的复杂度的软件结构,从而引入不必要的复杂。
在《大话重构》一书中作者提出的“恰如其分地规划,演进式地开发”使我找到了问题答案,我觉得我可以开始写我的教学实例软件了,它应该是一个不断为需求推动的而演进的软件系列。