编程新举措 - 开放项目文档基金会。
基金会的宗旨是证明软件项目文档的必要性。该文档不仅包含期望的最终软件产品的描述,还包含其开发过程的描述。基金会网站 http://is.ifmo.ru。
简洁需要设计和良好的品味。 L. Torvalds
认为程序员的作品是程序,这是错误的。程序员必须提供可信赖的解决方案,并以清晰的论据形式呈现。程序源代码只是应用这些论据的辅助材料。 E. Dijkstra
在工程实践中,“项目”意味着项目文档的开发
不久前,作者之一看到一位著名的程序员(曾两次进入ACM国际大学生程序设计竞赛世界决赛)花了15分钟试图理解一个简短的程序(6行代码)。他知道这个程序是经典“汉诺塔”问题的迭代解决方案。后来我们在互联网上找到了另一个带有相当好的算法描述的解决方案。
开源代码和程序的可理解性
事实上,开源软件并不保证程序的易理解性。巴斯夫公司(BASF Corporation)的首席分析师、新泽西州费尔利迪金森大学(Fairleigh Dickinson University)教授、www.softpanorama.org网站的作者尼古拉·别兹鲁科夫(N. Bezrukov)认为[1]:“实践编程的核心问题是源代码的理解问题。”
拥有原始源代码总是好的,但问题是,在大多数情况下,这还不够。理解任何非平凡的程序都需要额外的文档。这种需求随着源代码数量的增加呈指数级增长。代码分析以检查初始项目规范和理解程序是两个不同的编程技术分支。例如,如果你没有编译器的形式化语言定义,试着理解编译器的结构。
任何参与过大规模软件再工程项目的人,在看到一堆文档不全(但可能写得非常好)的源代码时,肯定会记得那种无助感。当无法接触到关键开发者及其想法时,源代码的可用性并没有帮助。如果一个程序是用C语言(一种相对低级的语言)编写的,并且其文档还有很多不足之处,那么整个项目的设计可能会消失在编码细节中。在这种情况下,包括规范、接口定义和架构描述在内的高级文档将增加源代码的价值!
源代码与程序理解之间的不匹配导致了统一源代码和文档的方法的出现。最著名的统一尝试之一是D. Knuth在他的著作《文学编程》(Literate Programming)[2]中所做的。计算机科学历史上最臭名昭著的盗版书籍可能是《Unix评论:带源代码》(Commentary on Unix: With Source Code)[3],其中包含对Unix操作系统源代码的高级解释,甚至包括所用算法的描述。这本书自1977年出版以来,已被非法复制和分发了二十多年!
如果你没有从项目早期阶段开始参与,那么它的复杂性和规模就会隐藏在源代码中。除非有文档或与初始开发者有联系,否则理解“古老”的代码可能是程序员最困难的任务之一。
还有另一种观点:“是否存在任何值得称赞的免费软件,其[源代码]外观不会引起厌恶?因此,尽管免费软件数量庞大,但优秀的免费软件却寥寥无几。”[4]
这种趋势的一个可能结果被伟大的俄罗斯数学家L. S. Pontryagin描述道:“只有做得好的工作才能带来快乐!如果工作做得粗糙,就会引起反感,并一点一点地培养出一个人对工作的[不道德]态度。”[5]
为什么程序不被规划?
在这里,我们可以举出三个通常在没有计划的情况下产生的例子:孩子、艺术品,不幸的是,还有软件。
所以,没有源代码的工作是糟糕的,但通常有源代码的工作也不是很好。通常缺乏文档,而文档需要详细、精细和准确。软件源代码应该作为组件包含在项目文档中。
同样重要的是要注意,文档的多少并不依赖于工作的多少。即使壁橱里的一件连衣裙也是用纸样缝制的!桥梁、道路、摩天大楼都是按照文档建造的,但软件不是。然而,在软件开发中普遍观察到的情况可以用温伯格的第二定律来描述:“如果建筑工人像程序员编写程序那样建造建筑物,那么第一只啄木鸟就会摧毁文明。”[6]
为什么有这么多关于设备和硬件的文档?这类文档易于理解,并且是为具有平均资格的专家设计的。文档允许在多年后仍然可以安装和修改设备或硬件。不幸的是,对于程序来说,这种类型的文档通常不存在。
这种情况的一个解释如下。首先,设备和硬件是为外部消费者制造的,因此缺乏文档会迫使开发人员将其产品生命周期的剩余时间用于硬件支持,但通常情况并非如此。在软件开发中,情况则不同。在大多数情况下,源代码的消费者(不是最终产品,仅仅是代码)是同一组织内的另一位开发人员。普遍的观点是,在组织内部创建高质量文档没有充分的理由。
其次,设备和硬件是“硬”的,而软件是“软”的。这意味着更改软件比更改硬件更容易。事实上,大多数程序员病态地既不读也不写文档[7]。然而,这并不意味着不需要记录软件。
实验表明,能够编写程序文档的年轻程序员很少。尽管他们在大学学习中通过了许多数学课程的考试,但他们并没有获得逻辑写作的能力。例如,在文档的不同部分,同一个对象经常被命名为“lamp”、“Lamp”、“bulb”或“Bulb”。混乱是无限的!软件开发环境有助于在编程时避免此类错误,但在编写文档时则无济于事。
程序开发也变得类似于追求利润的娱乐业。没有人关心项目的未来,特别是遥远的未来。主要 concerns 是“有利可图”还是“无利可图”,而不是“好”还是“坏”,尽管在大多数情况下,好的技术也是有利可图的。
不愿意编写文档也可能是因为,项目越封闭(无文档),作者就越不可或缺!
不幸的是,这种工作风格甚至延伸到关键系统的软件开发。程序是写出来的,但没有规划!在规划过程中,任何比CRC卡[8]或使用图[9]更复杂的技术通常被认为过于复杂而未使用。程序员总是可以拒绝使用任何技术,并以“他无法按时完成”[10]为由向其主管辩解。
结果,即使是用户也不认为错误的程序行为是不同寻常的[11]。目前社会普遍认为,大房子应该被规划和记录在案,但软件则不需要。那么为什么不问这个问题:为什么在“数字之家”等项目中,其组件以不同质量水平进行规划和记录?
在本节的结尾,我们注意到目前的情况并不是软件时代开始时就存在的,那时程序员使用大型、古老的机器。当时程序是经过深思熟虑和编写的,因为执行一次尝试可能一天才进行一次。因此,技术进步似乎导致了不那么负责任的开发者。
程序文档的优点
有了良好的项目文档,软件开发人员就不能挟持他们的经理。即使程序员被解雇,他的职位也可以由其他人填补,通常是资格和薪水较低的人。
能否在书中学会规划和实现程序?我们认为可以,但目前只有关于项目规划[11]和实现[12]的独立书籍。不幸的是,几乎没有涵盖软件开发这两个阶段的书籍。可以通过开放项目、具有开放文档的软件来弥补此类文献的不足,这些项目可以展示此类系统的优点和缺点。这类似于新型的模式[13]。项目文档使得软件的重构[14]更容易。
此类文档应特别包含程序逻辑的形式化规范,因为“没有形式化规范的事物就无法验证,因此也无法出错”[15]。“如果没有规范,就没有错误”[16]。
此外,项目文档应包含“协议”或计算序列,以帮助理解程序功能;编程理论家正形成一种观点,即一套表征程序的协议可能比源代码好得多[17]。此外,没有项目文档,面向对象编程的一个主要优点——代码重用,可能会导致问题[18]。
最重要的一点:项目文档是必要的,因为根据算法理论(Rice定理)我们知道,总的来说,仅凭源代码不可能证明任何非平凡计算算法的正确性。“非平凡”意味着存在可以证明的简单程序,但大多数程序不能。
根据图灵的说法,程序理解(与执行程序相反)需要“精明和创造力”。但是源代码分析不能自动化,并且人类分析需要大量时间。所以不可能得出任何关于程序属性的结论!
数学家们在古代通过用人类语言编写数学证明(记录证明)来解决类似问题。这种方法区分了希腊数学学派和埃及学派。在埃及学派中,例如几何任务的解决方案是以图形和解释性图例形式呈现的:“看!”这类似于仅通过源代码来理解程序。
为了让其他人能够理解程序的功能和工作方式,需要为具有平均资格的人提供详细描述。该描述必须涵盖程序的开发以及其静态和动态属性。这实际上代表了项目文档,并证明程序计算了必要的功能(即符合需求规范)。
显然,我们必须断言“项目文档”不等于“操作文档”(用户手册、软件开发工具包或类似的东西)。同样显而易见的是,软件项目文档是必不可少的。对于不同的项目,它可以是秘密的、部分开放的或开放的,但至少为了教育目的,项目文档必须是开放的。
项目文档要求
关键软件的文档可分为两部分——基本文档,应根据标准创建;额外文档,为满足客户需求而开发。其他商业项目通常根据客户要求进行文档编写。
第一类商业项目必须有良好的文档记录,但这并不总是能做到,因为在这方面经验不多,人们也不习惯这样做,除了IBM和其他一些公司。时间和预算的缺乏往往是文档记录不佳的项目的原因。客户通常只要求手册和操作指南。
非商业软件(非教育类)通常由开发人员自行决定进行文档编写。在大多数情况下,开发人员认为除了在源代码中编写注释和为函数和变量起易于理解的名称之外,没有必要对项目进行文档编写。
因此,我们面临着一种令人沮丧的局面,特别是在非商业软件与商业软件一起使用,而客户削减了文档开发的情况下。
在描述的方法中,代码应该基于文档,而不是反之。同时,文档不仅应描述产品本身,还应描述创建过程。它应该对普通计算机用户来说是清晰的,以便普通程序员经过几个小时的工作就能理解它。也希望用户能与您一起进行文档编写。这样的过程,类比于极限编程,可以称为“极限文档”。
开放项目文档基金会
其中一位作者(Anatoly Shalyto)在ACM国际大学生程序设计竞赛(圣彼得堡,2002年11月)的东北欧半决赛开幕式上宣布创建“开放项目文档基金会”。为了支持该基金会,创建了 http://is.ifmo.ru[^] 网站。
在圣彼得堡国立信息技术、机械和光学大学计算机技术系,一项特殊的教学实验开始了。学生被分成近40个小组,每组一到两人。每个小组都要使用基于状态的编程技术(基于自动机理论的编程)[19]开发某个项目。最终的系统及完整的项目文档将在 http://is.ifmo.ru[^] 的“项目”部分发布。其中许多项目已经可用。
以下是一些已完成和正在开发的项目列表
- 用于离散数学和编程教学的算法可视化概念;
- 使用Macromedia Flash实现教育动画的交互式脚本
- 用于任意科目教学和测试学生的平台(以英语课为例);
- 编译器开发理论与基于状态的编程的结合使用;
- 骨骼动画;
- 使用XML描述视频播放器的外观(项目主页:http://www.crystalplayer.com);
- 各种设备的控制系统(柴油发电机、电梯、旋转门、密码锁、自动柜员机、交通信号灯、咖啡机、电话等);
- 银行安全系统;
- 使用基于状态的编程的客户端-服务器架构;
- 使用基于状态的编程的图形用户界面;
- SMTP协议实现;
- 经典的并行问题:“射手链同步”和“哲学家晚餐问题”;
- 游戏:“Robocode”[20]、“Terrarium”、“CodeRally”、“Sea Wars”、“Lines”、“Automatic Bomber”、“One-armed Bandit”和“Bank”(“Zavalinka”)。
重要提示:在“Robocode”游戏中数百个坦克中,只有我们的坦克拥有完整的项目文档[21]。我们的“Terrarium”[22]游戏也一样。
可以合乎逻辑地假设,如果世界正在朝着开源项目发展,那么也将是广泛接受开放项目文档的时候了。这将允许我们用阅读项目文档来代替阅读源代码。
故事的结局
在我们开发一个项目(“Sea Wars”游戏)时,经过八个修正周期(这还不是记录),项目作者,计算机技术系的一名学生,开始像柴郡猫一样微笑。我们对项目质量感到满意。程序具有良好的用户界面,运行良好,并且得到了准确的文档记录。
但是,开放项目文档既有优点也有缺点。一位著名的程序员(ACM国际大学生程序设计竞赛获奖者)审阅了源代码,项目作者又开始返工。这个过程(有间断)已经持续了半年多,我们希望在这个项目中一切都会像契诃夫的故事一样完美:面孔(用户界面)、衣服(文档)、灵魂(源代码)和思想(程序的运行)。
为什么文档应该是开放的?
开放项目文档首先意味着文档应该存在,其次,它应该可供进一步使用,并可能进行进一步修改。“开放项目文档基金会”是免费的,任何人都可以支持它,但它不同于“自由软件基金会”和“开源基金会”,因为开放项目文档的思想和概念不仅可以用于免费软件,还可以用于商业软件、秘密软件和其他项目。
结论
编写高质量文档所需的大量工作使我们无法认为该基金会在软件开发“娱乐业”中被接受。这里提供的技术是困难的,但目前似乎只有简单敏捷的方法[23]才能流行。
尽管如此,编程领域仍有一些领域,如果不努力工作就无法取得成功,因此需要并喜欢具有良好项目文档的软件的新人将会出现。例如,一位学生在看到按照我们的方法编写的项目文档后说,它比电视机的文档更详细。他认为潜艇可能也是这样记录的。
即使项目文档的使用没有变得流行,它在教学意义上也是非常重要的。开发文档齐全的项目对参与者是有益的。对于那些仅仅出于认知和美学价值而浏览项目的人来说,这一点也很重要。你知道,不是所有博物馆的参观者都是艺术家。
让我们以一个关于我们方法的观点的引述来结束:“缺少开放项目文档。不幸的是,商业项目的几乎所有文档都归客户所有,他们也不急于公开。这就是互联网上实际项目数量如此之少的原因。有很多网站提供源代码,但几乎没有提供项目解决方案的。我查看了您网站上的“项目”部分(http://is.ifmo.ru[^]),并将我的解决方案与提供的解决方案进行了比较。遗憾的是,我之前无法访问这些作品。我不会花这么多时间在项目规划和开发上!”[24]
最后,我们想指出,本文反映了近几年的一个趋势:软件开发似乎正在成熟——从艺术通过科学[25, 26]转变为工程手艺[27, 28]。
飞机先驱之一 D. Douglas 曾说过——“当文档的重量等于飞机的重量时,它就可以飞行了”,而 A. Martin 声称,著名的波音747的文档比飞机本身还要重。同样的观点也适用于软件开发。没有适当的文档,开发过程就会失控。电子格式的文档减轻了文档的重量,但这并没有改变事实。
这项研究得到了俄罗斯基础科学基金会的支持(项目号 02-07-90114,“自动化编程开发技术”)。
本文的材料将在Linux Summit 2004上报告(http://www.linuxsummit.org/summit2004_program.shtml)。
参考文献
- Bezrukov N. Reiterated Look at “Council” and “Market” // BYTE/Russia. 2000. № 8.
- Knuth D., Literate Programming. Stanford: Center for the Study of Language and Information, 1992.
- Lions J., Commentary on UNIX: With Source Code. Annabooks, 1977.
- Protasov P., From Below // Computerra. 2003. № 19.
- Researcher of “Steering Wheel” // Informatics. 2003. № 11.
- Bloch A., Murphy's Law // ECO. 1983. № 1-3.
- Demin V., Problems of Working of Russian Developers on the West // PC Week/Russian Edition. 2001. № 32.
- Badd T., Object-oriented Programming. SPb.: Piter, 1997.
- Booch T., Rambo D., Jacobson A., UML. Users Manual. M.: DMK, 2000.
- Fowler M., New Methods of Programming // http://www.spin.org.ua.
- Booch G., Future Creation // Open Systems (Otkrytye sistemy). 2001. № 12.
- Stroustrup B., The C++ Programming Language. M.: Binomial (Binom), Addison-Wesley, 2000.
- Gamma E., Helm R., Johnson R., Vlissidis J., Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley, 1995.
- Fowler M., Beck K., Brant J., Opdyke W., Roberts D., Refactoring: Improving the Design of Existing Code. Addison-Wesley, 1999.
- Zaitsev S., Description and Implementation of Computer Nets Protocols. M.: Science (Nauka), 1989.
- Allen E., Bug Patterns in Java. APress, 2002.
- Ershov A., Mixed Computations // In the World of Science (V mire nauki). 1984. № 6.
- Telles M.A., Telles M., Hsieh U., The Science of Debugging. The Coriolis Group, 2001.
- Shalyto A., Tukkel N., Programming with explicit state separation // World of PC (Mir PK). 2001, vol. 8, 9. http://is.ifmo.ru (section “Articles”).
- Shalyto A., Tukkel N., Tanks and Automata // BYTE/Russia. 2003. № 2. http://is.ifmo.ru (section “Articles”).
- Ozerov A., Four Tankmen and the Computer // Magic of PC (Magia PK). 2002. № 11. http://is.ifmo.ru (section “About Us”).
- Markov S., Shalyto A., Controlling System for Herbivorous Animal for “Terrarium” Game. http://is.ifmo.ru (section “Project”).
- Cockburn A., Agile Software Development. NJ: Addison-Wesley, 2001.
- Trofimov S., E-mail: info@caseclub.ru.
- Knuth D., The Art of Computer Programming. MA: Addison-Wesley, 1998.
- Kazakov M., Korneev G., Shalyto A., Using Finite Automata in Developing Logic of Algorithm Visualizers // Telecommunication and Informatization of Education. 2003, vol.6, http://is.ifmo.ru (section “Articles”)
- Sommervill I., Software Engineering MA: Addison-Wesley, 2001.
- Braude E.J., Software Engineering: An Object Oriented Perspective. NY: John Wiley&Sons, 2001.
- Fox J., Software and its Development. Englewood Cliffs. Prentice-Hall, 1982.