个人作业-期末总结
Part1: 阅读作业
在这一部分,首先我将说说我对这次阅读作业中每篇文章的理解,最后结合这次团队项目的经理谈谈自己对软件开发的看法。
1. No Silver Bullet
文章链接:No Silver Bullet
这篇文章我感触最深的还是作者在第一部分提到的,软件的4个本质性困难。
1.1 Conformity
不同组件之间的接口需要严格遵守,这就是说使用者必须学习所有接口的规格。这个问题最好的解决方法应该是对软件的接口有一个统一的规定,但是这基本是不可能的,写程序就像说话,你不可能让所有人表达同一种意思的时候都用同一句话。
1.2 Invisibility
在我看来这是软件一个最本质的特征,它导致我们只能以线性的方式去观察或者构建一个程序,但我们构建的程序的复杂度是以指数级增长的;另一方面,不可见性还会导致程序中概念的冗余,这种情况广泛发生,它就好像你在组装一个机器的时候放进去很多多余的螺丝,如果是这种情况你一定可以很快发现,但是在写程序的时候要发现就没那么容易。这种情况会发生的根本原因一是由于程序构建的自由性;二是在这基础上由于其不可见性导致的程序员对程序中概念理解上的障碍。
1.3 Complexity
上面也提到了,程序的复杂度会随着程序代码或者组件数量以指数级增长(当然这取决于程序的结构,但一般来说它是图而不是链),而程序代码和组件数量却不可能以指数级增长。个人认为这个难点并不是一个专属于软件的特征,而是属于任意一个系统的,同时复杂度也能通过一些手段去控制,比如组件内部的高聚合,组件之间的低耦合。
1.4 Changeability
上面的引用很好地说明了使得软件具有changeability的因素,严格来说这是由外部因素导致的性质,不过实际上我们根本无法避开这些因素去运行一个软件。对于一个面向过程的程序,这个性质更加明显,因为程序是以过程流的形式运行的,所以非常容易受到环境和需求的影响。
1.5 其他
这篇文章中也提到了过去在软件开发中的一些突破,比如高级程序设计语言、分时系统和统一开发环境,但这些都没有解决软件开发的本质性困难;
同时作者也对一些可能的"silver bullet"做了分析,他本人持一个悲观的态度,认为这些技术并不能解决这些困难,其中包括Graphical programming以及Automatic programming等,这些技术在现在看来也有很多确实是无法从根本上解决问题的,但是我们也无法确定像AI,Automatic programming这样的技术在将来不会有什么重大的突破。
2. There is a silver bullet
文章链接:There is a silver bullet
在这篇文章中作者的核心观点是应用面向对象的方式制造可复用的组件可以解决软件开发的困难。
面向对象确实是构建程序思维的一种变革:
上面这段话很好地解释了OO是如何在某种程度上解决软件的Invisibility和changeability的,以前过程式程序时的程序流在某种程度上转变成了代码中存在的实体,继承可以更快更好地构建对象,多态则可以应对Comfomity,一些之前无法解决的问题似乎都有了解决方法,不过作者也说明了面向对象面临的一些挑战:
这里困难体现在两方面,一是我们既需要让代码满足需求,同时也要让它们有复用性,满足需求就不能太抽象,有复用性则要抽象;二是移植性和对环境依赖的矛盾,这个问题现在看来依然存在,不过java的跨平台性应该说在一定程度上解决了这个问题。
个人认为OO确实解决了很多问题,也加速了软件的开发过程,不过那4个本质性困难仍然是存在的。
3. Big Ball of Mud
文章链接:Big Ball of Mud
说起来比较惭愧,由于时间关系我没有看完整篇文章,仅仅对文章提出的一些概念和结论做了归纳,如果有错误欢迎指正。
3.1 big ball of mud
简而言之,大泥球就是指一个结构混乱不堪,代码逻辑混乱的系统,这种系统经常需要不停地维护。
大泥球系统中信息的交互是混乱的,距离很远的组件也可能有信息交互,这就造成系统的复杂度增大。系统中的代码似乎没有考虑过二次使用,使用一次后就丢弃,从观察者的角度看这种做法的确很不明智,然而,这种现象是经常发生的,甚至我自身也有这种情况(很多作业都是这样,代码也许只用一次,出现问题的时候最省力的方法就是因引入一些dirty code,并且它是有效的,即便它会产生一些问题,所以为什么不用呢?)。这种dirty code会侵蚀(erode)原有的健康的系统架构,导致我们继续用dirty code去修复前面的dirty code产生的bug,形成一个恶性循环,最终一个大泥球就产生了。
很多因素会导致这样的系统产生——时间、成本、技巧,甚至软件本身的特质也妨碍到我们对一个健康架构的系统的构建,软件的线性特征会妨碍到我们观察整体的结构,软件的灵活性(我是说,即便是一个坏的设计,通常你也可以修复)同样也会导致这个问题。
3.2 shearing layer
这里作者提出了软件需要具备的两个性质:适应性(Adaptability)和稳定性(Stability),前者是说软件应该可以应对各种各样不同的需求,而后者则是说软件中已经稳定的部分不应该被轻易更改,很容易就能注意到这两个性质是有内在的冲突的:
作者这里用房屋来做了类比:
从外到内有6个层次,这些层次的变化速率是完全不一样的,比如内部的陈设可能几天就会变一次,但是房屋的地点却是不会改变的,相邻层次之间的变化速率差别是类似的,房屋能具有适应性和稳定性正是因为有这样的结构。
所以说shearing layer就是说我们应该让系统中相邻层次之间有类似的变化率。
3.3 refactoring
个人理解重构是随着软件的复杂度增长而不可避免要发生的事情,一个结构必然有它能满足功能的上限,超过这个上限结构就无法完美支持功能,这个时候程序可能变得无法修复甚至无法理解,那么我们就需要重构。
当然,虽然重构无法避免,但在一开始我们仍然需要谨慎对待设计,同时也应该做好重构之后的回归测试。
4. Cathedral and the Bazaar
文章链接:
[1] The Cathedral and the Bazaar
[2] A Generation Lost in the Bazaar
教堂和集市在这里是指两种自由软件开发的模型,前者是指软件在版本迭代过程中,虽然每次都公开发布时候的代码,但在两次发布之间的开发时期,新修改的代码只对开发者开放;集市模型和教堂模型相反,是指任意时期的代码均对外公开。
第一篇文章作者的核心观点是,当软件有更多的人去测试,它的bug就会越快地被发现,这确实是集市模型下的一个明显的优点,同时在这个模型中,用户也成了软件的开发者,这样可以在软件的开发过程中引入集体智慧;但是从另一方面来说,这种做法的缺点也是很明显的(具体可以参看第2篇文章),非专业人士参与到开发中会很容易侵蚀原有软件的健康架构,为了防止这种情况出现,一定需要专业人士对新增代码的检查。
只要能保证代码的质量,更多人参与到开发中一定是益处大于坏处的。
5. 瀑布模型
文章链接:water fall
瀑布模型是一种计划驱动的开发模型,它有完整严密的计划以及步骤之间的回溯:
瀑布模型在《构建之法》里已经有了比较详细的解释,这里就不赘述了。这个模型很适合大型的并且有严格要求的软件的开发,并且开发出的软件会有较高的质量,不过,任何模型都有它适用的范围,这个模型的周期很长,在需求变化快的商业环境下显得有些笨重,这个时候敏捷开发的灵活性就体现了它的优势。
6. 敏捷
文章链接:
[1]Agile Mehod
[2]敏捷已死
[3]The Corruption of Agile
[4]In defense of Agile
个人理解敏捷是顺应现在软件需求变化快、竞争激烈情况下顺势发展出的一套价值观和方法论,敏捷开发希望更快地交付软件以满足需求,它是一种需求导向的模型,所以它在某种程度上舍弃了严谨地计划,但是它并不是一通乱做,它也有一些固定的流程,比如产品规划、Sprint backlog、Sprint以及Scrum,可以说这些流程都是为了能更快更好地开发软件而设计的,敏捷流程在教材中也有详细解释,这里也不多说了。
这学期的团队项目也采用了敏捷开发流程,这个过程中确实能体会到scrum中面对面交流带来的即时反馈对软件开发带来的帮助,不过在这个过程中感觉最重要的是队友之间的互相配合,如果队友懒惰推卸责任,那么有再好的方法和模型也是无济于事的,万幸的是我的队友都非常可靠(这里要表达对他们的感谢),使得我们的开发流程比较顺利(敏捷)。
7. 软件开发的方法论有用吗?
文章链接:Why Software Development Methodologies Suck
作者在这篇文章中提出了两个通用的原则来判断一个实践是好是坏,是否能帮助我们提升软件的价值:减少开发周期和增加反馈
同时作者认为最终软件的整体质量还是需要依靠开发者本身的能力的,同时由于软件开发的不确定性使得技能的学习变得困难,建立一个有强大学习能力和适应能力的团队就显得非常重要;作者也认为一些建立在不可控项目上的对软件方法论的实践是经不起推敲的,这些思想和方法往往不是最重要的。
在上一节我也提到了,我确实从敏捷开发流程中体会到了它的益处,我想如果没有每天的scrum,那么开发进度一定会减缓,所以个人认为软件开发的方法论都是前人总结的宝贵经验,也是他们留给我们的宝贵财富,有能力强的开发人员虽然也很重要,但是如果没有一个系统并且严谨的方法论来指导,同样也是无法取得好的效果的。
Part2: 期末总结
2.1 收获和感想
这个学期软工的几个项目中,最重要并且收获最多的就是团队项目了,总体来说我们在开发的过程中并没有遇到太大的阻力,α阶段基本把能踩的坑都踩完了,之后的β阶段大家都显得比较轻松,并且大部分的精力都投入在编译上。
我们搭建网站选用了Vue+Django的组合,实现了前后端的分离,整体项目的结构中,信息流向很清晰,也很容易把握,负责每个部分的人只需要做好自己部分的内容,前后端交互以及和数据库的交互也只需要一些学习就可以解决。
能这么顺利还是要归功于靠得住的队友以及很负责的PM,在这里再次表达对他们的感谢。我想在团队项目中我学到的不仅是软件开发过程的思想和方法,更重要的是学习如何在团队中交流并和其他人配合。
当然说到收获也少不了一些和web开发相关的技术,以及个人项目中学到的C++和Qt,同时还有一个爬取教务的程序和用这个程序爬到的一大堆课程信息。
2.2 反思和检讨
说完收获也需要反省和检讨一下自己,首先是这次团队项目前端的代码写的并不优雅,甚至有点笨重,由于这是我第一次进行完整的web开发,在α阶段写了很多现在看起来不需要的dirty code,虽然在β阶段的代码中进行了一定的改进,但是已经写完的代码就没有时间和精力来重构了,这也是这次项目中让我比较遗憾的一件事,希望下次有机会能做的更好。