XP 还拥有其它优秀的实践,本文讨论了 XP 的另外三个实践,并研究如何在项目中灵活的使用它们。
代码集体所有权
XP提倡代码归属集体所有,这样做的理由是每个人都可以修改代码,而不是等待别人来修改代码。这种做法可以有效避免形成代码之间的鸿沟。但集体代码所有权也它的问题。
我们尝试了由多人共享代码的做法,其目的是为了加强交流,避免出现一段代码只有一个人了解的情况。这种方法一开始工作的很好,但很快我们发现出现了很多的问题,类的定义变得不清晰了,某些类变得臃肿,我们闻到了"Large
Class"的味道。更为糟糕的是,这些类的清理和重构相当的困难,因为这些类的客户太多了。正是因为这些类被广泛的使用,因此大家都对其进行修改和扩充,导致了代码的混乱。于是,我们加大了重构的力度,对这些类不断的进行审查和重构,但是新的问题又出现了,很难找到一个平衡点,既能够保持团队的敏捷性,又保证类的高度可用性。更糟糕的是,不同的人对这些类有着不同的了解和期望,导致了这些类的设计风格有些怪异。
在本文中,我们不只一次的强调过,XP中所有的实践是配合使用的。项目中采用集体代码所有权不是不行,但有前提。在上面的例子中,我们至少犯了几个错误:
-
没有考虑到团队成员之间配合的默契程度。只有团队成员之间知识程度相近,或是具有相近的思维观,例如都熟悉面向对象,都熟悉设计模式。这样他们才能够共同保证代码的质量。在项目中,我们尝试了一种新的做法,将集体所有权的范围缩小到组,这个组由三到四个资深的开发人员组成,称为核心组,负责构建基础的框架。这个组之间采用高效的共享代码机制。其他的开发人员利用核心组的成果进行工作,他们并不修改核心代码,但可以提供修改意见。
-
忽视了代码质量。不同人修改代码要比单人修改代码更容易导致代码质量的下降。必须考虑这个成本,并找出恢复代码质量的办法。审查是非常有效的手段,FDD(Feature
Driven Development
特征驱动开发)方法就非常强调审查在项目中的作用。只要成本能够接受,再多的审查都是不过分的。
-
代码标准化。这里说的代码标准化不仅仅指代码规范。还包括代码是不是具有可读性,代码的结构是否足够的清晰。这些都可能导致团队集体拥有代码时形成混乱。
此外,还应该注意到集体代码要求能够频繁的集成代码。代码必须要快速的同步和集成,共享代码往往意味着同一个包,同一个类都有可能被同时修改。这样大大增加了引入bug的可能。尽快的同步代码时非常有必要的。
如果一个软件组织不能够解决这些问题,冒然采用集体代码所有权的实践是比较危险的。相反,可以考虑采用个人代码所有权,或是微团队代码所有权。前者说的是个人对个人的代码负责,后者说的是两到四个人对某部分代码负责。
不论是个人代码所有权还是微团队代码所有权,其立足的根本是有明确的开发人员对代码负责,他保证代码的统一设计思路和风格,负责代码的客户端接口,负责维护和改进代码,负责代码的相关文档,负责解释代码的运行机理。个人代码所有权是最清晰的做法,但其坏处和集体所有权正好相反。某个人的代码可能造成进度的瓶颈,任何一个人离开团队都会造成损失。
个人代码所有权很容易理解,但微团队代码所有权就需要特别做解释了。他的组织思路非常类似于我们在结对编程中提倡的组织风格:
不同的人负责不同的代码,人员之间形成交叉。这样的组织比较灵活,和结对编程有着异曲同工之妙。
持续集成
在Martin
Fowler的持续集成(在Agilechina网站上可以找到该文的中文译本)一文中,对持续继承有着这样的描述:
在软件开发的领域里有各种各样的"最佳实践",它们经常被人们谈起,但是似乎很少有真正得到实现的。这些实践最基本、最有价值的就是:都有一个完全自动化的创建、测试过程,让开发团队可以每天多次创建他们的软件。"日创建"也是人们经常讨论的一个观点,McConnell在他的《快速软件开发》中将日创建作为一个最佳实践来推荐,同时日创建也是微软很出名的一项开发方法。但是,我们更支持XP社群的观点:日创建只是最低要求。一个完全自动化的过程让你可以每天完成多次创建,这是可以做到的,也是完全值得的。
和本文提到的其它实践一样,持续集成的主要思路是将软件过程末期的软件继承分摊到软件的全过程。虽然没有办法评判两种持续方式的成本,但是持续集成可以获得很多额外的好处。单次集成最要命的地方是除bug的过程,尤其是那些隐藏的很深,让人觉得无从下手的bug。如果说写代码是一种享受,那修复bug的过程绝对是一种煎熬。在这个过程中花费的时间有时候是惊人的,更糟糕的问题是,这部分的时间根本无法估计,这令项目管理者头疼不已。向编码者询问进度时得到的回复永远都是"还差一点儿"。
持续集成避免了这种尴尬处境,由于间隔的时间很短,集成中出现的问题可以很轻易的发现。即便无法定位错误,最差的情况也可以不把代码集成到软件中。这样,软件的质量就会比较高。此外,持续集成的另一个重要任务是运行自动化测试,保证所有的代码都是经过测试的,没有发生问题的。这里的测试源自于单元测试,在本文的测试一章,可以找到更为详细的讨论。
对一些没有持续集成经验的团队来说,持续集成像是一块吊的很高的饼,看得见却摸不着。要做好持续继承并不容易,但我们可以使用持续集成的思路,来接近持续集成的目标。
持续集成最好的做法是自动化的构建和测试。这要求软件组织拥有很好的配置管理机制,以及丰富的测试脚本编写经验。对于一个企业应用软件来说(抱歉,我只有这方面的经验),软件设计包括很多的因素,要把这些因素都考虑到持续集成的过程中并不是一件容易的事情。因此很多组织都可能缺少这两个因素,但没有关系,我们可以利用半手工的方式来完成持续集成,然后再慢慢的将持续集成的过程自动化。这里提供一个半自动持续集成的思路和改进过程。
首先是定义职责。如果你采用了代码非集体所有权的形式,那么,请明确的指定各个类或包(对于面向过程语言来说是函数和模块)的负责团队(或个人)。同样,你还需要指定数据库模式的负责人。这些代码之间可能会有交叉的地方,但没有关系,只要保证沟通,少量的交叉职责没什么特别的。最好还必须指定一个专门负责持续集成的人,可以让项目中的不同人交替担任该职责。
其次是定义自动化代码。所有的测试都必须写成测试代码的形式,并能够运行。所有的数据库模式定义也必须编写为DDL的形式,而不是使用数据库工具。千万别偷这个懒。总的原则是,能够写成代码的都写成代码,只有代码才是可以执行的。我承认,工作量是很大的,但这是必须的。
再次是定义集成的频度。频度的制定取决于团队的规模和沟通质量。对于小的团队而言,一小时一次的集成也是可行的。对于大的项目,可以划分子团队,子团队中采用频繁集成(一小时一次),子团队之间采用日集成(每天集成一次)。有了子团队的集成保证,整个团队的集成一般不会有什么问题。
接下来是使用工具。最需要的是版本控制工具,可以选用正式的,例如ClearCase。也可以选用简单的,例如SourceSafe,还可以选用免费的(CVS)。都没有关系,关键在于是否合用。代码和文档的集成都通过这个工具,数据库的集成则通过数据库管理员(就是第一步指定的负责数据库模式的人)。而集成负责人负责协调集成过程,保证集成的成功。
最后是发现问题,这只是一个开始,你在集成的过程一定会遇到各种各样的问题的。例如集成的时间,数据的相关性,设计的耦合度,测试代码的变化等。没有关系,这里存在一个自适应的过程。一开始的持续集成过程一定是错误百出的,慢慢的就会稳定下来,这时候就是改进的时候了,改进的主要目标始终都是过程自动化。有时候,为了保证集成的质量,我们要求出现错误的人请吃冰淇淋,不要笑,这也是过程的一部分,实践证明,这可是非常有效的,所有人在提交代码之前都会很认真的保证测试成功。
代码标准
代码标准是非常基础的管理常识。但是我们这里并不打算再赘述代码标准的问题。我们将重点讨论开发标准。开发标准包括各种各样的标准。例如过程的标志、文档的标准、设计模型的标准、代码风格的标准、变量命名的标准、大小写标准等等。在XP中,其实并不非常强调标准,因为XP提倡简单的做法,但有时候标准往往是违背这一准则的,因为它会带来额外的标准化成本。而重量级方法之所以笨重,过分遵循标准正是一大原因。
但在实际的过程中,我认为宁可多投入一些资源在标准制定的执行上。这和国内目前的软件开发实际情况有关系。国外的轻量级方法出现在重量级方法之后,大部分的程序员都经历过强制性的标准化过程。但是国内不同,虽然轻量级方法很好,但是理解或执行不当的话,却常常导致画虎不成反类犬的后果。国内很多软件组织的开发过程仍然处于无序的状态,而开发人员也鲜有标准过程的经验,在这样一种情况下,盲目的推崇敏捷的做法,其实骨子里仍然是一种混沌的状态。
因此,标准的制定和执行总是值得的,虽然会需要一定的成本,但这个成本同它的带来的改善沟通、促进积累等效益比起来不算什么。
但是标准的制定绝对不是要把程序员上洗手间的时间都规范起来,如何保持标准的平衡是敏捷方法的重点。XP认为代码规范就已经足够了。但我认为至少还有几种标准是需要重视的:
文档标准:这是一个大的话题,最好的文档标准是UML。一幅图胜过千言万语。当UML2.0出世之后,UML将会越来越强大。因此,使用UML来代替部分的文档是必要的。UML的相关资料有很多,这里不做过多的讨论,但关于UML的一句忠告是,不要试图在一开始就利用UML的所有类型的图,也不要一开始就利用UML所有特性。这种做法,和摆弄文字处理器的特性,与不写文档的做法没啥区别。
设计标准:同样是一个大的话题。设计标准包括如何进行设计,如何表示设计,如何设计架构,如何设计各个层次等等问题。在一个组织中贯彻设计标准是一个长期的过程。但仍然是那句话,做总是比不做的好。
代码风格标准:XP非常看中代码的可读性,代码可读性好代表了程序员的水平,设计人员的努力。提高代码可读性的最佳实践是重构和复审,这两项实践在本文的其它位置都有详细的讨论。
界面标准:界面标准有时候只是一个很小的问题,但对于现代的软件来说,界面正扮演越来越重要的角色。而在软工领域,优秀界面的关键是一致性。同样的按钮必须有同样的大小、位置和字体。制定一份界面标准是非常关键的。
如何制定标准:标准的制定其实并不需要大量的说明文档,这些文档晦涩难懂,也不会有多少人会看,就算看了也未必会懂。只能是浪费时间。最好的方式是示例和培训。文档标准的说明就编写一份文档范例,并加以简短的说明。再辅以面对面的讲解,其效果要远远超过说明文档。
参考资料
- Martin Fowler and K. Scott, UML Distilled: A Brief
Guide to the Standard Object Modeling Language,
Addison-Wesley, 1997.
中文版:《UML精粹--标准对象建模语言简明指南》,徐家福译,清华大学出版社,2002 年6 月。
- Martin Fowler, Refactoring: Improving the Design of
Existing Code, Addison-Wesley, 1999.
- Joshua, Kerievsky Refactoring To Patterns, 2002.
- Gamma, E. Helm, R. Johnson and J. Vlissides, Design
Patterns: Elements of Reusable Object-Oriented Software,
Addison-Wesley, 1995.
中文版:《设计模式:可复用面向对象软件的基础》,李英军等译,机械工业出版社,2000 年9 月。
- Deepak Alur, John Crupi, Dan Malks, Core J2EE
Patterns: Best Practices and Design Strategies, Prentice
Hall PTR, 2001. 中文版:《J2EE核心模式》 牛志奇等译,机械工业出版社,2002年。
- Stephen R.Palmer,John M.Felsing, A Practical Guide
to Feature-Driven Development, Prentice Hall PTR, 2001.
中文版:《特征驱动开发方法原理与实践》 Stephen R.Palmer, John M.Felsing
熊焕宇译,机械工业出版社 2003年4月。
- Ken Auer,Roy Miller, Extreme Programming
Applied:Playing to Win, Addison-Wesley, 2001.
中文版:《应用极限编程--积极求胜》, 唐东铭译,人民邮电出版社,2003年4月。
- William C. Wake, Extreme Programming Explored,
Pearson Education, 2001. 中文版:《探索极限编程》,
郑荣林译,人民邮电出版社,2002年6月。
- Kent Beck,Martin Fowler, Planning Extreme
Programming, Pearson Education, 2001. 中文版:《规划极限编程》,
曹济译,人民邮电出版社,2002年6月。
- Giancarlo Succi, Michele Marchesi, Extreme
Programming Examined, Pearson Education, 2001.
中文版:《极限编程研究》, 张辉译,人民邮电出版社,2002年6月。
- Kent Beck, Extreme Programming Explained:embrace
change, 2001. 中文版:《解析极限编程-拥抱变化》, 唐东铭,人民邮电出版社,2002年6月。
- Ron Jeffries,Ann Anderson,Chet Hendrickson, Extreme
Programming Installed, Pearson Education, 2001.
中文版:《极限编程实施》, 袁国忠译,人民邮电出版社,2002年6月。
作者简介
林星,辰讯软件工作室项目管理组资深项目经理,有多年项目实施经验。辰讯软件工作室致力于先进软件思想、软件技术的应用,主要的研究方向在于软件过程思想、Linux集群技术、OO技术和软件工厂模式。您可以通过电子邮件
iamlinx@21cn.com
和他联系。 |
|