<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>冰云</title>
    <description>Thought[b]Works[/b] China 商务分析师</description>
    <link>http://icecloud.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>敏捷团队建设</title>
        <author>冰云</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://icecloud.javaeye.com">冰云</a>&nbsp;
          链接：<a href="http://icecloud.javaeye.com/blog/90821" style="color:red;">http://icecloud.javaeye.com/blog/90821</a>&nbsp;
          发表时间: 2007年06月15日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          刚写好的时候本来尝试发javaeye，结果那天好像服务器有问题没提交上来。这么多天才想起来重新发。。。<br />
<br />
--------------------------<br />
<br />
敏捷团队建设 本文发表于4月《软件世界》<br />
<br />
最近很多人都问我，有没有适合的人可以推荐给他们公司，他们正在招人，面试了很多个，但有经验的开发人员太难找了。有一个朋友在问我要人的同时，他手下的一个开发人员反而问我有没有好的机会，他想跳槽。<br />
<br />
不久前一份报告称，中国本地软件企业面临的最大问题之一，就是高级技术人才的缺乏。造成这种问题的原因，主要是由于本地软件企业的人才培养机制和管理机制的欠缺。人才大量涌入外资企业和频繁的流动，导致了各类有经验人才的欠缺。<br />
<br />
每个人都会梦想自己的理想工作。做技术的开发人员要求的更是简单：一个能够不断学到新知识和新技能的职位，一个融洽的团队，一个舒适宽松的开发环境，一份成长的空间。而这些简单的需要，恰恰是许多公司所忽视的地方。这些东西，很多时候就是一个人决定离职的因素。<br />
<br />
有的公司认为开发团队是成本中心，所以给他们买最便宜的桌椅&mdash;&mdash;而恰恰是开发人员们一天都依赖于这样的桌椅为公司创造价值；有的公司觉得自己的一套软件不停的实施就能不停盈利&mdash;&mdash;而开发人员最厌烦的就是做重复性工作；有的公司要求开发人员必须上班打卡&mdash;&mdash;好的，那开发人员绝对不会晚下班一分钟。有的公司从来不举行内部的技术交流和培训活动&mdash;&mdash;而开发人员希望的技术提高绝不仅仅是只靠读书能够完成的。<br />
<br />
公司要依靠软件来盈利。而要开发一个成功的软件项目，人的作用是第一位的。而个人的力量相对于整个团队来说，又是微不足道的。稍微有点规模项目的成功都是集体努力的结果，而不是靠一两个英雄程序员能够完成的。为了能够保持一个稳定和高效的团队，建设一个吸引开发人员的环境和氛围是所有公司的管理人员们应该考虑的一件事。一个核心的产品开发人员离职，很可能使得当前的项目或订单陷入瘫痪，这目前已经成为了影响许多中小公司存亡的大事。<br />
<br />
我所在的公司不仅仅以敏捷过程著称，同时，它以其特有的文化和团队氛围吸引了一大批高水平的开发人员。他们不仅仅是认同敏捷而聚在一起，更多的是，他们向往着这种平等、自由、轻松、快乐的空气。<br />
<br />
人与团队<br />
<br />
在公司一个典型的敏捷团队中，大致有四种不同角色：项目经理、业务分析师、开发工程师、测试工程师。同时，根据项目不同可能还需要：美术设计师、数据库工程师、系统工程师、交互设计师等不同人员。虽然在项目中不同的人需要确定一个角色，并担负相应的责任，但在公司内部，人与人之间是完全平等没有级别区分的。这种平等的文化，就使得人与人之间的交流不会因为等级差距而丧失。同时公司鼓励每个人向其感兴趣的其他领域发展，成为综合性人才。例如某个人现在是开发人员，但他也可以通过帮助项目经理做一些辅助工作，来学习项目管理方法，从而最终成为独当一面的项目经理。<br />
<br />
项目成功的一个重要因素就是交流。保障团队内外顺利交流是项目经理的责任之一。公司鼓励员工之间交流看法和讨论问题。在公司内部，如果有闲暇时间，随时可安排一场讲座。这些讲座都是由员工自发组织和自愿开展，话题多种多样，不仅仅限于技术。经济、法律、业务知识等等，都是大家平时感兴趣的领域。在项目中，定期的Learning Lunch也是公司项目的一大特色。和客户一起围坐在餐桌前，边享受公司提供的午餐边讨论项目中的技术，团队的学习交流气氛自然会无限高涨。<br />
<br />
除了自发的、自由的交流，还有一些约定的交流时间和形式，例如，每天的站立会议。你要说出昨天做了些什么，今天会做些什么，遇到了什么困难是否需要别人的帮助。站立会议鼓励每个人说出事情的真相。有了困难就大胆的向你最值得信任的同伴来寻求帮助，没有人会嘲笑你，也没有人会冷漠的不去理睬你的困境。一个自组织的团队，应当是一个温馨而又和谐的集体。每个人都会努力的帮助其他的人，帮他解决他的问题并从中积累更多的经验。<br />
<br />
图略：站立会议<br />
<br />
无论是在项目中还是在个人的发展过程中，回顾与总结都是一个必不可缺的步骤。公司内部任何事情告一段落的时候都会有一个总结活动。迭代总结，项目总结，发布总结，陪训总结等。在这段时间内什么做的好，什么做的不好，如何进行改进。任何的过程和成绩都不能是静止不变的。只有不断的反省和总结，才能够在未来的发展中进一步提高。项目团队一起召开总结会议活动，在这个活动中，任何人不能够对其他人进行指责和攻击，一切都应该以互相信任为基础，我们的目的是提高下次的工作效率和增强同伴的信心，而不是批斗和推卸责任。公司对员工的绩效考核，也是类似的由一起工作过的同伴来进行评价，360度全方位考核。这种定期的总结和回顾，提供给了员工与团队自我成长的机会。<br />
<br />
除了内部的交流，公司还鼓励员工进行技术创新和参与其他社会活动，例如参与开源软件开发、撰写书籍、向杂志投稿、参加和举办技术社群活动等。这些对技术社区的贡献，不仅仅能够提高员工个人的能力，同时还展现了公司员工的整体能力和提升了公司的知名度。对公司和个人来说是双赢。<br />
<br />
环境与工具<br />
<br />
如果你有机会到我们的办公室，你就会发现，每一张墙都被占得满满的。墙上可能会贴满了各种颜色的小卡片，这些都是正在进行的项目的需求。每张卡片都是一条用户故事，开发人员根据用户故事实现系统功能。这种被贴在墙上的一目了然的管理方法叫做可视化管理。在公司内部，开发、招聘、销售等各种流程的状态都被一一列在墙上。一来可以作为工作的进展图公示于众，二来可以使每个感兴趣的人都可以随时提出他的想法或主意，集思广益，将工作做到最好。<br />
<br />
图略：墙面<br />
<br />
公司采用大长桌作为开发用桌。座位之间没有隔板。一方面适合与敏捷开发中的结对编程实践，另一方面可以减少隔板带来的交流障碍。如果你到一个采用隔板的公司去走一圈，再来比较公司的工作环境，就会明显的感受到交流频度和广度的明显不同。公司提供给开发人员舒适的座椅，带有扶手并可以调节高度和后仰角度，以适合每个人不同的需要。如果中午工作累了，还可以躺在椅子上小憩一会养足精神以便下午更好的投入到工作中。<br />
<br />
图略 开发桌椅<br />
<br />
在项目中，必不可缺的交流工具是白板和纸。再没有比这更廉价和更好用的工具了。两个开发人员遇到了分歧，两人走到白板前写写画画，很快，一副清晰的系统脉络就出现在两人面前。分歧达成了一致，开发继续进行，而图像留在白板上，任何过路的程序员都可以驻足观看，如果感兴趣还可以问一问作者，更深入的探讨。在开发的过程中，随时遇到问题或需要记录的，都可以立即写在手头的白纸上，一些简单的算法草稿，也都是用白纸完成。这些白纸多是打印用过一面的纸张，环保而又经济。<br />
<br />
我公司和其他大多数外企公司一样，为员工提供免费的饮料和零食。每天早上，公司的面包机都会工作个不停，烤面包的香气会和着咖啡的味道飘扬在空气中。午饭后，从冰箱中拿出一罐健怡可乐，冰凉爽口，喝下后休息一下就可以精神十足的开展下午的工作。下午四五点钟，正是开始感到饿的时候，到零食区找一块巧克力吃补充一下体力，顺便休息几分钟，活动一下筋骨。<br />
<br />
图略 饮料零食区<br />
<br />
公司还在办公室内放了一台电视机和一台PS2，午饭后和下班后，你可以和同事相约PK一场实况足球，既休息了神经，又和同事加深了感情。公司还经常组织各种体育活动。每周租一次羽毛球场，让长期在电脑前工作的员工运动运动，有助于身体健康。<br />
<br />
以上这些是我公司在团队文化建设的一些做法，提出这些供大家参考，希望更多的公司管理人员，能够从中或多或少的汲取一些经验，将之用于提高公司开发人员的物理和人文环境。<br />
<br />
改造公司的开发环境，可以先从很简单的做起，例如，在办公室的一角开辟一处饮食区，提供免费的饮料和食品；在走廊上挂一个白板，随时有人记录一些东西；为员工提供更舒适的座椅。这些东西花不了多少成本，但其收效是明显的。不论是技术部门还是其他部门，都会为公司这一点点人性化的举动感到高兴。有了高昂的士气，做事情自然也会更加积极高效。不需要公司一下子全部改变，但往往一点点的细节变化就能够获得全体人员的支持。虽然有些投资，但员工给公司的回报会更多。<br />
<br />
无论是敏捷开发理论还是精益管理理论中，都提到团队的作用是最重要的。如果能够发挥人的能动作用，并良好的保持下去。我想，没有什么目标是我们完不成的。如果所有的公司都能够提供良好的环境给开发人员，那不仅仅是开发人员的的幸事，更是我们整个中国IT界的一大幸事了。
          <br/>
          <span style="color:red;">
            <a href="http://icecloud.javaeye.com/blog/90821#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 15 Jun 2007 21:15:58 +0800</pubDate>
        <link>http://icecloud.javaeye.com/blog/90821</link>
        <guid>http://icecloud.javaeye.com/blog/90821</guid>
      </item>
      <item>
        <title>异地分布式敏捷软件开发</title>
        <author>冰云</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://icecloud.javaeye.com">冰云</a>&nbsp;
          链接：<a href="http://icecloud.javaeye.com/blog/90820" style="color:red;">http://icecloud.javaeye.com/blog/90820</a>&nbsp;
          发表时间: 2007年06月15日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><strong>异地分布式敏捷软件开发 (Distributed Agile Software Development)</strong></p>
<p>异地分布式软件开发（<a href="http://en.wikipedia.org/wiki/Distributed_development" target="_blank">Distributed Software Development</a>）是指由多个位于不同地理位置的团队进行同一个软件项目的开发过程。这个词越来越频繁的出现在各种技术媒体中。</p>
<p>异地分布式软件开发不同于外包，它建立在平等关系的两个团队之间。通常是一个公司的不同分公司或办公室间的协作，他们之间大多不存在博弈的合同关系。而外包是指一个公司将其软件系统的开发委托给另一个公司或组织完成。二者之间是合同的甲乙方关系。</p>
<p>但无论是异地分布式软件开发或是外包，可以接触到实际客户的一端一般称为on-site，另一端可相应的称为off-site，他们可以根据地理位 置分为三类：on-shore（在岸，指在同一个国家或同一个时区内），near-Shore（近岸，在接近的国家和地区中）和off-Shore（离 岸，通常在时差8小时以上）。如下表。</p>
<table cellspacing="1" border="1" style="border: 1px solid black; font-size: 100%;">
    <tbody>
        <tr>
            <td>offsite</td>
            <td>on shore</td>
            <td>near shore</td>
            <td>off shore</td>
        </tr>
        <tr>
            <td>Distributed Development</td>
            <td>北京办公室 - 西安办公室之间</td>
            <td>印度分公司 - 中国分公司</td>
            <td>硅谷总公司 - 中国或印度分公司</td>
        </tr>
        <tr>
            <td>Outsourcing<br />
            Development</td>
            <td>北京某公司 &ndash; 广州另一公司</td>
            <td>东京某公司 - 大连另一公司</td>
            <td>欧洲某公司 - 中国另一公司</td>
        </tr>
    </tbody>
</table>
<p><strong>异地分布式开发的组织方式</strong></p>
<p>异地分布开发的组织方式有很多种。最常见的一种是公司将完整的团队组织结构分布在两地，每个团队都有本地项目经理，需求分析师，开发者以及测试。同时公司设定项目总负责人角色，负责两地的沟通与协调。</p>
<p><img src="http://blog.nona.name/wp-content/uploads/2007/teamorg2.jpg" alt="" /></p>
<p>有的公司将需求分析人员放在on-site一端，开发者、测试人员和项目经理在off-site一方，同时在本地也保持常规的需求分析师。也有公司将测试人员和开发人员分放在不同地方，一方面开发，另一方面利用时差，在夜间测试并在第二天及时反馈测试结果。</p>
<p><img src="http://blog.nona.name/wp-content/uploads/2007/teamorg1.jpg" height="247" alt="" width="497" /></p>
<p>各种组织方式都有其不同的适用场合。然而他们的共同点在于，都是注重<a href="http://en.wikipedia.org/wiki/Micromanagement" target="_blank">micro-management</a>，即加强在本地团队中项目管理和协调，而不是由一个人同时直接管理两地的活动。同时，也尽量保证团队两边都具有项目协调人、本地项目经理、需求分析师等辅助角色。</p>
<p><strong>基本原则：极尽交流之能事</strong></p>
<p>异地分布软件开发面临的最大问题是交流问题。随着人员距离的增加，交流效率将大大降低（参见<a href="http://danbunea.blogspot.com/2005/11/problem-of-communication.html" target="_blank">Alistair Cockburn的文章</a>），同时交流成本将极大提高。很多时候on-site一端团队不能把正确的需求传递到off-site一端，这直接造成产品质量的下降。</p>
<p>为了使避免这种情况，应尽量采用一切手段来提高交流的效果。例如，项目经理和团队成员都需要了解其他人的工作状态，一个技巧是可以将你的MSN或Y!名称后缀写上你在做哪一块的需求。并可以随时和同事通过IM进行交流。</p>
<p><img src="http://blog.nona.name/wp-content/uploads/2007/comm-value.jpg" alt="" /></p>
<p>交流频度和价值图，Vincent Massol，2004</p>
<p>每天的定时会议将成为很重要的一个很重要的交流方式。如果团队的人数较少，大家可以按照站立会议的方式在电话会议系统中说明自己的情况和遇到的问 题。如果人数较多，一种可替代的方式是每个团队自己进行每日例会，并由个项目的项目经理和需求分析人员进行另外的会议以便协调工作。</p>
<p>如果两个团队时差较大，例如中国北京时间和美国东部时间时差12-3小时，想要进行直接的电话会议交流很困难。如果遇到3个处于不同时区的团队，更 是经常不可能找到一个合适的时间来进行任何的会议。在国际化的公司中，起早贪黑的进行几地的电话会议很常见，但这却不适用于整个开发团队。对这种情况，每 日的开发状态邮件是很有用的。每日开发结束后由项目经理或成员来根据团队的情况来撰写一天的总结，并发送给远端的团队。</p>
<p>交流的障碍经常发生在陌生人之中，如果两地的开发人员互不熟悉，可以考虑将双方人员的照片贴在墙上，以增加熟悉感。可行的话，进行可视会议和当面的会谈。尽量减少陌生感，使交流效果提升。</p>
<p>任何交流方式都比不上面对面的交流。异地开发时，off-site一端很容易丢失on-site一端与客户交流的语义上下文和环境。如果情况允许， 公司应该设立常规的出差和轮换制度。让一部分的团队成员到另一端，见一见一起工作的同事，了解一下客户的需求和感受一下不同的环境。</p>
<p><strong>敏捷开发过程的改进</strong></p>
<p>般的敏捷过程中，都会有一个初始阶段，在这个阶段了解开发需求和制定发布计划。要进行这样的活动，最理想的办法是让所有人都出差到on-site一 端，一起了解需求和建立共识。这将会对后面的开发有很大帮助。如果由于人数或成本不可行，至少要派遣所有的需求分析师和项目经理、协调人以及部分测试人员 到场参与。对于迭代一级的计划，应该由两地的项目经理和需求分析师提前进行计划会议并做出决定。</p>
<p>日常的项目管理工作中，采用卡片墙的方式只适用in-house的开发。在异地开发中，为了使得每个团队都可以了解到团队任务，至少需要在两边开发室都设立卡片墙，并保持同步。可以采用在线工具帮助进行项目跟踪，例如<a href="http://studios.thoughtworks.com/mingle" target="_blank">Mingle</a>或<a href="http://trac.edgewall.org/" target="_blank">Trac</a>，都是适用的在线工具，同时也是在线Wiki或共享知识库。</p>
<p>项目协调人，应当制定完善的交流计划和交流机制。例如前文提到的每日的例会和每日开发状态邮件，每周的需求交流计划，问题的提出和反应机制等等。这些应当制定成为团队守则来遵循，并随着实际情况的变化修订。交流不怕多，只怕不充分。</p>
<p>一个共享的代码版本控制系统是必须的。例如在公司内网建立一个SVN并通过VPN来使用。On-site和off-site团队可建立自己单独的持 续集成环境，但需要保持系统环境的一致。两方的开发人员都应该保证每日离开办公室前的提交通过集成。这样可以避免异地团队开始开发不至于被失败的集成所耽 搁。</p>
<p>基本的敏捷时间必不可缺，例如测试，尤其是功能测试。On-site的QA应当在需求确定的时候制定好验收条件。一个描写良好的验收条件会对开发人员有所帮助。尤其是在On-site一端不能及时解答问题的时候，会起到很大的作用。</p>
<p>每个迭代结束时，应尽量安排一个两地同步的演示会议。让所有人都在电话会议上看到这个迭代的成果。迭代后的总结与回顾也应当两地一起进行，如果人数和条件不允许，可以分别进行，并互相通报回顾结果和改进方法。</p>
<p><strong>离岸团队的参与度</strong></p>
<p>多团队中，处于on-site的成员由于可以接触到客户，他们的话语权可能会被放大，使得on-site一边的人倾向于命令式的消息传递，直接指派 需求和开发进度，而忽视了对需求背景情况和上下文进行介绍。这种情况可能造成off-site一端团队产生抵触心里，从而导致项目的失败。</p>
<p>解决方法是提高off-site团队的参与度。如制度性的进行人员轮换，让两端的团队成员有所接触，并互相熟识。定期组织两个团队的共同活动。如果 都处于一个时区，可以考虑进行每周的Learning Lunch，大家在互相能看到视频的情况下一起吃饭和听讲座。讲座内容可以是任何话题，例如一些项目相关的技术决策等等。</p>
<p>不要忽视offsite团队的任何意见和建议，他们在很多时候能从另一个侧面对项目提出见解。鼓励offsite团队决策和发起讨论，这样可以提高他们的参与度。</p>
<p>实施异地开发的最初目的是为了降低人力成本和运营成本，一些跨时区的异地开发还可以提高时间利用效率，实现全球24小时开发。然而，异地开发带来了高昂的交流和管理成本，如果处理不当将直接导致项目或产品的失败。</p>
<p>近年来随着国内软件公司业务的发展，异地开发项目将会越来越多。全球化的进程也会使得外国公司开展更多类似的开发。异地开发项目将会逐渐发展和普遍。可以想像，多年以后，如果一个公司没有异地开发的团队，将会是多么的令人诧异。</p>
          <br/>
          <span style="color:red;">
            <a href="http://icecloud.javaeye.com/blog/90820#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 15 Jun 2007 21:14:56 +0800</pubDate>
        <link>http://icecloud.javaeye.com/blog/90820</link>
        <guid>http://icecloud.javaeye.com/blog/90820</guid>
      </item>
      <item>
        <title>敏捷界面重构</title>
        <author>冰云</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://icecloud.javaeye.com">冰云</a>&nbsp;
          链接：<a href="http://icecloud.javaeye.com/blog/73749" style="color:red;">http://icecloud.javaeye.com/blog/73749</a>&nbsp;
          发表时间: 2007年04月24日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>敏捷界面重构 &mdash; initial idea</p>
<p>很多人都觉得界面的事情是细枝末节，等功能做好了，找个时间一起清理一下就好，不会占用太多工夫。很多人也都是这样做的。</p>
<p>这里说的界面开发是指系统的交互设计和界面可用性及易用性设计，也包括CSS的界面布局、颜色、字体等基本的视觉元素。这些问题的重要性不用多谈。</p>
<p>我在项目中期加入过几个项目，这时候最令人头疼也最令人兴奋的莫过于在开发中期对于界面和UI进行变更了。一个项目在初期如果没有做良好的界面设计，想要在中间来进行大的变更简直是噩梦一般。在一个敏捷团队中，做这样的事情尤其困难。</p>
<p>敏捷开发中的一个实践，是需要客户的协作和参与，及时由客户认可做完的需求以及由客户决定下一步的开发。这种客户享有决定权能够使开发变得更顺畅，客户关系变得更融洽，是一个很好的实践。</p>
<p>但是，这种实践给界面的改进带来很大的麻烦：如果在项目中期打算进行界面的变更，自然要写出很多跟界面相关的需求，而客户按照需求的价值决定优先 级，他们有时候不理解这样的界面改进如何带来价值，为什么改善一些文字描述和交互方法还要占用开发时间，他们更希望在有限的时间内增加更多的功能和修复更 多的BUG。这时候，这些界面调整的优先级就被排的很低，在几个开发周期内都没有得到采纳。</p>
<p>我们先后尝试了几种方法来改进这个过程，例如给客户培训交互设计和可用性知识；将开发人员分为两组，其中一组专职负责界面改进；或者将界面改进需求单独分成一组，要求客户每个迭代从其中选择一部分等等。但这些办法都不是很理想，没有达到预期效果。</p>
<p>事后总结原因，觉得最大的原因还是在于：客户不是用户。他们虽然负责对项目功能验收，但他们并不最终使用系统。系统使用上的问题不是他们最关心的。他们需要得到投资回报，因此选择了回报更快的功能开发。从这方面看，客户的选择是无可厚非的。</p>
<p>理想的解决方案应当是在一开始就对界面及UI进行控制和把握，并进行持续的度量和改进，或者称为：界面重构。将界面重构和代码重构等同到同样地位，在开发过程中持续随时的进行改进。</p>
<p>我们都知道，代码重构是在不改变代码行为的基础上，改变其内部的结构。通过一系列小的步骤进行重新构造，系统不会因为这些小步骤的改变而停止运转， 仍然会保持顺利正常的运行。重构的结果是一套良好可读的代码，它不仅能够对我们扩展功能有帮助，也是我们适应变化的基本手段之一。</p>
<p>我们将其类比到界面的开发过程中：我们需要在不改变界面功能的情况下，通过一系列细小的步骤，来改变界面的交互行为和可用性。最终结果，不仅仅是一套良好的界面，也是保证我们扩展新的功能和适应变化的基础。</p>
<p>重构的一个要点是测试。测试可以保证重构的正确。而界面开发的过程中，测试工具的缺乏导致我们不得不采用其他的方式来保证功能的正确。一种可行的办 法是维护一个界面原型，纸质或电子形式均可。在不停地开发过程中，不断的维护这个原型，使之先于实际实现被用户感知和体验，提前获得用户的反馈和客户的认 可，并将原型用于指导团队的开发。这种不断的用户体验和用户测试过程，可以在一定程度上保证界面重构的正确性。BA阐述需求或QA进行验收测试的时候，也 不妨考虑使用界面原型作为一个验收条件来展现给开发者。</p>
<p>重构的另一个要点是要经常不断的进行，每当写新代码之前，先进行一点重构，使旧的代码更好阅读。界面重构也应该是这样。对每一个开发完成的需求，提 高界面验收的标准。不仅仅是完成功能就可以，还需要达到一定程度的可用性和可维护性要求。例如必须遵循提前制定的UI Guideline等等。避免因为界面开发的涣散导致的破窗户，这种疏于整理的小细节可能最终成为最头疼的问题。</p>
<p>比如，我们在开发的过程中，以前只以60分作为界面的验收标准，等积累一段时间后再批量修改界面一次，但可能这次修改只能达到80分。现在我们需要 改为以80作为验收标准后，在开发的过程中多花点时间来重构一点点，一直保持80的水平。这样如果我们需要进行更大的改进，可能很容易就能改到90或 100分，从而达到我们最终的目标。</p>
<p>由于开发团队的人员多数不太擅长界面的知识，并且界面的测试和度量工具缺乏所致，界面的持续改进在项目中较难做的很好。这些实践又要求BA或QA能 够有相应的交互设计能力和可用性工程的经验，也限制了其在项目中的实践。但这些确是在一个项目中长期被忽视地方，应当进行一些加强和发展。</p>
<p>总而言之，敏捷过程和界面设计并不是矛盾的，将敏捷的思想应用于界面开发和交互设计的过程中，我们可以获得更多更广泛的想法。</p>
<p>4月23日，和<a href="http://www.doernenburg.com/" target="_blank">Erik</a>谈 了谈这个想法，他也认同这类做法，但觉得由于目前没有一个显然的Vision，或者说，不像Code Refactoring那样有良好的OO设计准则和可读性在前方可以到达，这样的UI重构的准则不是很明显。原因可能还是由于Developer大多缺乏 这方面的Sense。路还很长。</p>
          <br/>
          <span style="color:red;">
            <a href="http://icecloud.javaeye.com/blog/73749#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 24 Apr 2007 05:47:17 +0800</pubDate>
        <link>http://icecloud.javaeye.com/blog/73749</link>
        <guid>http://icecloud.javaeye.com/blog/73749</guid>
      </item>
      <item>
        <title>客户协作 OVER 合同谈判</title>
        <author>冰云</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://icecloud.javaeye.com">冰云</a>&nbsp;
          链接：<a href="http://icecloud.javaeye.com/blog/66277" style="color:red;">http://icecloud.javaeye.com/blog/66277</a>&nbsp;
          发表时间: 2007年03月29日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          刚写的一篇blog: <a href="http://blog.nona.name/200703235.html">http://blog.nona.name/200703235.html </a>和徐x约好的命题作文，不过他还没写。<br />
<br />
最近有人和我谈起他们的项目管理。他是一个项目经理，负责项目的进度跟踪和与客户的沟通。他能够很好的保持客户关系。他的团队中有一个年轻的程序员，工作充满热情，喜欢思考，喜欢用新技术，也很勇于指出问题。
<p>有一天，这个年轻的程序员在客户处外勤，跟客户交流的时候，讨论到了系统某一块儿的功能。年轻的程序员基于他的工作热情，向客户提出，如果这么这么 做，那可能会给你带来更好的功能。客户听了挺高兴，觉得可行，这小伙说的不错。于是就反映到了项目经理处，说这小伙干的不赖，表扬表扬。这项目经理听到客 户的表扬，也附和的说，他确实很上进，回头我再给他当众表扬一下。</p>
<p>项目经理回到了公司，就把这程序员单独叫来聊了一下，他说，你给客户提建议，这样多思考挺好的，不过，咱们给客户开发，要一单一单的做。你说的那个 功能我早就想到了，但我没提，主要是考虑这个功能实现起来很容易，我们可以放在下一期，我们引导客户一下，让他们提出，我们再把它说的复杂艰巨点，这样咱 们很容易就能完成任务，下一期时间更充裕，而且还能收更多的钱。所以以后有想法咱们内部讨论，先别跟客户说。程序员点头称是。</p>
<p>这样的事情在很多公司都很常见。他们把客户视作敌方阵营，利用自己对IT知识优势了解，努力在一些地方上欺瞒和糊弄客户。</p>
<p>与客户成为敌对的关系，就难免要进行谈判。客户希望用低廉的价格买到他希望的功能，或者说，在一定价格内实现更多的功能。而公司希望提高价格，降低成本。两方表面上达成共识，实际上都在暗地<a href="http://bk.baidu.com/view/18930.htm" target="_blank">博弈</a>，要在边边角角上沾点小便宜。而这种博弈结果，就是双方都不能达到最好的情况。就像著名的<a href="http://bk.baidu.com/view/316629.htm" target="_blank">囚徒困境</a>，结局就是<a href="http://bk.baidu.com/view/28460.htm" target="_blank">纳什均衡</a>(Nash equilibrium)，或非合作均衡。</p>
<p>软件开发的最终目的是要给用户交付价值，要达到客户的商业目标，从而完成公司目标。而为了实现客户和公司的双赢，咨询公司采用了加深客户协作的方式 来达成目标。咨询师会和客户一起工作，了解和认识客户，提出针对性的建议，帮助客户发现和识别业务价值，改进目前的系统。咨询师会站在和客户同一方的阵 营，和客户一起思考、学习和成长。虽然说起来很粗泛，但我所认识的每个咨询师确实都在认认真真的为客户考虑。</p>
<p>另一个会产生非合作均衡现象的是按时收费的单价合同和固定价格固定范围合同的问题。一般PM书籍上都会讲FFP合同对买方的风险比较低，而单价合同对于买方风险可高可低，取决于内容和项目性质。</p>
<p>如果签订固定价格合同，通常的，由于价格固定，客户会倾向于在这个价格内挤入更多的需求，有些人甚至不顾质量而要求更多的特性，反正完成不了都是开 发方的责任。而相对的，开发公司会希望在这里面减少成本，或者是人，或者是需求范围，甚至是不惜牺牲质量。最终两方博弈的结果就是项目出了问题。</p>
<p>这种情况下，更好的办法是单价合同，或者具体说，就是确定阶段时间内的开发力量，但不确定开发范围的收费方式。按照客户需求的优先级来开发，双方合 作，尽最大的努力，频繁交付。这种做法的好处是，客户可以控制项目的长短。可以不停的做下去，也可以立即随时终止。由于双方的协作，开发公司也会按照自己 的能力，尽最大可能来保证质量和进度。另一种改进过的单价合同，是基于开发方对项目的理解和估算，报出一个固定价格。在合作共赢的前提下，双方信任并接受 这个契约。这种情况好像更加适合国内的甲方。</p>
<p>前些天，一个原来的同事电话我，她以前是负责销售的，现在自己开了家公司。她雇佣了一个公司给她开发软件，开发了两个多月了还没见到是什么样子。眼 看就要到交付期限了，她想去看看，就问我应该怎么样去中期查验这软件。我告诉她，要怎么怎么样才能看出这系统到底能不能做完，怎么看出到底做的质量如何等 等。</p>
<p>瞧瞧，怎么样，客户也不是很好糊弄的嘛。你糊弄客户，焉知客户不会另请人来对付你？所以，在商业的博弈中，合作才能双赢。这就是为什么<a href="http://www.agilemanifesto.org/" target="_blank">客户协作 over 合同谈判</a>的原因了。</p>
          <br/>
          <span style="color:red;">
            <a href="http://icecloud.javaeye.com/blog/66277#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 29 Mar 2007 08:43:15 +0800</pubDate>
        <link>http://icecloud.javaeye.com/blog/66277</link>
        <guid>http://icecloud.javaeye.com/blog/66277</guid>
      </item>
      <item>
        <title>24日北京聚会通知</title>
        <author>冰云</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://icecloud.javaeye.com">冰云</a>&nbsp;
          链接：<a href="http://icecloud.javaeye.com/blog/59873" style="color:red;">http://icecloud.javaeye.com/blog/59873</a>&nbsp;
          发表时间: 2007年03月14日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          本次活动继续由AgileChina与BJUG两个组织共同举办。我们的目的是让一切对技术和敏捷等有热情的同学们共同学习、共同进步。我们相信来参加活动的都是愿意交流，愿意上进的朋友。让我们一起努力交流，结交志同道合的朋友，把我们所热衷 的技术、思想推广到整个IT界。<br /><br />这次活动采用开放的活动形式(类似Open Space和Unconference)，将由所有参会的人贡献并选出自己感兴趣的话题，每一个愿意交流的人都可以写出自己希望交流的 topic，在活动一开始由主讲人展示出来，大家投票选择。得票最多的几个topic将 会作为当天的Session奉献给大家。topic选择范围可以是任何与技术、开源、项目管理、敏捷、测试、开发过程、需求分析、交互设计等有关的话题<br /><br />请发邮件至agile@bjug.org告知你要参会使我们对人数有所准备。请注明如下信息：姓名，id，email，公司，职位，联系电话，IM，blog等。你可以考虑提前准 备一个45分钟的topic。<br /><br />活动议程安排如下：<br />14:00 参会者自我介绍与投票感兴趣的Session 30分钟<br />14:30 Session1  45分钟<br />15:15 Session1 讨论及Q&A 25分钟<br />15:40 休息和Freetalk 30分钟<br />16:10 Session2  45分钟<br />16:55 Session2 讨论及Q&A 25分钟<br />17:20 结束投票及总结 10分钟<br />17:30之后解散，如有人有兴趣单聊或腐败可自行安排<br /><br />时间：2007年3月24日星期六下午14:00准时开始<br />地点请见：http://groups.google.com/group/agilechina<br /><br />欢迎大家踊跃报名，你也可以邀请你的朋友来参加。我们奉行两条原则，交流与贡献。<br /><br />地点请见：http://groups.google.com/group/agilechina<br />http://www.bjug.org
          <br/>
          <span style="color:red;">
            <a href="http://icecloud.javaeye.com/blog/59873#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 14 Mar 2007 22:06:21 +0800</pubDate>
        <link>http://icecloud.javaeye.com/blog/59873</link>
        <guid>http://icecloud.javaeye.com/blog/59873</guid>
      </item>
      <item>
        <title>BJUG&amp;AgileChina07年2月4日联合活动通知</title>
        <author>冰云</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://icecloud.javaeye.com">冰云</a>&nbsp;
          链接：<a href="http://icecloud.javaeye.com/blog/51452" style="color:red;">http://icecloud.javaeye.com/blog/51452</a>&nbsp;
          发表时间: 2007年01月31日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          本次活动将由AgileChina与BJUG两个组织共同举办，由北京和利时信息技术有限公司提供支持。我们的目的是让一切对技术和敏捷等有热情的同学们共同学习、共同进步。我们相信来参加活动的都是愿意交流，愿意上进的朋友。让我们一起努力交流，结交志同道合的朋友，把我们所热衷的技术、思想推广到整个IT界。<br /><br />这次活动采用开放的活动形式(类似Open Space和Unconference)，将由所有参会的人贡献并选出自己感兴趣的话题，每一个愿意交流的人都可以写出自己希望交流的topic，在活动一开始贴在墙壁上，大家投票选择。得票最多的几个topic将会作为当天的Session奉献给大家。<br /><br />报名方式：请发邮件至sagittatius.qiao@gmail.com，注明如下信息：姓名，id，email，公司，职位，联系电话，IM，blog等。你可以提前准备一个45分钟的topic，topic选择范围可以是任何与技术、项目管理、敏捷等有关的话题。<br /><br />活动议程安排如下：<br />14:00 参会者自我介绍与投票感兴趣的Session 30分钟<br />14:30 Session1  45分钟<br />15:15 Session1 讨论及Q&A 25分钟<br />15:40 休息和Freetalk 30分钟<br />16:10 Session2  45分钟<br />16:55 Session2 讨论及Q&A 25分钟<br />17:20 结束投票及总结 10分钟<br />17:30之后 解散，如有人有兴趣单聊或腐败可自行安排<br /><br />时间：2007年2月4日下午13:30签到，14:00准时开始<br />地点：北京和利时信息技术有限公司1301会议室<br />交通：1、运通105 和利时公司(终点)下车即到。<br />2、315，323，719，810，814，运通109到<br />新都环岛下车，南行500米多点<br />3、城铁到霍营站下车，<br />a）临4路(始发站)到新都环岛下车，南行500米多点<br />b）坐出租车到和利时公司（10元多点）<br />4、自驾车由西三旗桥向东直至新都环岛后，南行500米多点<br /><br />欢迎大家踊跃报名，你也可以邀请你的朋友来参加。我们奉行两条原则，交流与贡献。我们期待你的加入！<br /><br />http://groups.google.com/group/agilechina<br />http://www.bjug.org
          <br/>
          <span style="color:red;">
            <a href="http://icecloud.javaeye.com/blog/51452#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 31 Jan 2007 14:52:02 +0800</pubDate>
        <link>http://icecloud.javaeye.com/blog/51452</link>
        <guid>http://icecloud.javaeye.com/blog/51452</guid>
      </item>
      <item>
        <title>AgileChina与BJUG十二月16日联合活动情况</title>
        <author>冰云</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://icecloud.javaeye.com">冰云</a>&nbsp;
          链接：<a href="http://icecloud.javaeye.com/blog/39547" style="color:red;">http://icecloud.javaeye.com/blog/39547</a>&nbsp;
          发表时间: 2006年12月18日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          时间：2006年12月16日下午14:00<br /><br />  本次活动由AgileChina与BJUG两个组织共同举办。我们的目的是让一切对技术和敏捷等有热情的同学们共同学习、共同进步。我们相信来参加活动的都是愿意交流，愿意上进的朋友。让我们一起努力交流，结交志同道合的朋友，把我们所热衷的技术、思想推广到整个IT界。<br /><br />  这次活动采用开放的活动形式(类似Open Space和Unconference)，将由所有参会的人贡献并选出自己感兴趣的话题，每一个愿意交流的人都可以写出自己希望交流的 topic，在活动一开始贴在墙壁上，大家投票选择。得票最多的几个topic将会作为 当天的Session奉献给大家。<br /><br />TOPIC： <br />1 敏捷 vs CMM -- 不同组织的研究报告  杨崑<br />2 DSL in practice -- 徐昊<br />3 Selenium -- 黄亮<br /><br />我们的价值观：<br />1 Communication 交流<br />  我们乐意与别人真诚交流，认识更多的朋友，并从交流中获取更多的知识。我们建立平等和谐的交流氛围，并希望这种氛围能够扩展到任何一家公司。<br />2 Contribution 贡献<br />  我们愿意将自己的经验总结整理，并分享给大家，我们希望把自己所热衷的理念、技术、思想等传播给更多的人接受。在传播种子的同时，我们也不停的回顾自省和学习提高。<br /><br />相关网站<br />http://groups.google.com/group/agilechina<br />http://www.bjug.org
          <br/>
          <span style="color:red;">
            <a href="http://icecloud.javaeye.com/blog/39547#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 18 Dec 2006 13:22:11 +0800</pubDate>
        <link>http://icecloud.javaeye.com/blog/39547</link>
        <guid>http://icecloud.javaeye.com/blog/39547</guid>
      </item>
      <item>
        <title>敏捷培训宣言</title>
        <author>冰云</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://icecloud.javaeye.com">冰云</a>&nbsp;
          链接：<a href="http://icecloud.javaeye.com/blog/35976" style="color:red;">http://icecloud.javaeye.com/blog/35976</a>&nbsp;
          发表时间: 2006年11月26日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          我和徐x一行4人刚从深圳那边培训敏捷课程回来，3天课程，4个讲师，30个学生，哎，好累。<br /><br />发现这敏捷培训还真不是一个人干的了的，站了3天腿疼死了。每天晚上根据当天情况总结经验教训，还有可能要临时改变课表以适应学员情况。尤其是第二天，我主持课程话说的多太了。。到晚上吃饭时候脑袋疼，说话好像在瓮里一样，能听到自己的回音。。。再加上第三天课表临时变化，晚上准备新课直到2点才全搞定，555。不过，最终学员反馈比较positive，我们都很<strong>安详</strong>。。。<br /><br />（不过还是徐x厉害，连续说话一点事情都没有，说错了都能糊弄过去没人发现。。。。。。）<br /><br />在准备这次的培训时，我们也总结了一个敏捷培训宣言：<br /><br /><span style="font-size: 18pt"><strong>交互与气氛 胜过 讲义与脚本<br />现场发挥 胜过 事先准备<br />白板和纸卡片 胜过 幻灯片<br />用实践引起兴趣 胜过 灌输理论</strong></span><br /><br />虽然右边也有价值，但左边更需要我们重视。。。
          <br/>
          <span style="color:red;">
            <a href="http://icecloud.javaeye.com/blog/35976#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 26 Nov 2006 00:29:28 +0800</pubDate>
        <link>http://icecloud.javaeye.com/blog/35976</link>
        <guid>http://icecloud.javaeye.com/blog/35976</guid>
      </item>
      <item>
        <title>Re: 敏捷需求分析</title>
        <author>冰云</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://icecloud.javaeye.com">冰云</a>&nbsp;
          链接：<a href="http://icecloud.javaeye.com/blog/35162" style="color:red;">http://icecloud.javaeye.com/blog/35162</a>&nbsp;
          发表时间: 2006年11月20日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <div class="quote_title">xiaoyu 写道</div><div class="quote_div">但这个东西好不好估计你的项目大概完成时间? 因为需求一开始并没有清楚. 对于公司要后期调整人员变动, 或者新项目等不明确.<br /><br />希望在这方面说一下. 谢谢</div><br /><br />现在的项目，尤其是web需要运营类的，很难定义什么时候是完成。因为项目很快就上线，之后不停的发布新版本。项目一直在不停的做。因此，你不可能估计完成时间，开始时候对后期的需求也不可能完全清楚。可持续的开发才是这类项目的关键。<br /><br />我们开始的时候计划的整个项目需求大概有50-70个Story，到项目进行了10个月的时候，完成了大约70个Story，但未完成的，或者说新增的需求也是50-70个。从传统项目管理来看，项目才完成一半。。。但项目已经发布了12次，已经开始创造利润。<br /><br />人员变动，也是很容易的。我们的方法是在项目中到6个月可以交换到别处。developer的roll off比较容易，提前一两周来，和人pair几天就熟悉了，BA的话可能需要1-2个迭代的交接时间。小规模的人员调动基本上不会影响项目的开发速度。新人进来，也会给项目带来新鲜的血液和思路。就像温水煮青蛙，在项目中干的太久了，很容易忽视一些做的不好的地方，新人的新视角对改进过程很有帮助。
          <br/>
          <span style="color:red;">
            <a href="http://icecloud.javaeye.com/blog/35162#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 20 Nov 2006 11:06:54 +0800</pubDate>
        <link>http://icecloud.javaeye.com/blog/35162</link>
        <guid>http://icecloud.javaeye.com/blog/35162</guid>
      </item>
      <item>
        <title>敏捷软件开发图书概览</title>
        <author>冰云</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://icecloud.javaeye.com">冰云</a>&nbsp;
          链接：<a href="http://icecloud.javaeye.com/blog/34984" style="color:red;">http://icecloud.javaeye.com/blog/34984</a>&nbsp;
          发表时间: 2006年11月19日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p class="MsoNormal" align="center" style="text-align: center;"><strong style=""><span lang="ZH-CN" style="font-size: 22pt; font-family: 宋体;">敏捷软件开发图书概览</span></strong><strong style=""><span style="font-size: 22pt; font-family: Tahoma;"><o:p></o:p></span></strong></p>
<div align="center"><span lang="ZH-CN" style="font-family: 宋体;">本文发表于程序员杂志2006年第5期</span><span lang="ZH-CN" style="font-family: 宋体;"></span></div>
<p class="MsoNormal"><em style=""><span style="font-family: Tahoma;">&ldquo;</span></em><em style=""><span lang="ZH-CN" style="font-family: 宋体;">敏捷软件开发宣言：我们正在通过亲身实践和帮助其他人实践，揭示更好的软件开发方法，通过这项工作，我们认为：</span></em><em style=""><span style="font-family: Tahoma;"><o:p></o:p></span></em></p>
<p class="MsoNormal" style="text-indent: 21pt;"><strong style=""><em style=""><span lang="ZH-CN" style="font-family: 宋体;">人和交流胜过过程和工具</span></em></strong><strong style=""><em style=""><span style="font-family: Tahoma;"><o:p></o:p></span></em></strong></p>
<p class="MsoNormal" style="text-indent: 21pt;"><strong style=""><em style=""><span lang="ZH-CN" style="font-family: 宋体;">可工作的软件胜过面面俱到的文档</span></em></strong><strong style=""><em style=""><span style="font-family: Tahoma;"><o:p></o:p></span></em></strong></p>
<p class="MsoNormal" style="text-indent: 21pt;"><strong style=""><em style=""><span lang="ZH-CN" style="font-family: 宋体;">客户协作胜过合同谈判</span></em></strong><strong style=""><em style=""><span style="font-family: Tahoma;"><o:p></o:p></span></em></strong></p>
<p class="MsoNormal" style="text-indent: 21pt;"><strong style=""><em style=""><span lang="ZH-CN" style="font-family: 宋体;">响应变化胜过遵循计划</span></em></strong><strong style=""><em style=""><span style="font-family: Tahoma;"><o:p></o:p></span></em></strong></p>
<p class="MsoNormal" style="text-indent: 21pt;"><em style=""><span lang="ZH-CN" style="font-family: 宋体;">虽然右项也有价值，但是我们认为左项更重要。</span></em><em style=""><span style="font-family: Tahoma;">&rdquo;<o:p></o:p></span></em></p>
<p class="MsoNormal" style="margin-left: 21pt; text-indent: 21pt;"><em style=""><span style="font-family: Tahoma;">&mdash;&mdash; Kent Beck</span></em><em style=""><span lang="ZH-CN" style="font-family: 宋体;">，</span></em><em style=""><span style="font-family: Tahoma;">Mike Beedle</span></em><em style=""><span lang="ZH-CN" style="font-family: 宋体;">，</span></em><em style=""><span style="font-family: Tahoma;">Arie van Bennekum</span></em><em style=""><span lang="ZH-CN" style="font-family: 宋体;">，</span></em><em style=""><span style="font-family: Tahoma;">Alistair Cockburn</span></em><em style=""><span lang="ZH-CN" style="font-family: 宋体;">，</span></em><em style=""><span style="font-family: Tahoma;">Ward Cunningham</span></em><em style=""><span lang="ZH-CN" style="font-family: 宋体;">，</span></em><em style=""><span style="font-family: Tahoma;">Martin Fowler</span></em><em style=""><span lang="ZH-CN" style="font-family: 宋体;">，</span></em><em style=""><span style="font-family: Tahoma;">James Grenning</span></em><em style=""><span lang="ZH-CN" style="font-family: 宋体;">，</span></em><em style=""><span style="font-family: Tahoma;">Jim Highsmith</span></em><em style=""><span lang="ZH-CN" style="font-family: 宋体;">，</span></em><em style=""><span style="font-family: Tahoma;">Andrew Hunt</span></em><em style=""><span lang="ZH-CN" style="font-family: 宋体;">，</span></em><em style=""><span style="font-family: Tahoma;">Ron Jeffries</span></em><em style=""><span lang="ZH-CN" style="font-family: 宋体;">，</span></em><em style=""><span style="font-family: Tahoma;">Jon Kern</span></em><em style=""><span lang="ZH-CN" style="font-family: 宋体;">，</span></em><em style=""><span style="font-family: Tahoma;">Brian Marick</span></em><em style=""><span lang="ZH-CN" style="font-family: 宋体;">，</span></em><em style=""><span style="font-family: Tahoma;"> Robert C. Martin</span></em><em style=""><span lang="ZH-CN" style="font-family: 宋体;">，</span></em><em style=""><span style="font-family: Tahoma;">Steve Mellor</span></em><em style=""><span lang="ZH-CN" style="font-family: 宋体;">，</span></em><em style=""><span style="font-family: Tahoma;">Ken Schwaber</span></em><em style=""><span lang="ZH-CN" style="font-family: 宋体;">，</span></em><em style=""><span style="font-family: Tahoma;">Jeff Sutherland</span></em><em style=""><span lang="ZH-CN" style="font-family: 宋体;">，</span></em><em style=""><span style="font-family: Tahoma;">Dave Thomas<o:p></o:p></span></em></p>
<p class="MsoNormal"><span style="font-family: Tahoma;"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal" style="text-indent: 21pt;"><span lang="ZH-CN" style="font-family: 宋体;">敏捷软件开发这个词在</span><span style="font-family: Tahoma;">2006</span><span lang="ZH-CN" style="font-family: 宋体;">年的中国软件界听起来仍然显得有些陌生。自</span><span style="font-family: Tahoma;">2001</span><span lang="ZH-CN" style="font-family: 宋体;">年敏捷联盟被发起以来，敏捷方法的实践经验和理论研究都在不断的更新。而我国的大多数程序员还是只能在书本上读到敏捷的好处，很难在项目中进行实践。这其中的原因，主要是缺乏拥有实际敏捷项目经验的人来带领实施敏捷。虽然敏捷开发是种实践行为，很难从书本上直接学习，不过多数程序员了解敏捷，却都是先从书本开始的。无论结果怎样，从认识到实践的过程是免不了的。</span><span style="font-family: Tahoma;"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Tahoma;"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal"><strong style=""><span lang="ZH-CN" style="font-family: 宋体;">敏捷软件开发之方法论篇</span></strong><strong style=""><span style="font-family: Tahoma;"><o:p></o:p></span></strong></p>
<p class="MsoNormal" style="text-indent: 21pt;"><span lang="ZH-CN" style="font-family: 宋体;">大家都知道敏捷软件开发方法包括了多种方法论，主要有：</span><span style="font-family: Tahoma;">SCRUM</span><span lang="ZH-CN" style="font-family: 宋体;">，</span><span style="font-family: Tahoma;">Crystal,</span><span lang="ZH-CN" style="font-family: 宋体;">特征驱动软件开发（</span><span style="font-family: Tahoma;">FDD</span><span lang="ZH-CN" style="font-family: 宋体;">），自适应软件开发（</span><span style="font-family: Tahoma;">ASD</span><span lang="ZH-CN" style="font-family: 宋体;">），以及最著名的极限编程</span><span style="font-family: Tahoma;">(XP)</span><span lang="ZH-CN" style="font-family: 宋体;">。这些方法论分别在不同的著作上专门论述过：</span><span style="font-family: Tahoma;"><o:p></o:p></span></p>
<p class="MsoNormal" style="text-indent: 21pt;"><span style="font-family: Tahoma;">SCRUM</span><span lang="ZH-CN" style="font-family: 宋体;">：《</span><span style="font-family: Tahoma;">Agile Software Development with Scrum</span><span lang="ZH-CN" style="font-family: 宋体;">》</span><span lang="ZH-CN" style="font-family: Tahoma;"> </span><span style="font-family: Tahoma;">by Ken Schwaber, Mike Beedle</span><span lang="ZH-CN" style="font-family: 宋体;">，《</span><span style="font-family: Tahoma;">Agile Project Management With Scrum</span><span lang="ZH-CN" style="font-family: 宋体;">》</span><span style="font-family: Tahoma;">by Ken Schwaber<o:p></o:p></span></p>
<p class="MsoNormal" style="text-indent: 21pt;"><span style="font-family: Tahoma;">FDD:</span><span lang="ZH-CN" style="font-family: 宋体;">《</span><span style="font-family: Tahoma;">Java Modeling in Color with UML</span><span lang="ZH-CN" style="font-family: 宋体;">》</span><span style="font-family: Tahoma;">by Peter Coad, </span><span lang="ZH-CN" style="font-family: 宋体;">《</span><span style="font-family: Tahoma;">A Practical Guide to Feature-Driven Development</span><span lang="ZH-CN" style="font-family: 宋体;">》</span><span style="font-family: Tahoma;">(</span><span lang="ZH-CN" style="font-family: 宋体;">特征驱动开发</span><span style="font-family: Tahoma;">) by Stephen R Palmer, John M. Felsing,<o:p></o:p></span></p>
<p class="MsoNormal" style="text-indent: 21pt;"><span style="font-family: Tahoma;">Crystal: </span><span lang="ZH-CN" style="font-family: 宋体;">《</span><span style="font-family: Tahoma;">Crystal Clear</span><span lang="ZH-CN" style="font-family: 宋体;">》</span><span style="font-family: Tahoma;">by Alistair Cockburn<o:p></o:p></span></p>
<p class="MsoNormal" style="text-indent: 21pt;"><span style="font-family: Tahoma;">ASD: </span><span lang="ZH-CN" style="font-family: 宋体;">《</span><span style="font-family: Tahoma;">Adaptive Software Development</span><span lang="ZH-CN" style="font-family: 宋体;">》（自适应软件开发）</span><span style="font-family: Tahoma;">by James A. Highsmith<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Tahoma;"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal" style="text-indent: 21pt;"><span lang="ZH-CN" style="font-family: 宋体;">其中尤以</span><span style="font-family: Tahoma;">XP</span><span lang="ZH-CN" style="font-family: 宋体;">系列的书籍居多。人民邮电出版社的一系列极限编程系列丛书，在国内引进较早。在还没有统一敏捷词汇的情况下，引发了一批敏捷先锋人士的热情，是我国程序员的敏捷启蒙教材。这些书包括《</span><span style="font-family: Tahoma;">Extreme Programming Explained</span><span lang="ZH-CN" style="font-family: 宋体;">》（解析极限编程），《</span><span style="font-family: Tahoma;">Extreme Programming Examined</span><span lang="ZH-CN" style="font-family: 宋体;">》（极限编程研究），《</span><span style="font-family: Tahoma;">Extreme Programming Installed</span><span lang="ZH-CN" style="font-family: 宋体;">》</span><span style="font-family: Tahoma;">(</span><span lang="ZH-CN" style="font-family: 宋体;">极限编程实施</span><span style="font-family: Tahoma;">)</span><span lang="ZH-CN" style="font-family: 宋体;">，《</span><span style="font-family: Tahoma;">Extreme Programming Explored</span><span lang="ZH-CN" style="font-family: 宋体;">》（探索极限编程），《</span><span style="font-family: Tahoma;">Extreme Programming Applied</span><span lang="ZH-CN" style="font-family: 宋体;">》（应用极限编程）《</span><span style="font-family: Tahoma;">Extreme Programming in Practice</span><span lang="ZH-CN" style="font-family: 宋体;">》（极限编程实践），《</span><span style="font-family: Tahoma;">Planning Extreme Programming</span><span lang="ZH-CN" style="font-family: 宋体;">》（规划极限编程）等，这些书有的是作者的</span><span style="font-family: Tahoma;">XP</span><span lang="ZH-CN" style="font-family: 宋体;">实践论文，有些是对</span><span style="font-family: Tahoma;">XP</span><span lang="ZH-CN" style="font-family: 宋体;">项目的介绍，其中，值得推荐的是下面两部著作。</span><span style="font-family: Tahoma;"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Tahoma;"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal"><strong style=""><span lang="ZH-CN" style="font-family: 宋体;">《</span></strong><strong style=""><span style="font-family: Tahoma;">Extreme Programming Explained: Embrace Change</span></strong><strong style=""><span lang="ZH-CN" style="font-family: 宋体;">》</span></strong><strong style=""><span style="font-family: Tahoma;">by Kent Beck<o:p></o:p></span></strong></p>
<p class="MsoNormal"><strong style=""><span lang="ZH-CN" style="font-family: 宋体;">第一版中译版：《解析极限编程：拥抱变化》，</span></strong><strong style=""><span lang="ZH-CN" style="font-family: 宋体;">唐东铭，</span></strong><strong style=""><span lang="ZH-CN" style="font-family: 宋体;">人民邮电出版社</span></strong><strong style=""><span style="font-family: Tahoma;"><o:p></o:p></span></strong></p>
<p class="MsoNormal"><strong style=""><span lang="ZH-CN" style="font-family: 宋体;">第二版中译版：</span></strong><strong style=""><span lang="ZH-CN" style="font-family: 宋体;">雷剑文，电子工业出版社</span></strong><strong style=""><span style="font-family: Tahoma;"><o:p></o:p></span></strong></p>
<p class="MsoNormal" style="text-indent: 21pt;"><span lang="ZH-CN" style="font-family: 宋体;">作为</span><span style="font-family: Tahoma;">XP</span><span lang="ZH-CN" style="font-family: 宋体;">的开山之作，目前已经出版了第二版。在第一版中，</span><span style="font-family: Tahoma;">Kent Beck</span><span lang="ZH-CN" style="font-family: 宋体;">对</span><span style="font-family: Tahoma;">XP</span><span lang="ZH-CN" style="font-family: 宋体;">作了详细的描述。从当前软件开发的现状和问题谈起，从需求的变化到如何拥抱变化，给出了</span><span style="font-family: Tahoma;">XP</span><span lang="ZH-CN" style="font-family: 宋体;">的四项价值观和十二项实践。对于想了解敏捷的来龙去脉的人，此书属于必读之类。在第二版，</span><span style="font-family: Tahoma;">Kent</span><span lang="ZH-CN" style="font-family: 宋体;">根据几年来的实践，为</span><span style="font-family: Tahoma;">XP</span><span lang="ZH-CN" style="font-family: 宋体;">增加了一项价值观：尊重，并增加了原则的概念，同时增加和删改了一些实践。</span><span style="font-family: Tahoma;"><o:p></o:p></span></p>
<p class="MsoNormal" style="text-indent: 21pt;"><span lang="ZH-CN" style="font-family: 宋体;">该书第一版是程序员的宣言，这和</span><span style="font-family: Tahoma;">Kent</span><span lang="ZH-CN" style="font-family: 宋体;">的背景很有关系。随后</span><span style="font-family: Tahoma;">XP</span><span lang="ZH-CN" style="font-family: 宋体;">经历了五六年的发展和实践，</span><span style="font-family: Tahoma;">Kent</span><span lang="ZH-CN" style="font-family: 宋体;">自己也逐渐意识到，这样的观点太狭隘了。因此就有了第二版，与其说这是技术书籍，到更像是纯粹意义的软工书籍。期间也可以看出</span><span style="font-family: Tahoma;">XP</span><span lang="ZH-CN" style="font-family: 宋体;">的体系更加完备。这其中尤为突出的是把人放到了更为重要的地位。</span><span style="font-family: Tahoma;"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Tahoma;"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal"><strong style=""><span lang="ZH-CN" style="font-family: 宋体;">《</span></strong><strong style=""><span style="font-family: Tahoma;">Extreme Programming in Practice</span></strong><strong style=""><span lang="ZH-CN" style="font-family: 宋体;">》</span></strong><strong style=""><span style="font-family: Tahoma;">by James Newkirk, Robert C. Martin<o:p></o:p></span></strong></p>
<p class="MsoNormal"><strong style=""><span lang="ZH-CN" style="font-family: 宋体;">中译版：《极限编程实践》，</span></strong><strong style=""><span lang="ZH-CN" style="font-family: 宋体;">王钧，</span></strong><strong style=""><span lang="ZH-CN" style="font-family: 宋体;">人民邮电出版社</span></strong><strong style=""><span style="font-family: Tahoma;"><o:p></o:p></span></strong></p>
<p class="MsoNormal" style="text-indent: 21pt;"><span lang="ZH-CN" style="font-family: 宋体;">读过了一些列的</span><span style="font-family: Tahoma;">XP</span><span lang="ZH-CN" style="font-family: 宋体;">书籍，程序员们都会觉得</span><span style="font-family: Tahoma;">XP</span><span lang="ZH-CN" style="font-family: 宋体;">非常好，但到底如何才能开始实施</span><span style="font-family: Tahoma;">XP</span><span lang="ZH-CN" style="font-family: 宋体;">呢？还不是太清楚。本系列中的这本书用一个完整的小项目作例子，从头到尾教给人如何敏捷开发，是一本不可多得的实践教材。如果想直接实施</span><span style="font-family: Tahoma;">XP</span><span lang="ZH-CN" style="font-family: 宋体;">开发，这本书可以给你很大启示。</span><span style="font-family: Tahoma;"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Tahoma;"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal" style="text-indent: 21pt;"><span style="font-family: Tahoma;"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal"><strong style=""><span lang="ZH-CN" style="font-family: 宋体;">敏捷软件开发之实践篇</span></strong><strong style=""><span style="font-family: Tahoma;"><o:p></o:p></span></strong></p>
<p class="MsoNormal"><strong style=""><span lang="ZH-CN" style="font-family: 宋体;">一、极限编程最佳实践</span></strong><strong style=""><span style="font-family: Tahoma;"><o:p></o:p></span></strong></p>
<p class="MsoNormal" style="text-indent: 21pt;"><span lang="ZH-CN" style="font-family: 宋体;">由于极限编程是如此的流行，多数敏捷团队都会或多或少的借鉴一些</span><span style="font-family: Tahoma;">XP</span><span lang="ZH-CN" style="font-family: 宋体;">中的敏捷实践，而</span><span style="font-family: Tahoma;">XP</span><span lang="ZH-CN" style="font-family: 宋体;">的每一个敏捷实践也确实值得大书特书，而其中最著名的是测试驱动开发和重构实践：</span><span style="font-family: Tahoma;"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Tahoma;"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal"><strong style=""><span lang="ZH-CN" style="font-family: 宋体;">《</span></strong><strong style=""><span style="font-family: Tahoma;">Test-Driven Development</span></strong><strong style=""><span lang="ZH-CN" style="font-family: 宋体;">》</span></strong><strong style=""><span style="font-family: Tahoma;"> by Kent Beck<o:p></o:p></span></strong></p>
<p class="MsoNormal"><strong style=""><span lang="ZH-CN" style="font-family: 宋体;">中译版：《测试驱动开发》，</span></strong><strong style=""><span lang="ZH-CN" style="font-family: 宋体;">崔凯，中国电力出版社</span></strong><strong style=""><span style="font-family: Tahoma;"><o:p></o:p></span></strong></p>
<p class="MsoNormal" style="text-indent: 21pt;"><span lang="ZH-CN" style="font-family: 宋体;">测试驱动开发是</span><span style="font-family: Tahoma;">Kent Beck</span><span lang="ZH-CN" style="font-family: 宋体;">另一部力作。</span><span style="font-family: Tahoma;">&ldquo;Clean Code That Works&rdquo;</span><span lang="ZH-CN" style="font-family: 宋体;">是敏捷开发的目标之一，那么如何达到这个目标？</span><span style="font-family: Tahoma;">TDD</span><span lang="ZH-CN" style="font-family: 宋体;">给出了一种方式。测试实质上是需求。由需求产生出的代码肯定是能够工作的功能代码，而要实现</span><span style="font-family: Tahoma;">Class</span><span lang="ZH-CN" style="font-family: 宋体;">本身的可测试性，就不得不写出高度解耦合的</span><span style="font-family: Tahoma;">Clean</span><span lang="ZH-CN" style="font-family: 宋体;">的代码。本书从一个</span><span style="font-family: Tahoma;">Money</span><span lang="ZH-CN" style="font-family: 宋体;">的例子入手，从最初的一点需求开始，逐步增加需求，完成整个货币系统的代码。后面又给出了</span><span style="font-family: Tahoma;">Unit Test</span><span lang="ZH-CN" style="font-family: 宋体;">中的一些最佳实践和模式供参考。</span><span style="font-family: Tahoma;"><o:p></o:p></span></p>
<p class="MsoNormal" style="text-indent: 21pt;"><span lang="ZH-CN" style="font-family: 宋体;">然而，本书的教导意义比其实践意义更突出。作为一本</span><span style="font-family: Tahoma;">TDD</span><span lang="ZH-CN" style="font-family: 宋体;">的教程或入门教材，这本书无疑是最佳的，其中提出的一些最佳实践更是值得经常阅读来温习。本书面向的是单元测试，而实际开发中面对的数据库测试，</span><span style="font-family: Tahoma;">Web</span><span lang="ZH-CN" style="font-family: 宋体;">测试等问题并不属于单元测试的范畴。因此读者并不能从中直接进入到实战。</span><span style="font-family: Tahoma;"><o:p></o:p></span></p>
<p class="MsoNormal" style="text-indent: 21pt;"><span lang="ZH-CN" style="font-family: 宋体;">另一本同名书《</span><span style="font-family: Tahoma;">Test Driven Development: A Practical Guide</span><span lang="ZH-CN" style="font-family: 宋体;">》由</span><span style="font-family: Tahoma;">Davis Astels</span><span lang="ZH-CN" style="font-family: 宋体;">撰写，他将该书看作是</span><span style="font-family: Tahoma;">Kent</span><span lang="ZH-CN" style="font-family: 宋体;">著作的补充，重点阐述利用</span><span style="font-family: Tahoma;">TDD</span><span lang="ZH-CN" style="font-family: 宋体;">开发所必要的技术和工具上，因此对实际开发更具实用性。</span><span style="font-family: Tahoma;"><o:p></o:p></span></p>
<p class="MsoNormal"><strong style=""><span style="font-family: Tahoma;"><o:p>&nbsp;</o:p></span></strong></p>
<p class="MsoNormal"><strong style=""><span lang="ZH-CN" style="font-family: 宋体;">《</span></strong><strong style=""><span style="font-family: Tahoma;">Refactoring: </span></strong><strong style=""><span style="font-family: Tahoma;">Improving the Design of Existing Code</span></strong><strong style=""><span lang="ZH-CN" style="font-family: 宋体;">》</span></strong><strong style=""><span style="font-family: Tahoma;">by Martin Fowler<o:p></o:p></span></strong></p>
<p class="MsoNormal"><strong style=""><span lang="ZH-CN" style="font-family: 宋体;">中译版：《重构：改善既有代码的设计》，侯捷，熊节，中国电力出版社</span></strong><strong style=""><span style="font-family: Tahoma;"><o:p></o:p></span></strong></p>
<p class="MsoNormal" style="text-indent: 21pt;"><span lang="ZH-CN" style="font-family: 宋体;">重构这本书的意义在于，他提供了一种让你写出更加优美代码的能力。在测试的保证下，重构能够发挥强大的威力。敏捷团队中，不断的重构出简单且高效的代码才能够保持拥抱不断变化的需求。后来的一本书《</span><span style="font-family: Tahoma;">Refactoring to Patterns</span><span lang="ZH-CN" style="font-family: 宋体;">》（从重构到模式）</span><span style="font-family: Tahoma;">by Joshua Kerievsky</span><span lang="ZH-CN" style="font-family: 宋体;">，更是将重构的威力发挥到极限。</span><strong style=""><span style="font-family: Tahoma;"><o:p></o:p></span></strong></p>
<p class="MsoNormal" style="text-indent: 21pt;"><span lang="ZH-CN" style="font-family: 宋体;">重构曾被称为软件开发图书的双璧，另一本书是《</span><span style="font-family: Tahoma;">Design Patterns</span><span lang="ZH-CN" style="font-family: 宋体;">》</span><span style="font-family: Tahoma;">(</span><span lang="ZH-CN" style="font-family: 宋体;">设计模式</span><span style="font-family: Tahoma;">) by GoF</span><span lang="ZH-CN" style="font-family: 宋体;">。当然，对现在的软件开发这二者已经不是最重要的。</span><strong style=""><span style="font-family: Tahoma;">Thought</span></strong><span style="font-family: Tahoma;">Works</span><span lang="ZH-CN" style="font-family: 宋体;">的首席科学家</span><span style="font-family: Tahoma;">Martin Fowler</span><span lang="ZH-CN" style="font-family: 宋体;">总结了朋友们的各种实践心得，写出了这本书。从几年后的目光来看，这本书中的多数实践都被各种</span><span style="font-family: Tahoma;">IDE</span><span lang="ZH-CN" style="font-family: 宋体;">做到了操作菜单中。虽然</span><span style="font-family: Tahoma;">IDE</span><span lang="ZH-CN" style="font-family: 宋体;">提供了大量重构功能，但仅靠</span><span style="font-family: Tahoma;">IDE</span><span lang="ZH-CN" style="font-family: 宋体;">是无法写出简洁美妙代码的，多数的敏捷团队重构工作做得还是不够。</span><span style="font-family: Tahoma;"><o:p></o:p></span></p>
<p class="MsoNormal" style="text-indent: 21pt;"><span style="font-family: Tahoma;"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal" style="text-indent: 21pt;"><span lang="ZH-CN" style="font-family: 宋体;">另外有一本专门介绍结对编程的书，《</span><span style="font-family: Tahoma;">Pair Programming Illuminated</span><span lang="ZH-CN" style="font-family: 宋体;">》（结对编程技术）</span><span style="font-family: Tahoma;">by by Laurie Williams and Robert Kessler</span><span lang="ZH-CN" style="font-family: 宋体;">，指出了为什么要结对？并从各种不同水平不同性格的程序员结对情况来讨论该实践的优劣。对此有兴趣的程序员不妨一读。</span><span style="font-family: Tahoma;"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Tahoma;"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">二、敏捷软件开发实践</span><span style="font-family: Tahoma;"><o:p></o:p></span></p>
<p class="MsoNormal" style="text-indent: 21pt;"><span lang="ZH-CN" style="font-family: 宋体;">自从</span><span style="font-family: Tahoma;">2001</span><span lang="ZH-CN" style="font-family: 宋体;">年敏捷联盟成立以来，单独推广极限编程的书变少了，而统一口径推广敏捷的书变得越来越多。两本同名的敏捷软件开发都是不可多得的好书，</span><span style="font-family: Tahoma;"><o:p></o:p></span></p>
<p class="MsoNormal"><strong style=""><span style="font-family: Tahoma;"><o:p>&nbsp;</o:p></span></strong></p>
<p class="MsoNormal"><strong style=""><span lang="ZH-CN" style="font-family: 宋体;">《</span></strong><strong style=""><span style="font-family: Tahoma;">Agile Software Development</span></strong><strong style=""><span lang="ZH-CN" style="font-family: 宋体;">：</span></strong><strong style=""><span style="font-family: Tahoma;">Principles, Patterns, and Practices</span></strong><strong style=""><span lang="ZH-CN" style="font-family: 宋体;">》</span></strong><strong style=""><span style="font-family: Tahoma;">by Robert C. Martin<o:p></o:p></span></strong></p>
<p class="MsoNormal"><strong style=""><span lang="ZH-CN" style="font-family: 宋体;">中译版：《敏捷软件开发：原则，模式与实践》，邓辉，</span></strong><strong style=""><span lang="ZH-CN" style="font-family: 宋体;">清华大学出版社</span></strong><strong style=""><span style="font-family: Tahoma;"><o:p></o:p></span></strong></p>
<p class="MsoNormal" style="text-indent: 21pt;"><span lang="ZH-CN" style="font-family: 宋体;">被业内人士称为</span><span style="font-family: Tahoma;">Uncle Bob</span><span lang="ZH-CN" style="font-family: 宋体;">的</span><span style="font-family: Tahoma;">Robert C Martin</span><span lang="ZH-CN" style="font-family: 宋体;">在沉寂几年后写出了这部书。该书可以算是从软件开发角度对敏捷方法阐述的最详细和全面的一本。之前的敏捷书籍多是关注于过程改进，而对如何从技术角度实施讲的比较少。本书一开始先介绍了敏捷联盟和敏捷开发过程。之后详细论述了面向对象设计的原则，这些原则是本书的精华之一。后面通过几个项目介绍了如何将设计模式应用于项目中。</span><span style="font-family: Tahoma;"><o:p></o:p></span></p>
<p class="MsoNormal" style="text-indent: 21pt;"><span style="font-family: Tahoma;">Uncle Bob</span><span lang="ZH-CN" style="font-family: 宋体;">不愧是实践的大师，写出来的书也是拥有很强的实践意义。在敏捷团队的办公桌上，应当常备此书，一来可作为参考查询，二来可以作为新成员的必读书目。</span><span style="font-family: Tahoma;"><o:p></o:p></span></p>
<p class="MsoNormal"><strong style=""><span style="font-family: Tahoma;"><o:p>&nbsp;</o:p></span></strong></p>
<p class="MsoNormal"><strong style=""><span lang="ZH-CN" style="font-family: 宋体;">《</span></strong><strong style=""><span style="font-family: Tahoma;">Agile Software Development</span></strong><strong style=""><span lang="ZH-CN" style="font-family: 宋体;">》</span></strong><strong style=""><span style="font-family: Tahoma;">by Alistair Cockburn<o:p></o:p></span></strong></p>
<p class="MsoNormal"><strong style=""><span lang="ZH-CN" style="font-family: 宋体;">中译版：《敏捷软件开发》，俞涓，人民邮电出版社</span></strong><strong style=""><span style="font-family: Tahoma;"><o:p></o:p></span></strong></p>
<p class="MsoNormal" style="text-indent: 21pt;"><span lang="ZH-CN" style="font-family: 宋体;">这本书更加适合管理者来阅读。</span><span style="font-family: Tahoma;">Alistair</span><span lang="ZH-CN" style="font-family: 宋体;">从项目人数和交流难易程度，将敏捷的各种方法划分了其适用范围。人数多的或分布式项目就需要靠其他手段来加强交流，人数少的就可以靠</span><span style="font-family: Tahoma;">pair programming</span><span lang="ZH-CN" style="font-family: 宋体;">等进行面对面的交流。交流和反馈是敏捷的核心。同时</span><span style="font-family: Tahoma;">Alistair</span><span lang="ZH-CN" style="font-family: 宋体;">也介绍了一下他提出的</span><span style="font-family: Tahoma;">Crystal</span><span lang="ZH-CN" style="font-family: 宋体;">方法族。</span><span style="font-family: Tahoma;"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Tahoma;"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">三</span><span style="font-family: Tahoma;">.</span><span lang="ZH-CN" style="font-family: 宋体;">敏捷项目管理和敏捷需求分析</span><span style="font-family: Tahoma;"><o:p></o:p></span></p>
<p class="MsoNormal" style="text-indent: 21pt;"><span lang="ZH-CN" style="font-family: 宋体;">在推广敏捷一段时间后，敏捷社群也意识到，多数书籍更像是面向开发人员，过于技术化，难以吸引项目经理或主管。因此，一批面向管理者视角的书也开始浮出水面，这些书包括：</span><span style="font-family: Tahoma;"><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">《</span><span style="font-family: Tahoma;">Agile and Iterative Development</span><span lang="ZH-CN" style="font-family: 宋体;">》（敏捷迭代开发）</span><span style="font-family: Tahoma;">by Craig Larman<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">《</span><span style="font-family: Tahoma;">Lean Software Development</span><span lang="ZH-CN" style="font-family: 宋体;">》（</span><span class="13ptredcu"><span lang="ZH-CN" style="font-family: 宋体;">敏捷</span></span><span lang="ZH-CN" style="font-family: 宋体;">软件开发工具</span><span style="font-family: Tahoma;">&mdash;</span><span lang="ZH-CN" style="font-family: 宋体;">精益开发方法</span><span lang="ZH-CN" style="font-family: 宋体;">）</span><span style="font-family: Tahoma;">by Mary Poppendieck<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">《</span><span style="font-family: Tahoma;">Agile Software Development Ecosystems</span><span lang="ZH-CN" style="font-family: 宋体;">》（敏捷软件开发生态系统）</span><span style="font-family: Tahoma;">by Jim Highsmith<o:p></o:p></span></p>
<p class="MsoNormal" style="text-indent: 21pt;"><span lang="ZH-CN" style="font-family: 宋体;">书中从各种角度比较和分析各种敏捷方法的优劣，异同，起源，适用范围等。这些书对于一个项目主管决策使用何种过程来在自己的团队中实践敏捷有很好的参考作用。</span><span style="font-family: Tahoma;"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Tahoma;"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal" style="text-indent: 21pt;"><span lang="ZH-CN" style="font-family: 宋体;">近两年，人们开始逐渐意识到敏捷开发的侧重点不仅仅是开发过程和开发实践，还包括对需求和项目管理等其他相关方面的实践。一些相关的书籍也悄然出现在人们的视野：</span><span style="font-family: Tahoma;"><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">《</span><span style="font-family: Tahoma;">Agile Project Management</span><span lang="ZH-CN" style="font-family: 宋体;">》（敏捷项目管理）</span><span style="font-family: Tahoma;">by Jim Highsmith<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">《</span><span style="font-family: Tahoma;">User Stories Applied</span><span lang="ZH-CN" style="font-family: 宋体;">》</span><span style="font-family: Tahoma;">by Mike Cohn<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">《</span><span style="font-family: Tahoma;">Agile Estimating and Planning</span><span lang="ZH-CN" style="font-family: 宋体;">》</span><span style="font-family: Tahoma;">by Mike Cohn<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">《</span><span style="font-family: Tahoma;">Agile Requirements &amp; User Stories</span><span lang="ZH-CN" style="font-family: 宋体;">》</span><span style="font-family: Tahoma;"> by Louis Molnar<o:p></o:p></span></p>
<p class="MsoNormal" style="text-indent: 21pt;"><span lang="ZH-CN" style="font-family: 宋体;">这些书不同于以往强调新方法，新过程的书目。敏捷项目管理类的书主要介绍如何管理敏捷团队，如何计划要开发的需求，如何为客户提供最大的价值。介绍敏捷需求分析的书主要帮助商务分析师或项目经理挖掘和分析用户需求，写出用户故事，评估和计划用户故事等。人们已经意识到，各种方法论的实质是相同的，都是提供商业价值，减少浪费，增加交流，快速反馈。因此不需要着重于区分是使用了那种方法。对项目经理来说，不同的项目或团队应当采用适应其特殊情况的方法，而这些方法的基本原则是相同的。</span><span style="font-family: Tahoma;"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Tahoma;"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal"><span lang="ZH-CN" style="font-family: 宋体;">四</span><span style="font-family: Tahoma;">.</span><span lang="ZH-CN" style="font-family: 宋体;">敏捷软件开发新方向</span><span style="font-family: Tahoma;"><o:p></o:p></span></p>
<p class="MsoNormal" style="text-indent: 21pt;"><span lang="ZH-CN" style="font-family: 宋体;">对架构师或程序员来说，近年来的技术进展，也使得敏捷开发有了新的研究方向：</span><span style="font-family: Tahoma;"><o:p></o:p></span></p>
<p class="MsoNormal" style="text-indent: 21pt;"><span lang="ZH-CN" style="font-family: 宋体;">《</span><span style="font-family: Tahoma;">Agile Web Development with Rails</span><span lang="ZH-CN" style="font-family: 宋体;">》</span><span style="font-family: Tahoma;">by</span><span style="font-family: Tahoma;"> </span><span style="font-family: Tahoma;">Dave Thomas, David Hansson, Leon Breedt, and Mike Clark<o:p></o:p></span></p>
<p class="MsoNormal" style="text-indent: 21pt;"><span lang="ZH-CN" style="font-family: 宋体;">该书是获得</span><span style="font-family: Tahoma;">2006JOLT</span><span lang="ZH-CN" style="font-family: 宋体;">奖的书，讲得是采用</span><span style="font-family: Tahoma;">Ruby on Rails</span><span lang="ZH-CN" style="font-family: 宋体;">这个</span><span style="font-family: Tahoma;">Web</span><span lang="ZH-CN" style="font-family: 宋体;">开发工具新贵来快速开发</span><span style="font-family: Tahoma;">Web</span><span lang="ZH-CN" style="font-family: 宋体;">项目，从而达到快速反馈拥抱变化的目的。</span><span style="font-family: Tahoma;"><o:p></o:p></span></p>
<p class="MsoNormal" style="text-indent: 21pt;"><span lang="ZH-CN" style="font-family: 宋体;">《</span><span style="font-family: Tahoma;">Refactoring Databases</span><span lang="ZH-CN" style="font-family: 宋体;">》</span><span style="font-family: Tahoma;">by Scott W Ambler<o:p></o:p></span></p>
<p class="MsoNormal" style="text-indent: 21pt;"><span lang="ZH-CN" style="font-family: 宋体;">此书是</span><span style="font-family: Tahoma;">Scott</span><span lang="ZH-CN" style="font-family: 宋体;">的新作，延续和继承了《</span><span style="font-family: Tahoma;">Agile Modeling</span><span lang="ZH-CN" style="font-family: 宋体;">》（敏捷建模）和《</span><span style="font-family: Tahoma;">Agile Database Techniques</span><span lang="ZH-CN" style="font-family: 宋体;">》（敏捷数据）的思想。在敏捷开发过程中，作为持久化最常见技术的数据库如果不能够敏捷，怎么能够适应一次次迭代和一次次发布的修改呢？书中介绍了如何进行数据库演化，如何保证升级后数据库数据的正确性，以及最佳实践。</span><span style="font-family: Tahoma;"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family: Tahoma;"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal" style="text-indent: 21pt;"><span lang="ZH-CN" style="font-family: 宋体;">我们可以看到，随着敏捷方法和市场的不断成熟，敏捷的书籍也从理论性转向了实用和最佳实践类型。然而，不可否认的是，一个团队的敏捷化很难仅靠阅读书本来完成，由成功实践过敏捷的开发者手把手的带领，才是最好的方法。</span><span style="font-family: Tahoma;"><o:p></o:p></span></p>
          <br/>
          <span style="color:red;">
            <a href="http://icecloud.javaeye.com/blog/34984#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 19 Nov 2006 23:46:03 +0800</pubDate>
        <link>http://icecloud.javaeye.com/blog/34984</link>
        <guid>http://icecloud.javaeye.com/blog/34984</guid>
      </item>
      <item>
        <title>Re: 如何做需求管理？</title>
        <author>冰云</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://icecloud.javaeye.com">冰云</a>&nbsp;
          链接：<a href="http://icecloud.javaeye.com/blog/34983" style="color:red;">http://icecloud.javaeye.com/blog/34983</a>&nbsp;
          发表时间: 2006年11月19日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          使用story card + excel记录和管理需求，这就足够了。<br />
<br />
个人认为需求管理主要有以下要点需要注意：  <br />
1 需求的价值：<br />
&nbsp;该需求的存在目的是什么？<br />
&nbsp;它的商业价值是否可以/如何用金钱来衡量？<br />
&nbsp;这个需求需要花费多少力量/金钱来完成？<br />
&nbsp;不做它的机会成本有多少？  <br />
<br />
2 需求的优先级：<br />
&nbsp;它比其他的需求更重要吗？<br />
&nbsp;它需要在下一个发布中完成吗？ <br />
有没有手动的方式可以暂时代替这个需求？
          <br/>
          <span style="color:red;">
            <a href="http://icecloud.javaeye.com/blog/34983#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 19 Nov 2006 23:35:40 +0800</pubDate>
        <link>http://icecloud.javaeye.com/blog/34983</link>
        <guid>http://icecloud.javaeye.com/blog/34983</guid>
      </item>
      <item>
        <title>测试了导入导出还不错</title>
        <author>冰云</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://icecloud.javaeye.com">冰云</a>&nbsp;
          链接：<a href="http://icecloud.javaeye.com/blog/34982" style="color:red;">http://icecloud.javaeye.com/blog/34982</a>&nbsp;
          发表时间: 2006年11月19日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          对于csdn blog的支持相当不赖，把我n年前的旧贴都导进来了。。。。假装没看到吧<br />
<br />
不过好像没法成功导msnspace的帖子，说找不到我blog<br />
<br />
最遗憾的是不支持导入其他blog的格式。。。我原来的可爱的blog自从当掉之后，我就只剩下sql和txt了，如果能支持就好了<br />
          <br/>
          <span style="color:red;">
            <a href="http://icecloud.javaeye.com/blog/34982#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 19 Nov 2006 23:12:37 +0800</pubDate>
        <link>http://icecloud.javaeye.com/blog/34982</link>
        <guid>http://icecloud.javaeye.com/blog/34982</guid>
      </item>
      <item>
        <title>敏捷需求分析</title>
        <author>冰云</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://icecloud.javaeye.com">冰云</a>&nbsp;
          链接：<a href="http://icecloud.javaeye.com/blog/34957" style="color:red;">http://icecloud.javaeye.com/blog/34957</a>&nbsp;
          发表时间: 2006年11月19日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          （本文发表于程序员杂志2006年第4期）<br /><br />在很多人的印象中，敏捷软件开发是种类似黑客行为的过程，是程序员最爱的勾当。不写文档，不作需求分析，没有项目经理，做什么东西完全是程序员自己的行为。所以他们认为这样的过程无法满足真正大型项目和复杂项目的需要，因此在经过考虑后，放弃了敏捷方法。<br /><br />真的是这样吗？敏捷过程到底是如何做需求分析？用户故事和用例有什么区别？敏捷过程如何去管理需求的？这些是一些想要实践敏捷的人一直在困惑的事情。<br /><br />我们常常看到书中讲，程序员拿到一个用户故事后，怎么计划，怎么分解，怎么写单元测试，怎么小步前进，怎么持续集成。这是典型的程序员视角。事实上，敏捷方法分为三部分，敏捷项目管理，敏捷需求分析，敏捷软件开发。上述书中提到的完全是敏捷开发中的实践，很多人了解到的敏捷，只是敏捷的三分之一。<br /><br />在敏捷的团队中，作一个敏捷程序员确实是非常舒服的事情。从程序员的角度来看，只需要选择一张他感兴趣的故事卡片，了解清楚该卡片的需求，开始从功能测试写代码，等通过了所有测试就完工。基本上不需要考虑太多的事情，非常轻松愉快。但程序员向谁去问清楚需求？故事卡片是怎样写出来的呢？让我们来关注开发前发生的事情。<br /><br />了解敏捷过程的人都知道，Kent Beck在XP过程中提到了现场客户，如果一个敏捷团队能够有现场客户，这当然是最棒的事情。但多数情况下，客户都是很忙碌的，很难全力投入到软件开发过程中。这时候，我们就需要商务分析师这个角色，来充当客户的角色。<br /><br />我在ThoughtWorks的团队中担任的就是商务分析师这个角色。商务分析师最重要的职责就是与客户交谈，了解和分析需求，将其制作成用户故事并将需求转述给程序员。同时，商务分析师也要代替客户负责功能验收测试。<br /><br />敏捷思想的核心是人与交流。需求问题实际上是一个交流问题。商务分析师要和客户交流，搞清楚客户到底需要什么，到底为什么需要这些东西。商业价值是商务分析师关注的最终目标。有了目标的指向，就可以不迷失方向。和客户进行交流，最终目的就是挖掘出客户的商业目标。可能大家会经常有这样的经验，客户说，我要这个功能，我想要怎么怎么样。这时候要特别注意，他说的这些东西并不是真正的需求。商务分析师需要详细的问客户为什么，挖掘出他真正的目标。<br /><br />在这个目标下，商务分析师开始进行需求的分析：我们到底是否真的需要这个需求？有没有更好的解决方案？有没有简单并且低廉的方式？换一种形式是不是也能达到这样的需求？这个需求有多少地方涉及到以前的软件变更？<br /><br />搞清楚这些事情后，就可以写出用户故事。用户故事的书写遵循一定的原则，一般包括三部分："作为（系统的一个涉众），我想要（做一件事），从而（达到一个商业价值）"。在书写的时候格式比较随意，可以在故事卡背面写上注释或疑问，甚至画上界面原形图。<br /><br />举一个最常见的用户故事例子，"作为一个普通用户，我希望能够用用户名和密码登录，以便我能享受到个性化的服务"。其中，用户是系统涉众，登录是他想要做的事情，而他的目标是获得个性化的服务。<br /><br />从这个例子我们可以想象到，这个页面可能存在两个文本框，用于输入用户名和密码，有一个按钮来登录，并且不登录就不能看到个人资料，另外，如果用户输入错误需要提示"登录失败请重试"。这就是可见性，也可以称为可测试性。我们可以根据这样的可见性写出功能测试，从而驱动这个用户故事的开发，这被称为 Acceptance Driven Development。<br /><br />用户故事的作用有两个，一个是作为进度跟踪的依据，一个是作为与人交谈的备忘录。用户故事卡片并不是很精确的需求，因此不需要把事情描述的非常清楚。将需求的详细分析推迟到实现前夕来完成，这是敏捷需求分析的精华所在。任何提前做好的东西都会导致浪费，敏捷过程提倡足够就好，避免浪费。<br /><br />不少人对用户故事和用例的区别感到疑惑。用户故事的作用是备忘功能，而不是文档。而用例需要详细的描述其操作步骤，以及每个异常路径，因而起到了文档的作用。用户故事是可见的商业价值，而不是功能描述。每个用户故事的粒度和工作量都相差不多，这和用例有很大的区别。用户故事是小粒度的，可测试的，可见的，并且是有价值的。[注:此处存有争议，请读者辨证阅读，勿断章取义]<br /><br />ThoughtWorks有个项目组作的是一个网游物品交易平台。该平台是典型的互联网项目，在开工的时候客户对功能需求还不明确，但需要快速推出抢占市场，正是最适合敏捷过程的项目。<br /><br />在项目伊始，商务分析师和客户做了深入的谈话，了解他的商业构想，他的盈利模式，搞清楚宏观的结构，然后思考并整理获得的结果，花1-2天时间将客户需求大略整理为几十个用户故事。这些用户故事并不完善，不足以做好整个系统。但对于我们开始项目的前一阵，已经足够了。我们可以从这里开始项目。<br /><br />敏捷方法希望快速交付可用的软件。实现软件的快速交付是通过迭代来完成。在迭代开始前，由一组有经验的开发人员大致评估一下用户故事，标记出不同的难度和风险，并提出问题供商务分析师来获得更详细的信息，商务分析师会和相关涉众去讨论。然后商务分析师将推荐优先级最高的一组用户故事给客户来挑选，客户可以选择这些用户故事，或者指出从他的视角看到的优先级更高的用户故事。这些将成为下一个迭代的内容。<br /><br />客户看到每个迭代交付的可运行的软件后或者得到用户反馈后，常常会有新的想法冒出来。有些想法是好的，有些想法就属于看到别家网站有这个功能，不假思索的提出的功能。这些不同的需求都需要经过认真的分析，找出哪些是值得我们立即考虑的，哪些是不用急迫的去实现的。<br /><br />有一次和客户谈话时，他说到希望增加拍卖功能。那么，我们为什么需要拍卖呢？客户说希望让用户拍卖物品以获得最高价格。经过考虑，我们发现，网游物品的实时性和唯一性决定了系统不适合使用拍卖机制。拍卖的时效性无法满足实时交易的要求，因此，用户最终放弃了这个特性。<br /><br />另一次，客服人员提出增加一个查询用户交易的功能，而此时我们有其他更加重要的功能需要先去考虑，查询用户交易功能可以由技术人员临时通过数据库直接代为查询，因为项目运营初期交易不是很多，暂时还不需要专门的后台功能来支持客服的工作。所以把这个需求卡片一直贴在墙壁上，始终没有排到最高的优先级。<br /><br />客户一开始也不是很能够接受敏捷需求中强调商业价值和优先级的做法。但经过几个月的磨合，客户也逐渐适应了许多敏捷思想，甚至我在和客户讨论时，偶然提起了后期的某种可能的情况，他们还能够帮我纠正应当考虑目前的情况，为近期的情况作计划。<br /><br />用户故事的跟踪和管理是由项目经理来进行。每个迭代跟踪卡片的进展，是否已经开始实现？是否已经完成代码开发？是否已经开始功能测试？不同的卡片在迭代前都会评估为不同的大小。我们一般分为大中小三级。等实践过几个迭代后，团队的开发速度基本保持恒定，我们就可以很容易的知道每个迭代能做多少个用户故事，这样就可以安排下一迭代的开发。<br /><br />每个迭代内分析好恰好足够下一个迭代开发的需求，就是商务分析师每个迭代的主要工作内容。商务分析师的需求分析工作在上一个迭代完成，包括需求的了解，分析，评估和排列优先级。<br /><br />在每个迭代开始的时候，由商务分析师主持召开迭代计划会议，在会议上向所有的程序员解释这个迭代要完成的用户故事，然后由程序员自由提问，知道他们能够获得足够开始实现该功能的信息。<br /><br />在程序员完成一个用户故事后，商务分析师还要来代表客户做功能验收测试，查看是否完成了预计的功能，是否有程序员还没有想到的异常情况。如果存在问题需要退回给程序员继续完成。这在一定程度上保证了系统完成的需求不偏离客户的要求。当然，更多的测试还需要QA来完成。<br /><br />我们的实践充分表明了，敏捷过程并不是没有需求分析，而是把需求分析过程分散到整个开发的过程中，让开发和需求分析并行进行。这就是ThoughtWorks敏捷方法实施成功的秘诀之一。而商务分析师在这个过程中，起到了纽带和桥梁的作用，是一个团队不可缺少的角色。
          <br/>
          <span style="color:red;">
            <a href="http://icecloud.javaeye.com/blog/34957#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 19 Nov 2006 22:56:59 +0800</pubDate>
        <link>http://icecloud.javaeye.com/blog/34957</link>
        <guid>http://icecloud.javaeye.com/blog/34957</guid>
      </item>
      <item>
        <title>MockObjects的选择：EasyMock与JMock的比较</title>
        <author>冰云</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://icecloud.javaeye.com">冰云</a>&nbsp;
          链接：<a href="http://icecloud.javaeye.com/blog/34958" style="color:red;">http://icecloud.javaeye.com/blog/34958</a>&nbsp;
          发表时间: 2004年06月04日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <div class="Section1" style="LAYOUT-GRID:  15.6pt none"><p class="MsoNormal"><b><span lang="EN-US" style="FONT-FAMILY: 'Courier New'">MockObjects</span></b><b><span style="FONT-FAMILY: 宋体">的选择：</span></b><b><span lang="EN-US" style="FONT-FAMILY: 'Courier New'">EasyMock</span></b><b><span style="FONT-FAMILY: 宋体">与</span></b><b><span lang="EN-US" style="FONT-FAMILY: 'Courier New'">JMock</span></b><b><span style="FONT-FAMILY: 宋体">的比较</span></b></p><p class="MsoNormal" style="TEXT-INDENT: 21pt"><span style="FONT-FAMILY: 宋体">本文假设读者已经了解了</span><span lang="EN-US" style="FONT-FAMILY: 'Courier New'">MockObjects</span><span style="FONT-FAMILY: 宋体">的使用目的和基本方式，不对</span><span lang="EN-US" style="FONT-FAMILY: 'Courier New'">MockTest</span><span style="FONT-FAMILY: 宋体">之类的技术作过多解释。仅提醒一句：</span><span lang="EN-US" style="FONT-FAMILY: 'Courier New'">“</span><span style="FONT-FAMILY: 宋体">不要测试你的</span><span lang="EN-US" style="FONT-FAMILY: 'Courier New'">MockObjects”</span><span style="FONT-FAMILY: 宋体">。</span></p><p class="MsoNormal" style="TEXT-INDENT: 21pt"><span style="FONT-FAMILY: 宋体">本文作为一个评测结果的同时，也可以作为</span><span lang="EN-US" style="FONT-FAMILY: 'Courier New'">EasyMock</span><span style="FONT-FAMILY: 宋体">和</span><span lang="EN-US" style="FONT-FAMILY: 'Courier New'">jMock</span><span style="FONT-FAMILY: 宋体">的简短教程。他们本身都很易用，可惜带的示例过于复杂，都用了过多的模式。看过本文的例子，相信就可以从容的在项目中使用了。</span></p><p class="MsoNormal" style="TEXT-INDENT: 21pt"><span lang="EN-US" style="FONT-FAMILY: 'Courier New'">Java</span><span style="FONT-FAMILY: 宋体">中常用的</span><span lang="EN-US" style="FONT-FAMILY: 'Courier New'">MockObjects</span><span style="FONT-FAMILY: 宋体">有</span><span lang="EN-US" style="FONT-FAMILY: 'Courier New'">EasyMock</span><span style="FONT-FAMILY: 宋体">和</span><span lang="EN-US" style="FONT-FAMILY: 'Courier New'">jMock</span><span style="FONT-FAMILY: 宋体">等。其中</span><span lang="EN-US" style="FONT-FAMILY: 'Courier New'">EasyMock</span><span style="FONT-FAMILY: 宋体">开发较早，已经出了</span><span lang="EN-US" style="FONT-FAMILY: 'Courier New'">1.1</span><span style="FONT-FAMILY: 宋体">版本，而</span><span lang="EN-US" style="FONT-FAMILY: 'Courier New'">jMock</span><span style="FONT-FAMILY: 宋体">前几天才刚推出了</span><span lang="EN-US" style="FONT-FAMILY: 'Courier New'">1.0 final</span><span style="FONT-FAMILY: 宋体">。作为刚成熟的小弟弟，</span><span lang="EN-US" style="FONT-FAMILY: 'Courier New'">jMock</span><span style="FONT-FAMILY: 宋体">有什么竞争实力呢？</span></p><p class="MsoNormal" style="TEXT-INDENT: 21pt"><span style="FONT-FAMILY: 宋体">本比较针对于以下几个方面，代码请见附件。</span></p><p class="MsoNormal" style="TEXT-INDENT: 21pt"><span lang="EN-US" style="FONT-FAMILY: 'Courier New'">1 </span><span style="FONT-FAMILY: 宋体">是否能够对具体类进行模拟（当然，对接口模拟是基本功能）</span></p><p class="MsoNormal" style="TEXT-INDENT: 21pt"><span lang="EN-US" style="FONT-FAMILY: 'Courier New'">2 </span><span style="FONT-FAMILY: 宋体">是否能够对方法名，参数，返回值进行动态控制</span></p><p class="MsoNormal" style="TEXT-INDENT: 21pt"><span lang="EN-US" style="FONT-FAMILY: 'Courier New'">3 </span><span style="FONT-FAMILY: 宋体">基本代码行数</span></p><p class="MsoNormal" style="TEXT-INDENT: 21pt"><span lang="EN-US" style="FONT-FAMILY: 'Courier New'">4 </span><span style="FONT-FAMILY: 宋体">是否能够对具有构造参数的具体类模拟</span></p><p class="MsoNormal"><span lang="EN-US" style="FONT-FAMILY: 'Courier New'">&nbsp;&nbsp;&nbsp; </span><span style="FONT-FAMILY: 宋体">现在比较开始了。首先制作若干测试文件，很简单。要模拟的有一个接口和一个具体类，叫做</span><span lang="EN-US" style="FONT-FAMILY: 'Courier New'">TheInterfaceToMock</span><span style="FONT-FAMILY: 宋体">和</span><span lang="EN-US" style="FONT-FAMILY: 'Courier New'">TheClassToMock</span><span style="FONT-FAMILY: 宋体">，另外，提供方法</span><span lang="EN-US" style="FONT-FAMILY: 'Courier New'">SampleReturn sampleMethod(Parameter p);</span><span style="FONT-FAMILY: 宋体">以及同名无参数方法。</span></p><p class="MsoNormal" align="left" style="TEXT-ALIGN: left"><span lang="EN-US" style="FONT-FAMILY: 'Courier New'">&nbsp;&nbsp;&nbsp; </span><span style="FONT-FAMILY: 宋体">第一个测试是针对</span><span lang="EN-US" style="FONT-FAMILY: 'Courier New'">TheInterfaceToMock</span><span style="FONT-FAMILY: 宋体">，提供</span><span lang="EN-US" style="FONT-FAMILY: 'Courier New'">ParameterImpl</span><span style="FONT-FAMILY: 宋体">和</span><span lang="EN-US" style="FONT-FAMILY: 'Courier New'">SampleReturnImpl</span><span style="FONT-FAMILY: 宋体">作为期待的参数和返回值。</span></p><p class="MsoNormal"><span lang="EN-US" style="FONT-FAMILY: 'Courier New'">&nbsp;&nbsp;&nbsp; jMock</span><span style="FONT-FAMILY: 宋体">代码如下：</span><span lang="EN-US" style="FONT-FAMILY: 'Courier New'">&nbsp;&nbsp; </span></p><table class="MsoTableGrid" cellspacing="0" border="1" cellpadding="0" style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse"><tbody><tr><td valign="top" width="568" style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #f3f3f3; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 426.1pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid"><p class="MsoNormal" align="left" style="TEXT-ALIGN: left"><b><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #7f0055; FONT-FAMILY: 'Courier New'">public</span></b><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'"> <b><span style="COLOR: #7f0055">class</span></b> <span style="COLOR: black">JMockUsage</span> <b><span style="COLOR: #7f0055">extends</span></b> <span style="COLOR: black">MockObjectTestCase</span> <span style="COLOR: black">{</span></span></p><p class="MsoNormal" align="left" style="TEXT-ALIGN: left"><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">&nbsp;&nbsp;&nbsp; <b><span style="COLOR: #7f0055">public</span></b> <b><span style="COLOR: #7f0055">void</span></b> <span style="COLOR: black">testReturnValueWithParemeter(){</span></span><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></p><p class="MsoNormal" align="left" style="TEXT-ALIGN: left"><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #3f7f5f">// </span></span><span style="FONT-SIZE: 9pt; COLOR: #3f7f5f; FONT-FAMILY: 宋体">构造</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #3f7f5f; FONT-FAMILY: 'Courier New'">Mock</span><span style="FONT-SIZE: 9pt; COLOR: #3f7f5f; FONT-FAMILY: 宋体">控制器</span></p><p class="MsoNormal" align="left" style="TEXT-ALIGN: left"><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: black">Mock</span> <span style="COLOR: black">m</span> <span style="COLOR: black">=</span> <b><span style="COLOR: #7f0055">new</span></b> <span style="COLOR: black">Mock(TheInterfaceToMock.</span><b><span style="COLOR: #7f0055">class</span></b><span style="COLOR: black">);</span></span></p><p class="MsoNormal" align="left" style="TEXT-ALIGN: left"><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #3f7f5f">// </span></span><span style="FONT-SIZE: 9pt; COLOR: #3f7f5f; FONT-FAMILY: 宋体">这是要测试</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #3f7f5f; FONT-FAMILY: 'Courier New'">MockObject</span></p><p class="MsoNormal" align="left" style="TEXT-ALIGN: left"><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: black">TheInterfaceToMock</span> <span style="COLOR: black">mock</span> <span style="COLOR: black">=</span> <span style="COLOR: black">(TheInterfaceToMock)</span> <span style="COLOR: black">m.proxy();</span></span></p><p class="MsoNormal" align="left" style="TEXT-ALIGN: left"><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #3f7f5f">// </span></span><span style="FONT-SIZE: 9pt; COLOR: #3f7f5f; FONT-FAMILY: 宋体">期待的返回值</span></p><p class="MsoNormal" align="left" style="TEXT-ALIGN: left"><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: black">SampleReturn</span> <span style="COLOR: black">sr</span> <span style="COLOR: black">=</span> <b><span style="COLOR: #7f0055">new</span></b> <span style="COLOR: black">SampleReturnImpl();</span></span></p><p class="MsoNormal" align="left" style="TEXT-ALIGN: left"><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #3f7f5f">// </span></span><span style="FONT-SIZE: 9pt; COLOR: #3f7f5f; FONT-FAMILY: 宋体">期待的参数</span></p><p class="MsoNormal" align="left" style="TEXT-ALIGN: left"><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: black">Parameter</span> <span style="COLOR: black">p</span> <span style="COLOR: black">=</span> <b><span style="COLOR: #7f0055">new</span></b> <span style="COLOR: black">ParameterImpl();</span></span></p><p class="MsoNormal" align="left" style="TEXT-ALIGN: left"><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></p><p class="MsoNormal" align="left" style="TEXT-ALIGN: left"><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #3f7f5f">// </span></span><span style="FONT-SIZE: 9pt; COLOR: #3f7f5f; FONT-FAMILY: 宋体">控制器，期待一次，方法</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #3f7f5f; FONT-FAMILY: 'Courier New'">sampleMethod</span><span style="FONT-SIZE: 9pt; COLOR: #3f7f5f; FONT-FAMILY: 宋体">，参数等于</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #3f7f5f; FONT-FAMILY: 'Courier New'">p(equals)</span><span style="FONT-SIZE: 9pt; COLOR: #3f7f5f; FONT-FAMILY: 宋体">，将返回</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #3f7f5f; FONT-FAMILY: 'Courier New'">sr</span></p><p class="MsoNormal" align="left" style="TEXT-ALIGN: left"><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: black">m.expects(once()).method(</span><span style="COLOR: #2a00ff">"sampleMethod"</span><span style="COLOR: black">)</span></span></p><p class="MsoNormal" align="left" style="TEXT-INDENT: 54pt; TEXT-ALIGN: left"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 'Courier New'">.with(eq(p)).will(returnValue(sr));</span></p><p class="MsoNormal" align="left" style="TEXT-ALIGN: left"><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></p><p class="MsoNormal" align="left" style="TEXT-ALIGN: left"><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #3f7f5f">// </span></span><span style="FONT-SIZE: 9pt; COLOR: #3f7f5f; FONT-FAMILY: 宋体">正式执行</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #3f7f5f; FONT-FAMILY: 'Courier New'">mockobject</span></p><p class="MsoNormal" align="left" style="TEXT-ALIGN: left"><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: black">SampleReturn</span> <span style="COLOR: black">ret</span> <span style="COLOR: black">=</span> <span style="COLOR: black">mock.sampleMethod(</span><b><span style="COLOR: #7f0055">new</span></b> <span style="COLOR: black">ParameterImpl());</span></span></p><p class="MsoNormal" align="left" style="TEXT-ALIGN: left"><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #3f7f5f">// </span></span><span style="FONT-SIZE: 9pt; COLOR: #3f7f5f; FONT-FAMILY: 宋体">确定返回值是相同的</span></p><p class="MsoNormal" align="left" style="TEXT-ALIGN: left"><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: black">assertSame(sr,ret);</span></span></p><p class="MsoNormal" align="left" style="TEXT-ALIGN: left"><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">&nbsp;&nbsp;&nbsp; <span style="COLOR: black">}</span></span></p><p class="MsoNormal" align="left" style="TEXT-ALIGN: left"><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'"></span>&nbsp;</p><p class="MsoNormal"><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: black; FONT-FAMILY: 'Courier New'">}</span></p></td></tr></tbody></table><p class="MsoNormal"><span lang="EN-US" style="FONT-FAMILY: 'Courier New'"></span>&nbsp;</p><p class="MsoNormal"><span style="FONT-FAMILY: 宋体">相同功能的</span><span lang="EN-US" style="FONT-FAMILY: 'Courier New'">easyMcok</span><span style="FONT-FAMILY: 宋体">代码如下：</span></p><table class="MsoTableGrid" cellspacing="0" border="1" cellpadding="0" style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse"><tbody><tr><td valign="top" width="568" style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #f3f3f3; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt solid; WIDTH: 426.1pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt solid"><p class="MsoNormal" align="left" style="TEXT-ALIGN: left"><b><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #7f0055; FONT-FAMILY: 'Courier New'">public</span></b><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'"> <b><span style="COLOR: #7f0055">class</span></b> <span style="COLOR: black">EasyMockUsage</span> <b><span style="COLOR: #7f0055">extends</span></b> <span style="COLOR: black">TestCase</span> <span style="COLOR: black">{</span></span></p><p class="MsoNormal" align="left" style="TEXT-ALIGN: left"><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">&nbsp;&nbsp;&nbsp; <b><span style="COLOR: #7f0055">public</span></b> <b><span style="COLOR: #7f0055">void</span></b> <span style="COLOR: black">testReturnValueWithParameter(){</span></span><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></p><p class="MsoNormal" align="left" style="TEXT-ALIGN: left"><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #3f7f5f">// </span></span><span style="FONT-SIZE: 9pt; COLOR: #3f7f5f; FONT-FAMILY: 宋体">构造</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #3f7f5f; FONT-FAMILY: 'Courier New'">mock</span><span style="FONT-SIZE: 9pt; COLOR: #3f7f5f; FONT-FAMILY: 宋体">控制器</span></p><p class="MsoNormal" align="left" style="TEXT-ALIGN: left"><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: black">MockControl</span> <span style="COLOR: black">control</span></span></p><p class="MsoNormal" align="left" style="TEXT-INDENT: 54pt; TEXT-ALIGN: left"><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">&nbsp;<span style="COLOR: black">=</span> <span style="COLOR: black">MockControl.createControl(TheInterfaceToMock.</span><b><span style="COLOR: #7f0055">class</span></b><span style="COLOR: black">);</span></span></p><p class="MsoNormal" align="left" style="TEXT-ALIGN: left"><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #3f7f5f">// </span></span><span style="FONT-SIZE: 9pt; COLOR: #3f7f5f; FONT-FAMILY: 宋体">这是要测试的</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #3f7f5f; FONT-FAMILY: 'Courier New'">MockObject</span></p><p class="MsoNormal" align="left" style="TEXT-ALIGN: left"><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: black">TheInterfaceToMock</span> <span style="COLOR: black">mock</span></span></p><p class="MsoNormal" align="left" style="TEXT-INDENT: 54pt; TEXT-ALIGN: left"><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">&nbsp;<span style="COLOR: black">=</span> <span style="COLOR: black">(TheInterfaceToMock)</span> <span style="COLOR: black">control.getMock();</span> </span></p><p class="MsoNormal" align="left" style="TEXT-ALIGN: left"><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #3f7f5f">// </span></span><span style="FONT-SIZE: 9pt; COLOR: #3f7f5f; FONT-FAMILY: 宋体">这是要返回的值</span><span style="FONT-SIZE: 9pt; COLOR: #3f7f5f; FONT-FAMILY: 'Courier New'"> </span></p><p class="MsoNormal" align="left" style="TEXT-ALIGN: left"><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: black">SampleReturn</span> <span style="COLOR: black">sr</span> <span style="COLOR: black">=</span> <b><span style="COLOR: #7f0055">new</span></b> <span style="COLOR: black">SampleReturnImpl();</span></span></p><p class="MsoNormal" align="left" style="TEXT-ALIGN: left"><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #3f7f5f">// </span></span><span style="FONT-SIZE: 9pt; COLOR: #3f7f5f; FONT-FAMILY: 宋体">这是要传入的参数</span></p><p class="MsoNormal" align="left" style="TEXT-ALIGN: left"><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: black">Parameter</span> <span style="COLOR: black">p</span> <span style="COLOR: black">=</span> <b><span style="COLOR: #7f0055">new</span></b> <span style="COLOR: black">ParameterImpl();</span></span></p><p class="MsoNormal" align="left" style="TEXT-ALIGN: left"><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></p><p class="MsoNormal" align="left" style="TEXT-ALIGN: left"><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #3f7f5f">// </span></span><span style="FONT-SIZE: 9pt; COLOR: #3f7f5f; FONT-FAMILY: 宋体">恢复到记录</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #3f7f5f; FONT-FAMILY: 'Courier New'">(record)</span><span style="FONT-SIZE: 9pt; COLOR: #3f7f5f; FONT-FAMILY: 宋体">状态</span></p><p class="MsoNormal" align="left" style="TEXT-ALIGN: left"><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: black">control.reset();</span></span></p><p class="MsoNormal" align="left" style="TEXT-ALIGN: left"><span lang="EN-US" style="FONT-SIZE: 9pt; FONT-FAMILY: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="COLOR: #3f7f5f">// </span></span><span style="FONT-SIZE: 9pt; COLOR: #3f7f5f; FONT-FAMILY: 宋体">首先记录</span><span lang="EN-US" style="FONT-SIZE: 9pt; COLOR: #3f7f5f; FONT-FAMILY: 'Courier New'">sampleMethod</span><span style="FONT-SIZE: 9pt; COL