1、银弹与没有银弹
《没有银弹》是Fred Brooks在1987年所发表的一篇关于软件工程的经典论文。该论述中强调真正的银弹并不存在,而所谓的没有银弹则是指没有任何一项技术或方法可以能让软件工程的生产力在十年内提高十倍。
在该论述当中,讨论到了次要和必要复杂度的差异。所谓次要复杂度是指由人们本身所产生的问题,而这类型的问题是可以被解决的。譬如说,撰写和最佳化组合语言的复杂度就是属于次要的,它可以借由高阶程序语言如Java来取代。必要复杂度则是从软件本身要解决的问题衍生而来,并无法被移除。如果软件需要提供三十个不同的功能,那么这三十个功能都是必要的,这些功能都必须被实作出来。
由于软件创作包括了本质性工作和附属性工作,前者是创造抽象出复杂的概念结构,后者则是用编程语言来实现这些抽象出的实体。该篇文章的作者认为附加性工作的困难会随着工具的改善而逐渐改善,反而本质性工作的困难难以得到有效解决,因为大部分的活动是发生在人们的脑海里,缺乏有效的辅助工具,
该篇文章的作者认为附加性工作的困难会随着工具的改善而逐渐改善,反而本质性工作的困难难以得到有效解决,因为大部分的活动是发生在人们的脑海里,缺乏有效的辅助工具,故抑制了软件工程的生产力的巨大提高。它的主要困难分为复杂性、隐匿性、配合性、易变性四项。
而老师推荐的第二篇文章则不同意这个观点,认为银弹是存在的。作者认为银弹是观念的变革而不是技术的变革,他从面向对象技术,哥白尼理论和可复用软件构件等部分论述了银弹是一种观念改变。
Brooks认为银弹不存在是因为脑海中的活动没有有效的辅助工具,而 Cox认为银弹是一种观念的改革,这两者其实是统一的。很早时,人们计算星体运动轨迹,需要添加几十个本轮园,而当观念改为日心说时,人们才发现星体的运动是如此的简洁。新的观念就是脑海中活动的辅助工具。即使是未来真的发现了银弹,这又能否认两个人谁的观点?正如莎士比亚所写的麦克白中女巫的预言一样,预言不是假的,而错误在于我们忽略了预言中的前提条件。
我认为,银弹一定存在,因为世界上一切事物,归根到底是简洁的。但是现在重要的事情并不是对未来发出预测,而是立足当下。很多名人对未来的预测都失败了,很多当时学术界主流的预测也失败了。那我们就应该不讨论太遥远的将来,而是放眼于现在,在当前,银弹是难以出现的,银弹的产生终究是一世豪杰之作。而我们开发软件的周期太短,也不可能期盼着人类发现银弹并被我们采用。
就比如我们团队作业是开发一款安卓app,对于使用eclipse还是as,我们曾经犹豫。最初我们采用的传统的eclipse,因为这个曾经是最流行的安卓开发工具,同时我们使用过这款软件。到后期,为了一些UI上设计的简便,我们把开发工具转到了as上,我们体会到as,确实在开发上有了一定的方便,但是概念模型的架构还是需要在大脑中形成,as并无助于它。
2、大泥球
“大泥球”是“杂乱无章、错综复杂、邋遢不堪、随意拼贴的大堆代码”,对于产生大泥球的原因,主要划分为如下几个部分:
1) 一次性代码
2) 碎片式增长
3) 为了让软件不出问题
4) Copy/paste导致问题转移(有问题的代码被复制到很多地方,不断蔓延)
5)缺少前期设计
6)应对需求变化过晚
我们的项目:
1)主要原因是后端采用bmob提供的框架进行敏捷开发,bmob提供的框架使后端的开发层次化,降低了代码的复杂度和冗余的情况。
2)前期设计比较充分,我是负责后台开发的,在每个模块设计时,先是详细的列出了软件的需求及要实现的功能,根据这对后端进行了详细的设计,设计好每个接口,然后就按照这个接口写的,所以代码的复用性较好。这一系列的设计工作保证了我们程序的正确性。
3)代码复审:由于后端是四个人进行编写的,分别实现不同的模块功能,在开发时候,我们团队一直使用的是两人结对编程的模式,每个人写的代码都会被另一个人审查过。这样确保了代码的正确性和可复用性。
我们的软件并没有出现需求变化,这主要是为了开发方便,在作业之初,我们就确定了这款app的功能,之后也一直没有改变过。但是这和现实世界就有些不符了,在现实中需求肯定是难免变化的,这样就涉及到了代码的难以预料的变化,但是很短的作业周期里,我们并不想用需求变化来折磨我们自己。
3.大教堂&市集
Eric Raymond有一篇著名文章《大教堂和集市》(The Cathedral and the Bazaar)。
他说,世界上的建筑可以分两种:一种是集市,天天开放在那里,从无到有,从小到大;还有一种是大教堂,几代人呕心沥血,几十年才能建成,投入使用。
当你新建一座建筑时,你可以采用集市的模式,也可以采用大教堂的模式。一般来说,集市的特点是开放式建设、成本低、周期短、品质平庸;大教堂的特点是封闭式建设、成本高、周期长、品质优异。
Eric Raymond就问了一个问题,有没有可能用修建集市的方式,造出一所大教堂?
他认为,这就是开放的威力。一个开放式的项目,如果加以良好的管理和运作,能取得比同等的封闭式项目大得多的成功。
我们的团队项目采用的是大教堂的开发模式,项目开发是在自己的电脑上进行编写的,别人不能对源码进行修改。根据老师的要求,我们将代码放入开源社区中,供别人查看,但控制权还是归我们团队所有。
但是对于“只要眼睛足够多,所有坏虫都好捉”的支持开源的理论,我并不是怎么肯定。或许是我还没有进入开源社区,我感觉人们不会有时间去开源社区帮别人调bug,每个人的时间都是有限的,哪里有空闲的时间。当然这应该是我见识短浅的缘故。
4、worse is better
在《Lisp: Good News, Bad News, How to Win Big》的2.1章节"The Risk of Worse is Better"中,Gabreil提到了更坏就是更好的设计理念原则。
他先提到了普遍认为是“好”的设计原则:
1)简单性:在实现和接口中,设计必须简单。接口的简单性比实现更重要。
2)正确性:在所有可观察的方面,设计都必须正确。一丝的错误都是不允许的。
3)一致性:设计不能不一致。为了避免不一致性,可以稍微减少一些简单性和完整性。一致性和正确性同样重要。
4)完整性:实际上,设计必须覆盖许多重要的情况。应该覆盖可能出现所有情况。简单性不可以过度地削弱完整性。
他又提到了“更坏是更好”的设计原则:
1)简单性:在实现和接口中,设计必须简单。相对于接口而言,实现的简单性更为重要。简单性是设计中最重要的注意事项。
2)正确性:在所有可观察的方面,设计都必须正确。正确性的重要程度仅次于简单性。
3)一致性:设计不能过于不一致。在某些情况下,为了实现简单性可以牺牲一致性,但放弃设计中处理非常见情况的那些部分比引入实现复杂性或不一致性更好。
4)完整性:实际上,设计必须覆盖许多重要的情况。应该覆盖可能出现所有情况。为保证其它质量,可以牺牲完整性。实际上,只要危害到实现简单性,就必须牺牲完整性。如果保证了简单性,可以牺牲一致性以实现完整性;尤其是在接口的一致性没有价值的情况下。
从这里我们可以看出,他十分推崇简洁。
有人斗胆做了评语,我也十分同意:谁好谁坏,我们往往是在用结果在说话。Gabriel如果不是因为他的公司运营情况不好,可能也就不会得出这个结论。很多事情,是因为做成功的,而不是理论证明成功的。
成败是非本无定,怎样做都有人成功,成功不是理论所能框定的。到底是不是应该追逐简洁,还是应当自己理性的思考。
我们的项目中,最初我的建议是只允许发起一两类活动,主打这些活动成精品,但是队友认为做一个平台,应该支持多种活动,最后我们允许发起六大类活动。很明显,怎么讲都是有道理的,所以不应该追求靠成功的道理来成功,而是靠自己的做来成功。
5、瀑布模型
瀑布模型严格把软件项目的开发分隔成各个开发阶段:需求分析,要件定义,基本设计,详细设计,编码,单体测试,结合测试,系统测试等。像流水线操作一样,把软件开发过程分成各种工序,对每种工序进行了更细致的分配。
我们的项目中,开发流程和瀑布模型类似:在第一周的开始我们针对我们的项目实现、用户需求进行了分析,通过问卷等形式对真正需求量大的需求进行了调查;在第一周接下来的时间内,先由PM对软件框架和模块进行了大致的设计,并结合实际需求分析,再根据组员的不同分工,让组员根据自己的职责再次分析模块基本设计,并提出合理的详细设计;接下来的两周时间内我们分工进行了代码的实现,开发过程中组员对自己负责的各部分功能进行了模块测试,在最后一周,将各组员完成的模块组合拼装并进行完整App的结合测试;然而在最后的系统测试中,我们发现了一个致命的设计缺陷,即缺少用户间的交流功能,我们仅实现了用户实体和活动实体间的联系,用户与用户是通过活动间接关联,无法直接交流,因此阻碍了活动的进行;发现了缺陷后我们只能又返回最初的需求分析,再针对用户交流这个模块重新执行了一遍类似瀑布模型的流程。
6、敏捷开发
敏捷开发以用户的需求进化为核心,采用迭代、循序渐进的方法进行软件开发。在敏捷开发中,软件项目在构建初期被切分成多个子项目,各个子项目的成果都经过测试,具备可视、可集成和可运行使用的特征。换言之,就是把一个大项目分为多个相互联系,但也可独立运行的小项目,并分别完成,在此过程中软件一直处于可使用状态。
对于整个团队的开发过程而言,也算是经历了一次完整的敏捷开发。因为开发时间短,所以每天都是十分关键的,每天都要进行daily scrum任务分析,从中感受到了敏捷开发固有的灵活性和可适应性,在讨论中大家及时把发现的问题和想法提出来,一起交流解决,不但提高了项目开发的效率,也是开发的过程更加灵活,及时适应需求的变化。另外在分工上把软件分成几个子项目分别开发、测试,使用git进行项目管理,子项目有了进展就上传到git上,时刻确保git上整个系统能够处于可使用状态。
7、软件工程的方法论
软件工程的方法论毫无疑问是有用的。方法论是一种以解决问题为目标的体系或系统,通常涉及对问题阶段、任务、工具、方法技巧的论述。方法论会对一系列具体的方法进行分析研究、系统总结并最终提出较为一般性的原则。软件工程方法论是人们进行软件开发时总结出来的一般性的原则。很明显,它肯定是有用的。
虽然各个软件开发公司的项目管理方法各有不同,大小公司不同,各大公司也不同,但是,这些都是方法上的不同,各个方法之间所遵循的方法论还是统一的。
由于各种计算机系统在数量、复杂程度、应用种类等方面的增长对计算机软件提出了极高的需求,一个组织想要维持这样一个庞大的体系仅仅靠经验主义现有的方法是不足够的,此时软件工程的方法论起到了至关重要的作用。
一套完整的方法论体系为软件工程中的成员划分好其各自的职责,同时规定要每个开发流程,以及需要遵从的原则,无疑会让整个开发流程更清晰明确。
我看到网上有人这样评论软件工程的方法论:一种方法论是否管用取决于条件:团队生产力,快乐,保持,遵从,可预言,有责任,沟通,每天代码行数,人月,代码质量,工件等。如果你用对了地方,每个方法论都管用。但是依照唯一的衡量方法就会出现问题,那就是按时、不超过预算地满足需求,我还没有看到任何方法论能够取得一致的结果。
我认为这是犯了混淆方法论与方法的错误。方法论是以方法为研究对象的科学体系,它主要研究方法建立的原则、方法之间的关系以及如何正确应用方法等等。方法是运用一定的世界观处理事物、现象的手段、方式。我们在处理生活中的方方面面问题时都需要运用一定的方法。所以各个公司使用的是方法,他们的失败表明方法的失败,而不是方法论的失败。