软件工程阅读作业二——团队项目理解与心得

  软件工程团队项目Alpha版本已基本完成,我们的项目是一个Web UI设计——Xueba在线学习网站。团队在整个项目中应用了C#、ASP.NET、SQL等语言,为这个项目付出了极大的努力。

  在项目即将发布的欣喜时刻,我们阅读了老师推荐的一些博客、论文与书籍,对软件工程整体的概念与理论也有了一些新的认识。我就“没有银弹”、“瀑布模型”、“大泥球”、“教堂与集市”、“敏捷开发方法”等文章结合自己参与的团队项目来总结一下理解与心得。

   我们对Silver Bullet这个概念都不陌生。能够干掉几乎无敌的狼人的银色子弹,如果用在软件项目开发中,自然是所向披靡,一些让我们很痛苦的开发难题会迎刃而解。然而很遗憾,就目前软件发展的情况来看,所谓的银弹是不存在的。就像Albert Einstein生前致力于的统一场理论一样,想要创造一种能够涵盖所有方面问题的解决方案或工具是不可能的。Frederick P. Brooks, Jr.先生在文中指出的几样很有望成为软件开发银弹的语言、概念如Ada语言等,这些都是被认为是很优越的软件开发解决方案,但却依旧无法成为银弹。软件的特性本身也导致不大可能有任何的发明创新——能够像计算机硬件工业中的电子器件、晶体管、大规模集成一样——提高软件的生产率、可靠性和简洁程度。

  我们必须看到这样的畸形并不是由于软件发展得太慢,而是因为计算机硬件发展得太快。从人类文明开始,没有任何其他产业技术的性价比,能在30年之内取得6个数量级的提高,也没有任何一个产业可以在性能提高或者成本降低方面取得如此的进步。这些进步来自计算机制造产业的转变,从装配工业转变成流水线工业。

  对于软件开发来说,一个相互牵制关联的概念结构是软件实体必不可少的部分,它包括:数据集合、数据条目之间的关系、算法和功能调用等等。这些要素本身是抽象的,体现在不同的表现形式下的概念构造是相同的。尽管如此,它仍然是内容丰富和高度精确的。软件开发中困难的部分是规格说明、设计和测试这些概念上的结构,而不是对概念进行表达和对实现逼真程度进行验证。当然,我们还是会犯一些语法错误,但是与绝大多数系统中的概念错误相比,它们是微不足道的。

  如果这是事实,软件开发总是非常苦难的,天生没有银弹。If this is true, building software will always be hard. There is inherently no silver bullet.

  我们的团队在开发这个项目时,还没有上升到考虑银弹的高度。因为我们做的东西所需要的知识有很多是全新的,我们需要learning by doing新知识,还远远达不到考虑它的多方面优缺点以及是否有成为银弹可能性的程度。程序员对于面向对象编程一直都有着很高的期望值,可我们现在虽说也是写过一定数量的面向对象程序,却依旧没有真正掌握其精髓。要在这一次小规模的团队项目中所涉及到的技术与银弹联系起来过于牵强,但我们单是从这有限的技术手段中就已经体会到程序设计面临的诸多困难挑战。我们不能期望着银弹横空出世为我们干掉所有的障碍,在自己的能力范围内尽可能多地学习程序设计手段或许才是完成工程的不二法门。

  1970年 ,Dr. Winston W. Royce提出瀑布模型,他结合自己在过去参与宇宙飞船空间任务的分析项目经验发表了Managing the development of large software systems阐述对计算机软件开发的看法。

  任何计算机程序开发无论规模大小都有两个部分,即分析与编程。但是对于软件的实现来说,分析与编程并不是一成不变的。因为对于软件开发者或是软件开发部门内部使用的小型软件,软件的实现、功能与使用都不必像面向全体客户那样事无巨细都要达到很高的标准。仅仅是通过分析与编写程序实现需要的功能就完全足够了。而那些用户付费使用的、应用更为广泛的更大型的软件,这些细节方面的东西就必须纳入考虑之内。仅仅是简简单单的analysis与coding显然已经不能满足大工程的实现要求。

  要实现更大规模的软件,就要从最初分析与编程的基础上衍生出更多的实现步骤,也就形成了较完备的瀑布模型:

   系统需求—软件需求—软件分析—程序设计—代码实现—软件测试—运行维护

   虽说叫做瀑布模型,但这整个的开发阶段并不是像瀑布一样从上到下按顺序走一遍就大功告成。它们之间的联系十分紧密,每一步都是在其上一步和下一步的基础上实现的。前一步是后一步的基础,后一步是前一步的反馈。虽然各步互相依存,但是非相邻的两步却没有太大的联系。为了保证每一个步骤的正确实施,我们希望每个步骤有一定的交互,然而不幸的是,我们在测试的时候往往会发现设计甚至是需求的问题,因此我们不得不返工。为了很好地解决这个问题,我们采用几个步骤来解决。

  1)   Preliminary Design,程序设计先行,确定在进入需求分析之前,我们的概要设计要完整。

  2)   Document the Design,书写设计文档,确认我们的设计是完整的。

  3)   Do it Twice,双保险,把文档了的东西试着预先走一遍,看看能否成为最终产品。

  4)   Plan,control and monitor testing计划,控制和监控测试。

  5)   Involve the customer  用户介入,全程review各个环节。

  最后,一个完整的瀑布模型就完成了。

  现在,当你在使用waterfall开发软件的时候,知道为什么痛苦了吧,40年前就已经如此了。

  我们团队的项目还没有完成瀑布模型中的后一部分,但对于模型中提到的“返工”我们可是充分领教到了。我们之前对于需求分析并没有想得很详细,在写代码的时候不断补充、删减、修改,最后才形成现在的作品。根据反馈更改程序设计前期的工作,这本身就是一个相辅相成的前进过程,但是因为自己一开始考虑不够全面而导致的大的功能变更,这应该算是开发过程的忌讳。我的老师曾经这样给学习新知识打比方:学新东西就像蒸馒头一样,第一遍蒸不熟,再回笼就不是那个味了。同样的,开发新软件在第一遍写的时候没有打好基础,将来也就难逃崩溃的命运。

  至于大泥球,这太贴近我们的开发过程了。我认为行云流水般顺畅地完成软件开发应该是每一个程序员的梦想,但是真正在开发过程中没有遇到一点的混乱与邋遢对于我们来说实在是难度太大了。虽然出现了各种鼓励、促进良好结构代码的开发方法,软件技艺运动也在不断成长,但大泥球看起来仍然是设计软件架构的最常见方法。即使人们已经从过去恶劣的设计中学到了东西,但在新的开发过程中,大泥球仍未消失。我们的项目组出现杂乱无章、错综复杂的代码的例子不少,这也为最后整合到一起增加了很多困难。

  大泥球发生的主要原因可以归结为:

  • 一次性代码
  • 碎片式增长
  • 为了让软件不出问题
  • Copy/paste导致问题转移(有问题的代码被复制到很多地方,不断蔓延)

  我们常提的敏捷是解决这个问题的手段之一,但是值得注意的是敏捷之所以能起作用,不是因为其流程,而是因为很多实践能够让人们持续关注技术的卓越性、回顾、面对面沟通和得到激励的个体。当软件质量下降时,采取简单的重构和测试。因此,看起来并不是流程能够帮助减少泥球,最终还是有责任心的程序员愿意承担责任、保持警惕。除非如此,不管是敏捷还是非敏捷,大泥球总会挥之不去。

  说到敏捷,我们的项目中也不纯熟地运用了一些敏捷的开发方法。我曾读过敏捷软件开发宣言(Manifesto for Agile Software Development),我们在开发中也体会到了这些原则:个体和交互胜过过程和工具;可以工作的软件胜过面面俱到的文档;响应变化胜过遵循计划等。工作的软件是首要的进度度量标准——这是我们毫不动摇的基本原则。而其中有关结对编程和SCRUM的方式我们也实践得很好。

  在之前的讨论中我们也谈到过不要为了敏捷而敏捷。在我看来,在目前的软件开发中,多数方法仍是边写边改(code and fix),那么,引入一些纪律约束肯定会比一片混乱要好。敏捷型途径的主要优点在于它的步骤要少得多。如果你已习惯于无过程,那么遵循简单过程应该比遵循繁琐过程更容易一些。对任何新过程,你都需作一番评价,这样你可看一看它是否适合你的环境。我们的小组虽然只有6个人,但是在开发过程中对敏捷的态度基本都是支持的。敏捷开发众口难调,就目前而言我们的项目从敏捷开发中收获不少。不管我们以后是否会继续从事软件开发方面的工作,从软工团队项目中学到的互相学习合作的精神,将是帮助我们在任何领域实现个人在团队中价值的重要利器。

你可能感兴趣的:(软件工程)