蔡维德 李 磊 
北京航空航天大学

引言

当前,许多新型技术凭借开源方式推广。开源 软件的发展由来已久,目前已有数以万计的开源社 区和模型。由于开源软件存在局限性,近来学术界 开始对开源软件和社区的发展进行反思,认为 :开 源软件的使用比开发更重要 ;要重视发展开源软件 工程技术 ;在大数据和云平台的环境下,应该建立 新的软件工程,包括软件的需求、设计、测试、整合、 部署和监测。

开源软件和开源社区的发展

一个流行的开源软件拥有一群高效率的开发者和数量庞大的用户群,在通常情况下,用户无须 支付费用。这些“免费”的开源软件往往由拿着高 薪的工程师完成。为什么这些工程师愿意无偿从事 开发?以Linux为例,以前很多人虽然反感微软的 Windows系统,但由于没有其他操作系统,只能选 择Windows。当Linux系统开源项目一出现,许多 软件开发组织自愿加入进来。再如,OpenStack的 开发也是如此,许多公司愿意付薪水给员工,并将 其组成团队进行开发,期望OpenStack能取代市场 的主导产品。如果市场上出现了能够主宰市场的产 品,而其他公司却没有足够的资源能在短时间内开 发出自己的产品与其竞争,这些公司就会结成联盟 使用开源软件开发来改变竞争态势。安卓系统也存 在同样的情形。该系统一直在利用开源软件系统与

其竞争对手苹果iOS系统对抗。 由于每个参与开发的组织都有自己的管理方 式、企业文化及软件开发流程,因此他们只能以开 源的方式合作,通过社区交换代码进行交流。这是 开源软件和开源社区的驱动力。 比尔·盖茨说过: “市场占有率是最重要的”[1]。 一旦占领市场,以后开发出来的软件就不得不依靠 之前拥有市场主导地位的软件,所以软件公司以占 领市场为首要任务。由于人们可以免费或低价获取 开源软件,所以开源成为占领市场的利器。 从许多开源软件的事例可以发现以下几个事实:
1. 虽然大多数开源项目没有成功,但是成功的 开源软件占据了绝大多数市场份额,例如Hadoop、 Linux、Spark和OpenStack。
2. 成功的开源软件大多是被“赞助”的(意指 多个公司结成联盟进行软件开发),而“独立”的 开源项目则大多失败。
3. 成功的开源项目也可能走向失败,其原因有: 出现了新一代产品,开源软件领导核心离开以及企 业改变了经营策略等。
4. 许多新的软件技术也经常使用开源软件来进 行推广。例如作为当前金融学领域炙手可热的区块 链技术 [2]。 “开源社区”的核心是“开源”,社区是“果”, 而不是“因”。“赞助”往往是“因”,有了大量的赞助, 才有了大量的开发人员。此外,社区这个“果”并 不意味着其相应的软件已经成为“产品”。软件产 品和项目是不同的,一个软件成为产品要花费大量的工程与测试。所以如果有人认为软件放在开源社 区开发,就会有工程师免费参与,那是不切实际的。如果没有赞助,相信大多数工程师都没有兴趣来开 发,愿意无偿开发的工程师毕竟是少数。
斯蒂芬·瓦利斯(Stephen Wallis)在其著作中提 到了开源社区和顾客的不同 :社区是一群开发者, 对软件有兴趣,有大量的时间却缺乏资金 ;顾客正 好相反,没有时间但有钱。在一个社区里,开发者 也可能是顾客,但不是每一个开发者都是顾客,也 不是每一个顾客都是开发者。社区活动的要素包括 :社区辨识与认同 (identify community)、社区的 使命(mission)、平台工具、参与机制(architecture of participation)、行为准则、知识产权和治理结构等。 开源社区需要顾客发现软件和使用软件,培训 顾客使其了解软件并产生购买欲望。开源社区与顾 客的关系如图1所示。
开源软件和开源社区的反思_dotnet
成功的开源社区形成的模式通常经历以下过程 :
1. 项目开始于一些开发者对问题的讨论 ;
2. 开发者讨论要发展的项目 ;
3. 把软件放在开源社 区,让其他的开发者共同参与 ;
4. 建立说明文档及 FAQ1,让众人参与讨论 ;
5. 建立一个非盈利的基金会。基金组织确认知识产权管理的制度,使投资人从上述生态系统中获益。

开源软件的开发和应用

开源软件技术分为软件“开发”及“应用和采 购(adoption and acquisition)”两部分。人们往往谈 论软件开发多一些,但是,通过了解美国国防部对 开源软件的方针就会发现,他们更重视“采购”和 “使用”[3]。早期美国卡内基梅隆大学软件工程研 究所(SEI2)曾提出软件能力成熟度模型(Capability Maturity Model, CMM)理论,其重点是“软件的开 发遵循着一定的流程”,流程在一定程度上保障了软 件的开发质量。这在过去是正确的,但后来美国国 防部的软件开发项目几乎全部采用了外包策略,这 才有了软件采购技术的研究。采购技术是一种关于 设计软件需求以及验证外包商开发的软件是否能够 被采纳的新兴技术。 “采购”与“开发”技术有所关联。“开发”是 源于“生产者”的观点,目的是用最高效的方法研 发软件; “采购”是源于“消费者”的观点,目的是 用最低的费用来快速地得到和使用有质量的软件。 例如,生产者(工程师)关注设计和制造软件,消 费者(用户)则更关注软件的质量、维护以及使用。 采购技术是为了收集、批准和使用软件。对于 那些有开发进度数据的软件系统,采购者需要检验 开发进度中的数据,以判定开发者或者项目管理者 是否存在欺骗。如果已经偏离了规定的进度,或者 明显落后于计划,管理者就可以采取措施来改正或 取消项目。 如果没有可利用的进度数据,则采购者需要检 验产品来判断软件质量。因此,采购者关注的是测 试和评价数据,根据需要获取足够的此类数据,来 确保系统符合质量标准、安全性和可靠性标准。这 项工作通常包含端对端测试和集成检测 [4]。采购者 还需要确保所需的项目能够集成到现有系统中。因此,采购技术包括计划、承包、进度管理(包括规范、 控制、跟踪和审计) 、测试和评价以及最终政策和 指向。 在开源软件时代,采购的一个重要目标是创造 可信赖的软件库,库中只存有通过严格测试和用户 验证的软件。虽然国内外的开源社区非常多,也提 供了大量的开源软件,但只有极少数的开源软件能 通过严格的测试而放在可信赖的软件库中 [5]。美国 国防部开发Forge.mil社区就采取了这个策略。 表1比较了开源软件的 “开发” 与 “应用和采购”。
开源软件和开源社区的反思_C#_02

应用社区的探索

Forge.mil社区

Forge.mil与软件开发社区有许多不同,主要有 以下几个特点 [6] : (1)需要用户提前、持续地参与系 统开发 ; (2)软件开发者必须经常发布不同版本的软 件 ; (3)所提交的软件必须可以持续升级 ; (4)开发 者必须使用一种可模块化、开放的流程。社区包括 软件库、协作开发/测试的环境、软件过程管理与 方法、软件工具与资源这四个部分。 其软件开发的方法是敏捷开发方式加上开源 软件。要实现这个方法不仅需要社区有许多的开源软件,还需要对这些开源软件的使用提供大量的支 持,包括传统的软件开发工具、社交网络以及大数 据。可以利用大数据方法搜集每个开源软件的元数 据,并利用云计算上面的快速运算来帮助搜寻开源 软件。开源软件元数据是SEI所做的工作 [7],正是 得益于他们的软件支持以及云计算平台的联合,才 有了持续集成 (continuous integration)、持续测试 (continuous testing)以及持续部署(continuous deployment)等技术。

其他软件社区

其他具有代表性的开源软件社区有Black Duck (黑鸭软件)、Stackoverflow以及CSDN(中国程序 员大本营)。Black Duck是开源代码审计和管理领域 的领导者,软件包含Protex、Codecenter和Export 三个工具。Protex用于代码扫描,可以帮助用户发 现自己的源代码中是否含有开源软件代码,如果有, 则帮助用户判断其是否有触犯开源软件知识产权法 律的风险。Codecenter是帮助用户在软件开发生命 周期中管理和有效使用开源代码的工具。Export能 够帮助用户发现源代码中是否含有加密算法等。
Stackoverflow是一个与程序相关的技术问答网 站。用户可以在网站免费提交问题,浏览问题,检索相关内容。
CSDN创立于1999年,目前是中国最大的信息 技术社区和服务平台,为信息技术从业者提供服务。

开源软件工程教育

开源软件改变了软件工程。当前由于人们已拥 有大量的开源软件,并可以利用一些方法搜寻元数 据,再加上能够获得持续集成、持续测试、持续部 署等工具的支持,使得软件开发模型开始发生根本 的改变。例如,软件需求被改变。在传统的需求中, 不论是瀑布模型或是敏捷模型,都需要先与顾客讨 论需求细节。而在开源软件的环境下,则是先查看 相关的开源软件,再了解开源软件的需求,这是因 为很多开源软件已经包含80%的新软件需求。在此情形下,可以把开源软件的需求当作新软件需求的初稿。同样,设计软件的时候,不是先设计软件,而是先在开源社区里查看是否有可重用的设计。同理,开源软件程序代码以及测试方法也可以重用。
本文第一作者在美国从事软件工程教育多年, 最近开始用开源软件进行软件工程方面的教学。起 初,对学生的要求是可以在开源软件或传统方法进 行软件开发之间进行选择,结果许多学生选择了传 统方法,而不愿意使用开源软件,原因是害怕或者 不愿意花时间去学习开源软件,而且教科书上也没 有开源软件的使用方法。所以在授课的第二年,笔 者强制要求学生必须使用开源软件。由于项目较大, 开源软件的利用使得开发时间较之前缩短了许多, 取得了不错的效果。如果项目不采用开源软件,则 几乎不可能完成任务。作为额外的要求,学生还需 要做三个星期的测试。结果大部分学生既完成了代 码,也完成了测试。他们的软件还具有不同环境下 的可扩展性(scalability)。在互联网以及大数据的环 境下,若软件没有可扩展性,则基本上不会有人使用。
在开源的环境下,通常会要求工程师必须在 很短的时间内开发大量的软件,这在以前被认定 是错误的。旧的观点认为软件开发必须耗费大量 时间才能保证质量和数量。这是30年前软件工程 之父布鲁克斯(F. Brooks)在其著名的文章《没有 银弹》中提出的,其核心思想就是软件开发非常 复杂,任何宣称能够快速发展新软件的技术都是 荒谬的。这种观念今天仍然正确。但开源软件重 点不是在于“创造”新软件,而是“重复利用” 已被开发过的软件。因为有大量的开源软件,所 以重复利用、集成大量的软件比重新开发软件效 率要高得多。表2是传统与现代两种软件开发思 想的对比。
我们曾经在课堂上讲过一个有启发的软件开发 实例 : Instagram软件 [9],它是由3个人在两年半 的时间内开发出来的,并创造了10亿美元的市价。 软件的92%使用了开源软件,自行开发的部分只占 8%。他们的原则是: (1)“永远不重新‘发明’设计 轮子”(do not re-invent the wheel)。即任何已经存在的东西,都不重新开发。如果碰到问题,就先在网 上搜寻看看有没有解答;如果有就用,如果找不到, 就到社交网络上询问那里的大师,大师们通常都乐 意解答。(2)软件要有可扩展性。他们列举了软件开 发过程中的许多重大改变都是为了满足可扩展性的 要求。(3)注重软件用户的体验。
开源软件和开源社区的反思_dotnet_03

“开源”的开源软件工程教育

我们需要一个新的软件开发环境来开展新的软 件工程教育。这个开发环境是一个为教育学生而设 计的软件搜寻工具,能够搜索开源软件,支持持续 集成,保证持续测试、持续部署。学生们可以在系 统中自由交谈,讨论设计和问题。只有通过严格测 试和检验的软件才允许被放进来。
我们还需要一个新的开源软件工程的教材。像 开源软件一样,公开的、共享的资源可以充分激励 人参与,创造价值。因此,我们可以设计“开源”的开源软件工程教材,任何人都可以参与教材的制 作。孔子曰“三人行必有我师”。在这个大数据、 云计算以及开源软件的环境中,每一个人都可以当 老师。即使是软件工程教师也并非对每个软件都了 解,事实上对于某些软件,学生可能了解得更多。 所以,那些懂得多的学生可以把知识分享给他人。 这种教育的原则是“人人为我师”。使用开源软件 案例也要经过评审。由一组专家先把样本做出来, 他们随时监督、检验所提交的教材,以保证“开源” 教材的质量。因为开源软件是在不断进步、可扩展 的,所以软件工程的材料必须能够得到持续扩展且 随时更新。
这种开源软件的教育方式还可以与国外软件公 司进行合作,一起开发。此外,中国有大量的软件 工程师、学生以及开源软件产品,如果中国师生共 同参与,“开源”的软件工程教育还能在世界产生 重大的影响。
最近出现了许多新型的教育方式和新学说,例 如慕课(MOOC)、知识地图(concept map or knowledge map)、在做项目中学习(边做边学)、群体学 习(crowd learning)和数字出版(digital publishing)[10]、 小规模在线课程(SPOC)等。这些都可以在开源的 软件工程教育上使用。在软件工程教学方面,老师 的课程并非最重要的,学生参与软件开发才是核心, 学生需要做到以下几点。
1. 在开源软件项目上学习(边做边学):传 统的软件工程是在小项目上做练习学习,这种方式 在现在的环境下需要补充加强。学生们应该在大学 时代就接触大型的、可扩展的及有质量的开源软件, 并学习开发高手是如何设计软件的。虽然不需要初 学的学生就能够开发开源软件,但是他们要学会如 何了解、寻找、使用、评估和测试开源软件。由此 出发再学会开发开源软件。
2. 在社区中学习(群体学习):在开源的社区 里需要学习如何做一个有所作为的参与者,如何和 其他人一同工作。而且在这个开源的环境中,还会 有许多外国人参加,要学会通过英语进行交流。有 问题不耻下问,向社区里的大师询问。
3. 自主学习“开源”软件材料(知识地图、 慕课、小规模在线课程和维基百科):学生可以自 主选择某些材料来学习。不过这些材料必须事先以 教学的方式组织起来,以便自学。学生们可以进行 在线讨论,听在线的讲座,在博客上交流,学习和 编写维基百科相关内容。
4. 自主发表学习材料(数字出版):学生在 自主学习后,可以把相关的资料包装成一个学习模 块,发表在开源软件工程教育社区,以便让其他老 师、学生学习。在这个社区中,允许一个题目上让 多个团队发表他们的学习材料,使用者也可以评论 和参与。
5. 在社区发表软件(数字出版):在开源社区 里发表软件是学生学习的一个重要的里程碑。学生 甚至可以创立一个新的开源软件项目。学生不只是 学习软件开发的方法,更重要的是学习开发有质量 的软件(边做边学)。传统的软件工程教给学生各 种技术,例如需求分析、设计模板、编码标准、测 试脚本以及文档编写。但是这些都聚焦在软件工程 技术而不是在软件本身。敏捷开发方式创始者的“敏 捷宣言”(Agile Manifesto)[11] 中讲到“软件才是有价 值的,而软件开发过程、软件需求、软件设计都是 创造价值的工具或者过程”。
软件工程教育的最终目的是让学生能够开发有 质量的软件,而不只是让他们明白软件工程技术。 所以,对软件工程学生的评估不能只看考试成绩, 更应该注重学生是否能在社区中开发软件,能否通 过严格的社区测试,以及用户对他们所开发软件能 否给予正面的反馈。

结论

大量的开源软件造福了许多公司,也改变了软 件工程的发展。虽然开源软件的发展是市场的自我 选择,但它也在一定程度上促成了开放、共享的软 件工程,包括软件开发、采购和应用。不仅如此, 它还改变了软件工程教育。这些都必须通过公开的、 分享的且持续不断的更新来实现。