个人阅读作业 --软件工程M1/M2总结
软件工程M1/M2总结
写在前面的话:
这学期的软件工程伴着考期的展开逐渐落下帷幕,回顾这学期的软件工程,我感觉我的热情在一次又一次的失落中逐步消耗殆尽,每个人对于这门课的体验都会有所不同吧,可以确定的是软件工程的方法论非常重要,于实践中的应用也非常重要。但是这是否就自然而然的衍生出我们对于这门课程发自内心的认可呢?我认为这个问题还值得继续探讨。
进入正题:
这学期开始时进行了第一次的阅读作业,通过对于《构建之法》的快速阅读,我提出了对于软件工程方法论的5个问题。
这学期的软件工程课程临近尾声,回头来看这些问题都有了一个较为深刻的认识。
问题1.第四章谈到了两人合作,在这个过程中倘若结对的两个人能力是相近的,如何达到高效的开发,如果两个人的能力是互补的,又如何达到高效的开发?
这学期的结对编程主要存在于两个场景。一个是在结对编程作业中实现一个四则运算的程序,这一作业带有强制性的要求我们通过结对编程来实现;另外一个是在团队项目中,由于M2阶段各种大作业纷至沓来,包括编译课设,数据库课设,C2,Android等,软工项目实际开发的时间相较于M1阶段要少很多,为了提高整体的开发效率而采用的自主的结对编程方法,即通过结对编程达到快速,高效的交流开发目的,从而防止因为交流问题而引入新的bug。
在通过一学期的结对编程实践后,我对于这一问题有了自己的认识,即不论两个人的能力是相近还是互补,在结对编程的实践中深入的交流至关重要,此外,倘若两个人能力相近,可以由两个人共同承担核心功能的实现,而如果两个人的能力互补,则应当把功能切分为尽可能相互独立的子模块,每个人来实现自己较为擅长的模块,对于同样不擅长的模块实现则由学习效率高的同学为主导,通过两个人之间的沟通来协作完成。
问题2.在第六章敏捷开发中,我认为软件设计的可扩展性对于敏捷开发相当重要,而软件的可扩展性应当从那些方面来考虑?即如何做到在需求不断变化的情况下,仍不至于不停地推倒重来?
在这一学期的实践中,对于软件的可扩展性有了一个进一步的认识,在我看来,在软件开发之前对于用户需求的详细分析至关重要,在这一阶段需求分析要尽可能的详细和完善,要从用户的角度出发而非开发者的角度,考虑用户需求可能的变化,要尽可能的为之后的设计留有余地。
软件框架构建的好坏往往取决于架构师的水平,对于已经纳入考虑的基础功能则予以着重考虑,对于在构建阶段已经被用户抛弃的需求则需要进行深入探讨,倘若不存在继续实现的必要性,则将其从基本功能中删去,对于在构建过程中用户提出的新功能则进行重要性判断,一般如果需求分析做的足够充分的话,这样的新增需求往往不是核心功能,而是附加功能,对于这些功能的实现亦纳入框架搭建中考虑的范畴。
问题3.在第十二章谈到了用户体验,有时候确实存在用户体验和产品质量不可兼具的问题,如何抉择?
通过这一个学期的实践,我认为如果将产品的开发分成多个迭代周期的话,那么,我们可以考虑先在M1阶段实现产品的基本功能,即满足产品发布的最小要求,即保证产品的质量,而对于用户体验的优化可以放到M2来做,当然,在M1阶段如果不进行相应用户体验的优化,那么至少应当为M2阶段进行优化提供必要的接口,保证在产品的整体架构上不会出现兼容性的问题。
问题4.在软件的开发过程中是否时时需要具备有防御性编程的意识,这样可能使问题复杂化,或者仅需要按照设计规格来实现相应功能?
这个问题在实践中主要依靠契约式编程思想来实现,防御性编程思想固然重要,但是有时候并没有必要时时对于参数合理性进行验证,否则会产生异常冗余的代码以及非常尴尬的编程体验。
然而不进行验证并不意味着会出错,在使用契约时编程思想时候,所有软件构建的参与者都会遵守相关抽象设计,即在函数的调用过程中事先满足函数的前置条件以及后置条件的约束,在满足这些条件的情况下才认为软件的执行满足不变性,即软件的正确性才能有形式化的保证,才能通过形式化的手段来验证软件的正确性。
问题5.在团队合作中,成员之间需要良好的沟通来完成,有没有什么必要的沟通原则和技巧?
在博客的回复中助教谈到了“unconscious bias”,在查阅相关资料后我了解到:无意识偏见的产生是由我们的环境和自身经验所决定的。由于我们的思维是在不断地处理信息数据,而当我们对问题的分析过程中如果缺乏相关的数据,那么我们无意识的偏见就填补了这一空白,从而影响了我们相互之间的沟通效果。现在已经有越来越多的科学家研究无意识偏见和我们如何防止它的负面影响对于我们决策的危害。
在我看来,无意识偏见对于沟通的影响非常严重,在我们进行沟通以及对于事物进行价值判断的时候可以通过对于相关领域做出相应的充分研究之后再做出判断,而非凭借着无意识偏见做出所谓“经验上”的判断。
软件工程中概念的再认识:
通过这一学期的软件工程理论的实践,我对于其中一些概念有了更加深刻的认识,主要包括有:
- No Silver Bullet:强调软件工程自身的复杂性以及多变性导致软件工程不同于摩尔定律所描述的硬件的增长速率那样,使得我们能够有确定的可期待的通用的优化方法能够使软件生产率得到成倍的提高。
-
Big Ball of Mud:强调代码只是杂乱无章的堆砌,没有进行结构化的设计,导致在开发的后期出现许多错误和缺陷,可以采用如下方法避免大泥球:在软件设计阶段首先需要关注软件的特性和功能,然后集中在架构和性能,使得软件设计之初就避免产生问题或者方向的偏差。其次,在编写软件时要及时解决出现的小问题或者原型概念等等,这样不会使得问题堆积导致后期的无法修改。
-
The Cathedral and the Bazaar:描述了两种软件开发模式,其中大教堂模式的软件开发让程式除错的时间大幅增加,因为只有少数的开发者可参与修改工作。市集模式则相反。
-
A Generation Lost in the Bazaar:描述了集市模式导致的一个悲哀的现实:成堆的权宜代码被一群盲目的根本不知IT架构为何物的所谓IT“专业人士”永无休止地复制着,粘贴着。针对这一现象最有效的解决方式是:所谓质量,只有在某人对它负责时才有意义,而这个“某人”只能是一个人,不能是几个人——二重奏除外。我的理解是针对软件的架构师必须要负责整个软件的生命周期,因为,软件的开发人员可能更迭,如果架构师不负责软件的维护,那么后续的开发人员对于软件很难有一个良好的把控,只能不明所以地沿用前人的代码,而无法对于已经过时甚至错误的代码做出适当的删改,导致软件的碎片化,以及文中指出的那样对于早已过时的Fortan编译器兼容性的检测。
-
Waterfall Model:在《构建之法》第五章(P107)谈到了瀑布模型,瀑布模型将软件生命周期划分为制定计划、需求分析、软件设计、程序编写、软件测试和运行维护等六个基本活动,并且规定了它们自上而下、相互衔接的固定次序,如同瀑布流水,逐级下落,最终得到软件产品。瀑布模型的突出优点是:可在迭代模型中应用瀑布模型。增量迭代应用于瀑布模型。迭代1解决最大的问题。每次迭代产生一个可运行的版本,同时增加更多的功能。每次迭代必须经过质量和集成测试。瀑布模型的突出缺点是:由于开发模型是线性的,用户只有等到整个过程的末期才能见到开发成果,从而增加了开发风险,此外这样的开发过程难以适应用户需求的变化。
-
Agile Methods:在团队项目开发的过程中用到的敏捷开发的思想主要有:采用迭代的方式来对于不可预见过程进行控制,采用SCRUM进行软件开发的进度管理。把一个项目分成若干个为期两周的迭代阶段,每一阶段为一“冲”(sprint〕。每天有一个短会,这样管理者能对项目有近距离的观察与控制。
知识点回顾:
对于软件工程项目实现过程中的各个阶段:需求、设计、实现、测试、发布、维护,每个阶段都学到了不同的知识点,概括如下:
- 需求:需求阶段主要的知识点是需求分析的“NABCD”模型。
- 设计:设计阶段主要的知识点是典型用户和场景分析以及功能说明书和技术说明书的撰写。
- 实现:实现阶段主要的知识点是对于实现流程的把握 。
- 测试:测试阶段主要的知识点是几种测试方法,包括单元测试,回归测试,以及场景测试。
- 发布:发布阶段主要的知识点是对于项目的回顾与反思(postmortem)。
- 维护:维护阶段主要的知识点是接受用户的反馈,并进行软件的维护。