<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
 <channel>
  <title>朱雀雀的巴士站</title>
  <link>http://phoenixtoday.blogbus.com</link>
  <description><![CDATA[上车，驶向远方......]]></description>
  <generator> by blogbus.com </generator>
  <lastBuildDate>Thu, 10 Dec 2009 17:04:58 +0800</lastBuildDate>
  <image>
									<url>http://public.blogbus.com/profile/head.gif</url>
									<title>朱雀雀的巴士站</title>
									<link>http://phoenixtoday.blogbus.com</link>
								</image>  <item>
   <title>关于REST API设计的一些小经验</title>
   <description><![CDATA[<p>最近小组里有一些关于REST API设计的讨论，有些收获，打算在这里写一下。通常来讲设计第一个版本的REST API并不难，难点在于将来你要改变了这些API，而客户那里已经有对应的客户端实现，
<script src="http://www.blogbus.com/user/tiny_mce/themes/advanced/langs/zh.js?4" type="text/javascript"></script>
那么你怎么保证兼容？或者，至少，你应当让这些东西失效吧，这样客户才能知道。所以基本上就是两个问题。</p>
<p>1，在最初设计时，如何尽量保证向后兼容？（这里不提倡过度设计噢，我们是搞敏捷的，哈哈）</p>
<p>2，如果API发生了改变，该怎么通知已有实现？</p>
<p>对于第一个问题，答案相对而言简单一些：支持必要的，但是最少的东西，而且层次不要太多。为什么？用下面的xml，举个例子来说</p>
<p>&nbsp;</p>
<p>&lt;person&gt;</p>
<p>&nbsp;&nbsp;&lt;name&gt;phoenix&lt;/name&gt;</p>
<p>&nbsp;&nbsp;&lt;job&gt;softerware developer&lt;/job&gt;</p>
<p>&nbsp;&nbsp;&lt;company&gt;ThoughtWorks&lt;/company&gt;</p>
<p>&lt;/person&gt;</p>
<p>&nbsp;</p>
<p>第一层，指的是这个xml具体针对什么，第二层有三个属性，分别是name，job和company，这是一个嵌套层次很好的，而且也没有包含过多的信息。但是如果我们在一开始再加上address属性（假设它并非必要），那么如果客户构建了一个客户端也的确包含了address属性，那么在下一个版本的API中，你把这个属性去掉了。问题是不是出现了？客户的软件无法工作了。反过来，如果最开始的版本不包含address，但是有客户强烈要求下一个版本要支持，那么怎么办？简单！在下一个版本加上就好了，对于已有的客户端，多一行冗余数据而已，也不会导致客户的软件无法工作。好了，这个问题解决了，那么，什么是嵌套层次不要太多。举个反例</p>
<p>&nbsp;</p>
<p>&lt;person&gt;</p>
<p>&nbsp;&nbsp;&lt;name&gt;phoenix&lt;/name&gt;</p>
<p>&nbsp;&nbsp;&lt;job&gt;softerware developer&lt;/job&gt;</p>
<p>&nbsp;&nbsp;&lt;company&gt;</p>
<p>&nbsp;&nbsp; &nbsp;&lt;name&gt;ThoughtWorks&lt;/name&gt;</p>
<p>&nbsp;&nbsp; &nbsp;&lt;locations type="array"&gt;</p>
<p>&nbsp;&nbsp; &nbsp; &nbsp;&lt;city&gt;beijing&lt;/city&gt;</p>
<p>&nbsp;&nbsp; &nbsp; &nbsp;&lt;city&gt;san francisco&lt;/city&gt;</p>
<p>&nbsp;&nbsp; &nbsp;&lt;/locations&gt;</p>
<p>&nbsp;&nbsp; &nbsp;&lt;products&gt;</p>
<p>&nbsp;&nbsp; &nbsp; &nbsp;&lt;product&gt;</p>
<p>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&lt;name&gt;mingle&lt;/name&gt;</p>
<p>&nbsp;&nbsp; &nbsp; &nbsp;&lt;/product&gt;</p>
<p>&nbsp;&nbsp; &nbsp; &nbsp;&lt;product&gt;</p>
<p>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&lt;name&gt;cruise&lt;/name&gt;</p>
<p>&nbsp;&nbsp; &nbsp; &nbsp;&lt;/product&gt;</p>
<p>&nbsp;&nbsp; &nbsp; &nbsp;&lt;product&gt;</p>
<p>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&lt;name&gt;twist&lt;/name&gt;</p>
<p>&nbsp;&nbsp; &nbsp; &nbsp;&lt;/product&gt;</p>
<p>&nbsp;&nbsp; &nbsp;&lt;/products&gt;</p>
<p>&nbsp;&nbsp;&lt;/company&gt;</p>
<p>&lt;/person&gt;</p>
<p>&nbsp;</p>
<p>这叫层次太多！一个company里，包含了太多的嵌套信息，其中location还算说的过去（因为只是一个简单的数组），但是products里包含了子对象就不对了，这就是第三层对象了，具体的解决方案可以利用url来替换掉。世界终于清静啦！</p>
<p>可是我还不能清静，因为要回答第二个问题：API改变了，该怎么通知已有实现？这是一个很头疼的问题，如果能避免回答我绝对会避免，可惜，不能！通常有两种解决方案，但目的都是为了让客户的软件失效（我知道，我知道，这会让客户抓狂，可是我们也没辙啊！所以还是能不动，则不动，打死也不动，打不死嘛......就按如下办）a，使用带有版本号的API URL（这是现在最经常使用的一种方法），例如api/v2/projects/members.xml前面的api不说也明白，v2就是version 2版本2的意思，如果更换了，就变v3，客户的软件不能用了，也就知道了；b，利用HTTP header 里的ACCEPT来解决（别说你写了这么多年程序，连HTTP有HEAD都不知道啊！会被鄙视的！），ACCEPT可以设置接受的文件，你可以将版本信息放在里面。技术细节不多说了，给个链接，供大家参考&nbsp;<a href="http://barelyenough.org/blog/2008/05/versioning-rest-web-services/" target="_blank">http://barelyenough.org/blog/2008/05/versioning-rest-web-services/</a> 其实我是比较赞成这种方式的，比较优雅，但缺点就是它还不是标准，对方的程序员也可能不知道HTTP有HEAD，所以做起来，对人家可能会有点复杂，这里就不再多说了。</p>
<p>总之昵～～，小初（想必盯我博客很久的人，也都知道我姓甚名谁了，以后我就用真名了）的技术博客在沉寂了，这么久之后，又回来了（我胡XX又回来啦！哈哈），有太多东西要写了，以后会陆续带给大家的，多谢捧场！</p>
<p>PS:为啥Blogbus不支持&lt;pre&gt;标签呢，让我的xml这么丑的出现在博客里？惭愧呀！</p><!--sp--><div class="relpost"><br/><h3>随机文章：</h3><div><a href="http://phoenixtoday.blogbus.com/logs/29434524.html">将欲强之，必故弱之──记 Mingle 性能调优</a> 2008-09-20</div><div><a href="/logs/35149540.html">活灵活现用Git-技巧篇</a> 2009-02-13</div><div><a href="/logs/33458940.html">活灵活现用Git--基础篇</a> 2009-01-05</div><div><a href="/logs/26994984.html">Textmate 快捷键总结</a> 2008-08-04</div><div><a href="/logs/14581935.html">朱雀雀的图</a> 2008-01-27</div></div><div class="addfav"><br />收藏到：<span class= "delicious"><a href="http://delicious.com/save?url=http%3A%2F%2Fphoenixtoday.blogbus.com%2Flogs%2F45855234.html&title=%E5%85%B3%E4%BA%8EREST+API%E8%AE%BE%E8%AE%A1%E7%9A%84%E4%B8%80%E4%BA%9B%E5%B0%8F%E7%BB%8F%E9%AA%8C">Del.icio.us</a></span></div><br /><br /><div class="sysmsg"><b><a href="http://pindao.blogbus.com/fengshang?utm_source=blogbus&utm_medium=rss&utm_campaign=fengshang" target="_blank">风尚频道——国内顶尖的时尚族群汇聚于此，未必是流行，但一定要有品位。</a></b></div><br /><br />]]></description>
   <link>http://phoenixtoday.blogbus.com/logs/45855234.html</link>
   <author></author>
   <pubDate>Sat, 05 Sep 2009 20:44:19 +0800</pubDate>
  </item>
  <item>
   <title>翻译Agile Adoption Patterns: A Roadmap to Organizational Success 一书发现的一些常见问题</title>
   <description><![CDATA[<p style="text-align: left; "><span style="font-family: mceinline; font-size: medium;"><span style="font-size: 16px;">
<!--StartFragment-->
</span></span></p>
<p class="MsoNormal" style="margin-bottom: 14.0pt; line-height: 22.0pt; mso-pagination: none; mso-layout-grid-align: none; text-autospace: none;">Agile Adoption Patterns: A
Roadmap to Organizational Success，这本书是讲述如何从非敏捷过程平滑的迁移到敏捷过程，挺喜欢这本书并决定翻译它的主要原因，是它里面不仅仅介绍了敏捷实践方法，更一语道破了软件开发中的关键两点：一、学习是瓶颈；二、交流和人是主要的。</p>
<p class="MsoNormal" style="margin-bottom: 14.0pt; text-align: center; line-height: 22.0pt; mso-pagination: none; mso-layout-grid-align: none; text-autospace: none;" align="center"><img src="http://phoenixtoday.blogbus.com/files/12413579170.jpg" border="0" alt="" />&nbsp;</p>
<p class="MsoNormal" style="margin-bottom: 14.0pt; line-height: 22.0pt; mso-pagination: none; mso-layout-grid-align: none; text-autospace: none;">现在的进度是，三个人大概翻译了一小半，作为组织者，最近整合大家的手稿，发现许多翻译英文文献中常见的问题。值得总结一下：</p>
<p class="MsoNormal" style="margin-bottom: 14.0pt; line-height: 22.0pt; mso-pagination: none; mso-layout-grid-align: none; text-autospace: none;">1、太多的&ldquo;你&rdquo;，&ldquo;你的&rdquo;，&ldquo;你们&rdquo;，&ldquo;他们&rdquo;等等。英语的语法有主、谓、宾，例如&rdquo;So
you are interested in Agile development. Why? Chances are, you want to improve
your software development process&ldquo;，每句都一个you，第二句还有一个your如果中文照着翻译，就变成了&rdquo;为什么你对敏捷开发感兴趣？可能你想改进你的软件开发过程。&ldquo;。从头到尾读一下中文的句子，你会发现，别扭。可是又说不出来在哪里，那么换成这样如何？&rdquo;为什么对敏捷开发感兴趣？想改进你的软件开发过程？&ldquo;，感觉通顺多了吧？我去掉了两个&rdquo;你&ldquo;，这才是大家说话的方法</p>
<p class="MsoNormal" style="margin-bottom: 14.0pt; line-height: 22.0pt; mso-pagination: none; mso-layout-grid-align: none; text-autospace: none;">2、词语不统一。这种情况在多人合译的时候，尤其普遍。我的小组会共享一个Google文档，里面是我们的词汇表，记录了我们遇到的关键词，定期碰头统一词汇</p>
<p class="MsoNormal" style="margin-bottom: 14.0pt; line-height: 22.0pt; mso-pagination: none; mso-layout-grid-align: none; text-autospace: none;">3、中文的精炼性。中文比英语精炼，我们平时说话，很少一气儿说很长的句子。而英语不是，句子的从句一串串。这个时候，我们就要学会断句。其实翻译主要是意译，如果觉得长句实在别扭，将整句读懂，撇开原作，用你的语言写出来，你会发现其实就是这么回事</p>
<p class="MsoNormal" style="margin-bottom: 14.0pt; line-height: 22.0pt; mso-pagination: none; mso-layout-grid-align: none; text-autospace: none;">4、这就引出了断句的问题。你都意译了，那断句和标点符号，就自然按照我们的习惯来了，我和我的朋友们在翻译的初期，生怕翻译错了，所以尽量按照原文走，句子都不敢改。其实这是错误的，这本书讲敏捷，敏捷依靠学习，学习依靠犯错误，因为人类的学习就是从犯错误成长，哪有人第一次写程序就能达到完美的？恐怕连第一个int都要想半天，查查书才知道。翻译一个道理，大胆翻译，犯错了有别人审查呢（当然这不表示你不负责任的乱翻）</p>
<p class="MsoNormal" style="margin-bottom: 14.0pt; line-height: 22.0pt; mso-pagination: none; mso-layout-grid-align: none; text-autospace: none;">5、漏翻。这就不用多说了，漏翻是不好的。有的时候遇到困难，千万不要空过去，标记个颜色，过几天再回头看看。如果空过去，很可能造成漏翻</p>
<p class="MsoNormal">6、中文的连贯性。有的时候，我们要想翻译的更&rdquo;像&ldquo;中文（哈哈，姑且用&rdquo;像&ldquo;来形容吧）。就需要将一些句子连起来，&rdquo;如果 就&ldquo;，&rdquo;不但 而且&ldquo;，&rdquo;不是 而是&ldquo;等等，这些连词要好好使用</p>
<p class="MsoNormal">很久没写Blog了，要努力呀</p>
<!--EndFragment-->
<p>&nbsp;</p><!--sp--><div class="relpost"><br/><h3>随机文章：</h3><div><a href="http://phoenixtoday.blogbus.com/logs/30107647.html">翻译的InfoQ 书评： 敏捷模式</a> 2008-10-10</div><div><a href="http://phoenixtoday.blogbus.com/logs/28533541.html">ThoughtWorks University 取经记(续)</a> 2008-09-04</div><div><a href="http://phoenixtoday.blogbus.com/logs/27454013.html">ThoughtWorks University 取经记</a> 2008-08-09</div><div><a href="http://phoenixtoday.blogbus.com/logs/25557507.html">体验真正的敏捷</a> 2008-07-25</div><div><a href="http://phoenixtoday.blogbus.com/logs/16034205.html">内部黄金时间与外部黄金时间对于敏捷</a> 2008-02-26</div></div><div class="addfav"><br />收藏到：<span class= "delicious"><a href="http://delicious.com/save?url=http%3A%2F%2Fphoenixtoday.blogbus.com%2Flogs%2F38881265.html&title=%E7%BF%BB%E8%AF%91Agile+Adoption+Patterns%3A+A+Roadmap+to+Organizational+Success+%E4%B8%80%E4%B9%A6%E5%8F%91%E7%8E%B0%E7%9A%84%E4%B8%80%E4%BA%9B%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98">Del.icio.us</a></span></div><br /><br /><div class="sysmsg"><b><a href="http://pindao.blogbus.com/xingzhe?utm_source=blogbus&utm_medium=rss&utm_campaign=xingzhe" target="_blank">行者频道——从普通游客到资深背包族，跟随Ta们的镜头游遍全世界。</a></b></div><br /><br />]]></description>
   <link>http://phoenixtoday.blogbus.com/logs/38881265.html</link>
   <author></author>
   <pubDate>Sun, 03 May 2009 22:06:01 +0800</pubDate>
  </item>
  <item>
   <title>活灵活现用Git-技巧篇</title>
   <description><![CDATA[<p>
 
 上一篇介绍了Git的基本概念和一些基本命令，本篇的重点在如下三个部分：个性化定制你的Git，更酷更巧妙的使用Git，以及如何在Git
Hub上开启你自己的开源项目。在所有技巧中，最重要的技巧是学会查看Git的帮助，因为Git是一个相对复杂的版本控制工具，如果你熟悉它的命令，那么
给你带来的价值是不言而喻的，所以要学会掌握那根金手指─查看Git的帮助，在任何Git命令后加上'--help'就会显示该命令的帮助文档，例如
'git log --help'你就可以看到命令'git log'的所有使用方法。接下来，从打扮Git开始吧。</p>
<div>
<div>
 <br />
 Git梳妆<br />
 </div>
我们可以利用Git的config命令或者直接编辑~/.gitconfig文件（如果没有的话创建它）来为自己打造独一无二的Git。我建议直接编辑用户目录下得.gitconfig文件，拿我本地的文件为例，一一为大家解说，完整的文件内容如下：<br />
 <br style="background-color: #cccccc;" />
 <span style="background-color: #b6d7a8;">[user]</span><br style="background-color: #b6d7a8;" />
 <span style="background-color: #b6d7a8;">&nbsp;&nbsp;&nbsp; name = Phoenix</span><br style="background-color: #b6d7a8;" />
 <span style="background-color: #b6d7a8;">&nbsp;&nbsp;&nbsp; email = phoenixtoday@gmail.com</span><br style="background-color: #b6d7a8;" />
 <span style="background-color: #b6d7a8;">[alias]</span><br style="background-color: #b6d7a8;" />
 <span style="background-color: #b6d7a8;">&nbsp; co = checkout</span><br style="background-color: #b6d7a8;" />
 <span style="background-color: #b6d7a8;">&nbsp; ci = commit -a</span><br style="background-color: #b6d7a8;" />
 <span style="background-color: #b6d7a8;">&nbsp; st = status</span><br style="background-color: #b6d7a8;" />
 <span style="background-color: #b6d7a8;">&nbsp; br = branch</span><br style="background-color: #b6d7a8;" />
 <span style="background-color: #b6d7a8;">&nbsp; oneline = log --pretty=oneline --since='2 days ago'</span><br style="background-color: #b6d7a8;" />
 <span style="background-color: #b6d7a8;">&nbsp; onelog = log -p -1</span><br style="background-color: #b6d7a8;" />
 <span style="background-color: #b6d7a8;">[color]</span><br style="background-color: #b6d7a8;" />
 <span style="background-color: #b6d7a8;">&nbsp; status = auto</span><br style="background-color: #b6d7a8;" />
 <span style="background-color: #b6d7a8;">&nbsp; branch = auto</span><br style="background-color: #b6d7a8;" />
 <span style="background-color: #b6d7a8;">&nbsp; ui = auto</span><br />
 <br />
 该文件主要包含三个部分的内容：<br />
 
<ul>
<li>
 用户基本信息：可以设置你的名字和email，这样在你提交代码的时候就会显示出你的名字
 </li>
<li>
命令别名：这是.gitconfig文件中，我最喜欢的部分，它可以大大减少你敲击键盘的次数（俗话说优秀的程序员都很懒么）。在该文件中，我将co设置
为checkout的别名，那么下次我只要用'git co
new_branch'就可以切换到new_branch分支下了，简洁而优雅；将ci设置为commit
-a的别名，-a选项表示我不需要将修改和删除的文件通过'git add'命令来加入索引，这样设置在使用'git ci
-m"message"'这样的命令时，相当于连续执行了'git add 被修改和删除的文件'和'git commit
-m"message"'两条命令，再一次节省了我们宝贵的时间；最酷的是最后两行，后面的章节会一一介绍。Git提供许多优雅、人性化的选项，我们如果
再结合别名的设置，可以发挥你最大的想象力，真的让你自己的Git活起来 </li>
<li>
 颜色：每次看diff时是不是挺痛苦的？那么为什么不给我们的Git加上颜色呢？只需要加上那三行，就可以让红色和绿色的提示出现在你的控制台中
 </li>
</ul>
<br />
 Git灵动<br />
 现在来讲讲'git log'，'git stash'，'git formate-patch'三个命令的用法和技巧：<br />
 
<ul style="text-align: left;">
<li>
git log：不同于SVN，Git将代码的历史记录全部在本地克隆了一份，所以这就使得'git
log'这样的命令使用起来非常的迅速，也是我最常使用的Git命令之一。在使用'git
log'的时候，你可以加入很多的后缀。'-p'表示查看修改的具体内容，例如'git log
-p'它不但会打印出提交的时间、版本号、人员等，还会将具体的代码修改部分打印出来；'-n'其中n表示一个数字，这表示打印出具体的几个日志，例如
'git -p
-1'正如我的Git配置文件中设置的onelog别名的内容一样，就表示打印出当前最新的一次日志记录及具体修改内容；'--since="时间/日
期"'，'--until="时间/日期"'表示你希望查找某个日期段的日志记录，例如'git log --since="2 days ago"
--until="1 hour ago"'就表示你希望查找两天前到一小时前的日志记录，Git是足够聪明的，它可以将类似于'2 days
ago'和'1 hour
ago'这种表示时间的英语转化为具体的时间数字；有的时候，你不希望翻很多页才可以看到所有的日志，你只希望看到简短的说明，那么Git为你提供打印格
式的定制'git --pretty=格式种类'，其中格式种类有full、short、oneline等，例如'git log
pretty=oneline'就会将每条代码历史记录放在一行里，看起来简单明了 </li>
<li> git
stash：在第一篇中，我举了一个使用branch解决紧急任务切换的问题，其实stash命令也可以很好的解决这样的问题。当你不想提交当前完成了一
半的代码，但是却不得不修改一个紧急Bug，那么使用'git
stash'就可以将你当前未提交到本地（和服务器）的代码推入到Git的栈中，这时候你的工作区间和上一次提交的内容是完全一样的，所以你可以放心的修
Bug，等到修完Bug，提交到服务器上后，再使用'git stash
apply'将以前一半的工作应用回来。也许有的人会说，那我可不可以多次将未提交的代码压入到栈中？答案是可以的。当你多次使用'git
stash'命令后，你的栈里将充满了未提交的代码，这时候你会对将哪个版本应用回来有些困惑，'git stash
list'命令可以将当前的Git栈信息打印出来，你只需要将找到对应的版本号，例如使用'git stash apply
stash@{1}'就可以将你指定版本号为stash@{1}的工作取出来，当你将所有的栈都应用回来的时候，可以使用'git stash
clear'来将栈清空 </li>
<li> git
format-patch：当你想给一个开源项目（例如Rails）提交一段代码的时候，或者你想给小组成员展示一段你并不想提交的代码，那么你还是需要
patch的，Git的'format-patch'命令良好的支持了这个功能。我来基本描述一下使用这个命令的步骤和方法：第一，利用branch命令
创建一个分支；第二，修改你的代码；第三，在该分支上提交你的修改；第四，使用'git
format-patch'命令来生成一个patch文件，例如：'git format-patch master --stdout &gt;
~/Desktop/tmp.patch'就是将工作分支与master主干的不同，存放在'~/Desktop'文件夹下，生成一个叫做
tmp.patch的文件（另一种简单的版本是利用diff命令，例如'git diff ..master &gt;
~/Desktop/tmp.patch'），这样就生成了patch文件。那么别人就可以使用'git
apply'命令来应用patch，例如'git apply ~/Desktop/tmp.patch'就是将patch打在当前的工作分支上
 </li>
</ul>
<br />
 Git亲友团<br />
 Git的使用技巧还包括利用Git包含的和附加的一些强大工具，这些工具主要包括git svn、git citool、gitk和Git的自动提示脚本：<br />
 
<ul>
<li>
git
svn：Git和SVN可以很方便的集成在一起，这就大大减少了从SVN向Git迁移的学习成本，这也是我特别建议大家首次接触Git的使用方式。git
svn是一个Git内置的工具，你安装了Git也就安装了它，譬如说你们团队有一个SVN服务器，但是你想利用Git本地的一些强大特性，那么你依然可以
安装Git，使用Git的branch功能，只不过再更新代码和提交代码的时候，使用git
svn命令即可。在这里我简单的讲讲最常使用和需要注意的两个命令，其余的命令读者可以通过'git svn --help'来查看：'git svn
rebase'命令取代了'svn update'用于将服务器代码更新到本地；'git svn dcommit'取代了'svn
ci'，需要注意的是，本地必须用Git提交了代码之后，再使用'git svn
dcommit'。只需要这样，你就可以轻松地从SVN转向Git了。 </li>
<li>
 git citool：这是我个人使用率最频繁的一个工具，上一篇文章也提到了，Git可以本地提交代码，那么你自然可以本地修改你的提交了，这个工具就是可视化界面，用于修改你本地的提交。只要在你的工作区间输入'git citool'，就会出现如下的界面
<div id="g976" style="padding: 1em 0pt; text-align: left;">
 <img src="http://docs.google.com/File?id=dcvntvfs_194c6f5vhhd_b" alt="" width="811" height="447" />
 </div>
</li>
</ul>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 你可以用它来提交代码，可以用它来将你本地的修改追加在上一次提交的代码中，你还可以用它来修改你上次提交的信息等等。这个工具可以大大帮助你完成以前SVN不可能完成的任务<br />
<ul>
<li>gitk：是一个查看主干/分支情况的工具，它主要用于观察整个项目的分支状况，使用'gitk'命令就会出现一个图形化界面供你查看，本篇就简单的说一下，大家回去试试就知道了</li>
<li>Git
的自动提示脚本：它是Shawn O.
Pearce为了让Git使用起来更方便而写得Shell脚本，你可以在http://gitweb.hawaga.org.uk/
找到一个叫做gitcompletion的脚本，下载下来，并按照该脚本中指导的方式进行配置，你就具有了Git自动提示（敲入部分Git命令，再按
Tab键）的功能，而且有了这个脚本，你也可以看到你当前工作在哪个branch下。惟一的不足是，它只支持Linux、Unix、Mac操作系统（推荐
大家都用Mac进行开发）</li>
</ul>
</div>
<div>
 <br />
 Git实战─Git Hub<br />
 经过这么长时间理论知识的熏陶，想必大家早已跃跃欲试了，那么我们在Git Hub上建立一个开源项目作为实战演习吧。Git Hub是全球最大的Git服务器供应商，每个帐号有100M的免费使用空间，网址是：https://github.com/<br />
<ul>
<li>首先我们在Git Hub上创建一个帐号，按照上面指导的方法设置好你的认证信息（每次提交代码都会需要这个认证信息）</li>
<li>然后，如下图新建一个项目(选择<span style="font-size: x-small;">Create a New Repository</span>)，名叫git usage<br />
<div id="lf98" style="padding: 1em 0pt; text-align: left;">
<div id="z-cg" style="padding: 1em 0pt; text-align: left;"><img src="http://docs.google.com/File?id=dcvntvfs_196cpc27hck_b" alt="" width="798" height="413" /></div>
</div>
</li>
<li>在服务器端，你可以看到这个项目的信息，包括项目源代码的URL，如下图
<div id="uajo" style="padding: 1em 0pt; text-align: left;"><img style="width: 395px; height: 114px;" src="http://docs.google.com/File?id=dcvntvfs_197gstpwmgt_b" alt="" /></div>
</li>
<li>在本地使用如下的命令，就可以完成你的第一次提交了：</li>
</ul>
<br />
<pre>&nbsp;&nbsp; &nbsp;mkdir git-usage（创建项目目录）<br />&nbsp;&nbsp; &nbsp;cd git-usage（进入项目目录）<br /> &nbsp;&nbsp;git init（Git初始化）<br /> &nbsp;&nbsp;touch README（创建一个README文件）<br />&nbsp;&nbsp; &nbsp;git add README（增加该文件到索引）<br />&nbsp;&nbsp; &nbsp;git commit -m 'first commit'（本地提交）<br />&nbsp;&nbsp; &nbsp;git remote add origin git@github.com:phoenixtoday/git-usage.git（增加远程服务器代码库地址）<br />&nbsp;&nbsp; &nbsp;git push origin master（将本地代码提交到远程服务器上）</pre>
</div>
<div>
 总结<br />
</div>
<p>我所在的项目小组自从使用Git后，发现Git提供的种种特性大大提高了我们的开发效率，在认识Git前我们无法想象一个版本控制工具可以让开发任务切换变得如此自然流畅。所以我强烈推荐大家使用Git，你付出的学习绝对物有所值</p><!--sp--><div class="relpost"><br/><h3>随机文章：</h3><div><a href="http://phoenixtoday.blogbus.com/logs/33458940.html">活灵活现用Git--基础篇</a> 2009-01-05</div><div><a href="http://phoenixtoday.blogbus.com/logs/27454013.html">ThoughtWorks University 取经记</a> 2008-08-09</div><div><a href="http://phoenixtoday.blogbus.com/logs/28533541.html">ThoughtWorks University 取经记(续)</a> 2008-09-04</div><div><a href="http://phoenixtoday.blogbus.com/logs/25557507.html">体验真正的敏捷</a> 2008-07-25</div><div><a href="http://phoenixtoday.blogbus.com/logs/16550157.html">初探OSGi 的全文</a> 2008-03-07</div></div><div class="addfav"><br />收藏到：<span class= "delicious"><a href="http://delicious.com/save?url=http%3A%2F%2Fphoenixtoday.blogbus.com%2Flogs%2F35149540.html&title=%E6%B4%BB%E7%81%B5%E6%B4%BB%E7%8E%B0%E7%94%A8Git-%E6%8A%80%E5%B7%A7%E7%AF%87">Del.icio.us</a></span></div><br /><br /><div class="sysmsg"><b><a href="http://tuijian.blogbus.com/" target="_blank">推荐：让我们寻找最优秀的Blogger！</a></b></div><br /><br />]]></description>
   <link>http://phoenixtoday.blogbus.com/logs/35149540.html</link>
   <author></author>
   <pubDate>Fri, 13 Feb 2009 18:38:10 +0800</pubDate>
  </item>
  <item>
   <title>活灵活现用Git--基础篇</title>
   <description><![CDATA[<span style="font-family: 'Times New Roman'; font-size: 16px; line-height: normal" class="Apple-style-span"><div style="min-height: 1100px; counter-reset: __goog_page__ 0; font-family: Verdana; font-size: 10pt; line-height: normal; background-color: #ffffff; padding: 0px; margin: 6px"><div style="margin-top: 0px; margin-bottom: 0px"><div style="margin-top: 0px; margin-bottom: 0px">这是程序员2009年1月份发表的文章，只是上半部分，下半部分下个月继续发表，呵呵，2009年不错的开端。不过Git 真的是很不错的东西，跟大家一起分享使用经验</div><div style="margin-top: 0px; margin-bottom: 0px">&nbsp;</div><div style="text-align: center; margin-top: 0px; margin-bottom: 0px"><font size="5">活灵活现用Git-基础篇</font><br /></div><br />Git是一个分布式的版本控制工具，本篇文章从介绍Git开始，重点在于介绍Git的基本命令和使用技巧，让你尝试使用Git的同时，体验到原来一个版本控制工具可以对开发产生如此之多的影响，文章分为两部分，第一部分介绍Git的一些常用命令，其中穿插介绍Git的基本概念和原理，第二篇重点介绍Git的使用技巧，最后会在Git Hub上创建一个开源项目开启你的Git实战之旅<br /><br />Git是什么<br />Git在Wikipedia上的定义：它是一个免费的、分布式的版本控制工具，或是一个强调了速度快的源代码管理工具。Git最初被Linus Torvalds开发出来用于管理Linux内核的开发。每一个Git的工作目录都是一个完全独立的代码库，并拥有完整的历史记录和版本追踪能力，不依赖于网络和中心服务器。<br /><br />Git的出现减轻了许多开发者和开源项目对于管理分支代码的压力，由于对分支的良好控制，更鼓励开发者对自己感兴趣的项目做出贡献。其实许多开源项目包括Linux kernel, Samba, X.org Server, Ruby on Rails，都已经过渡到使用Git作为自己的版本控制工具。对于我们这些喜欢写代码的开发者嘛，有两点最大的好处，我们可以在任何地点（在上班的地铁上）提交自己的代码和查看代码版本；我们可以开许许多多个分支来实践我们的想法，而合并这些分支的开销几乎可以忽略不计。<br /><br />Git 1+1<br />现在进入本篇文章真正的主题，介绍一下Git的基本命令和操作，会从Git的版本库的初始化，基本操作和独有的常用命令三部分着手，让大家能够开始使用Git。<br /><br />Git通常有两种方式来进行初始化:<br /><ul style="margin-top: 0px; margin-bottom: 0px"><li style="margin-top: 0px; margin-bottom: 0px">git clone: 这是较为简单的一种初始化方式，当你已经有一个远程的Git版本库，只需要在本地克隆一份，例如'git clone git://github.com/someone/some_project.git some_project'命令就是将'git://github.com/someone/some_project.git'这个URL地址的远程版 本库完全克隆到本地some_project目录下面</li><li style="margin-top: 0px; margin-bottom: 0px">git init和git remote：这种方式稍微复杂一些，当你本地创建了一个工作目录，你可以进入这个目录，使用'git init'命令进行初始化，Git以后就会对该目录下的文件进行版本控制，这时候如果你需要将它放到远程服务器上，可以在远程服务器上创建一个目录，并把 可访问的URL记录下来，此时你就可以利用'git remote add'命令来增加一个远程服务器端，例如'git remote add origin git://github.com/someone/another_project.git'这条命令就会增加URL地址为'git: //github.com/someone/another_project.git'，名称为origin的远程服务器，以后提交代码的时候只需要使用 origin别名即可</li></ul>现在我们有了本地和远程的版本库，让我们来试着用用Git的基本命令吧：<br /><ul style="margin-top: 0px; margin-bottom: 0px"><li style="margin-top: 0px; margin-bottom: 0px">git pull：从其他的版本库（既可以是远程的也可以是本地的）将代码更新到本地，例如：'git pull origin master'就是将origin这个版本库的代码更新到本地的master主枝，该功能类似于SVN的update</li><li style="margin-top: 0px; margin-bottom: 0px">git add：是将当前更改或者新增的文件加入到Git的索引中，加入到Git的索引中就表示记入了版本历史中，这也是提交之前所需要执行的一步，例如'git add app/model/user.rb'就会增加app/model/user.rb文件到Git的索引中</li><li style="margin-top: 0px; margin-bottom: 0px">git rm：从当前的工作空间中和索引中删除文件，例如'git rm app/model/user.rb'</li><li style="margin-top: 0px; margin-bottom: 0px">git commit：提交当前工作空间的修改内容，类似于SVN的commit命令，例如'git commit -m &quot;story #3, add user model&quot;'，提交的时候必须用-m来输入一条提交信息</li><li style="margin-top: 0px; margin-bottom: 0px">git push：将本地commit的代码更新到远程版本库中，例如'git push origin'就会将本地的代码更新到名为orgin的远程版本库中</li><li style="margin-top: 0px; margin-bottom: 0px">git log：查看历史日志</li><li style="margin-top: 0px; margin-bottom: 0px">git revert：还原一个版本的修改，必须提供一个具体的Git版本号，例如'git revert bbaf6fb5060b4875b18ff9ff637ce118256d6f20'，Git的版本号都是生成的一个哈希值</li></ul>上面的命令几乎都是每个版本控制工具所公有的，下面就开始尝试一下Git独有的一些命令：<br /><ul style="margin-top: 0px; margin-bottom: 0px"><li style="margin-top: 0px; margin-bottom: 0px">git branch：对分支的增、删、查等操作，例如'git branch new_branch'会从当前的工作版本创建一个叫做new_branch的新分支，'git branch -D new_branch'就会强制删除叫做new_branch的分支，'git branch'就会列出本地所有的分支</li><li style="margin-top: 0px; margin-bottom: 0px">git checkout：Git的checkout有两个作用，其一是在不同的branch之间进行切换，例如'git checkout new_branch'就会切换到new_branch的分支上去；另一个功能是还原代码的作用，例如'git checkout app/model/user.rb'就会将user.rb文件从上一个已提交的版本中更新回来，未提交的内容全部会回滚</li><li style="margin-top: 0px; margin-bottom: 0px">git rebase：用下面两幅图解释会比较清楚一些，rebase命令执行后，实际上是将分支点从C移到了G，这样分支也就具有了从C到G的功能</li></ul><img src="http://docs.google.com/File?id=dcvntvfs_191dk6vtsg6_b" alt="" width="510" height="174" /><br /><div style="text-align: left; margin-top: 0px; margin-bottom: 0px"><ul style="margin-top: 0px; margin-bottom: 0px"><li style="margin-top: 0px; margin-bottom: 0px">git reset：将当前的工作目录完全回滚到指定的版本号，假设如下图，我们有A-G五次提交的版本，其中C的版本号是 bbaf6fb5060b4875b18ff9ff637ce118256d6f20，我们执行了'git reset bbaf6fb5060b4875b18ff9ff637ce118256d6f20'那么结果就只剩下了A-C三个提交的版本</li></ul></div><div id="fhzj" style="padding-top: 1em; padding-right: 0pt; padding-bottom: 1em; padding-left: 0pt; text-align: center; margin-top: 0px; margin-bottom: 0px"><img src="http://docs.google.com/File?id=dcvntvfs_192875x2khg_b" alt="" width="362" height="115" /></div><ul style="margin-top: 0px; margin-bottom: 0px"><li style="margin-top: 0px; margin-bottom: 0px">git stash：将当前未提交的工作存入Git工作栈中，时机成熟的时候再应用回来，这里暂时提一下这个命令的用法，后面在技巧篇会重点讲解</li><li style="margin-top: 0px; margin-bottom: 0px">git config：利用这个命令可以新增、更改Git的各种设置，例如'git config branch.master.remote origin'就将master的远程版本库设置为别名叫做origin版本库，后面在技巧篇会利用这个命令个性化设置你的Git，为你打造独一无二的 Git</li><li style="margin-top: 0px; margin-bottom: 0px">git tag：可以将某个具体的版本打上一个标签，这样你就不需要记忆复杂的版本号哈希值了，例如你可以使用'git tag revert_version bbaf6fb5060b4875b18ff9ff637ce118256d6f20'来标记这个被你还原的版本，那么以后你想查看该版本时，就可以使用 revert_version标签名，而不是哈希值了</li></ul><br />Git之所以能够提供方便的本地分支等特性，是与它的文件存储机制有关的。Git存储版本控制信息时使用它自己定义的一套文件系统存储机制，在代码根目录下有一个.git文件夹，会有如下这样的目录结构：<br /><div id="xa1." style="padding-top: 1em; padding-right: 0pt; padding-bottom: 1em; padding-left: 0pt; text-align: left; margin-top: 0px; margin-bottom: 0px"><img style="width: 634px; height: 79px" src="http://docs.google.com/File?id=dcvntvfs_198gds5r2ck_b" alt="" /><br />有几个比较重要的文件和目录需要解释一下：HEAD文件存放根节点的信息，其实目录结构就表示一个树型结构，Git采用这种树形结构来存储版本信息，那么HEAD就表示根；refs目录存储了你在当前版本控制目录下的各种不同引用（引用指的是你本地和远程所用到的各个树分支的信息），它有heads、remotes、stash、tags四个子目录，分别存储对不同的根、远程版本库、Git栈和标签的四种引用，你可以通过命令'git show-ref'更清晰地查看引用信息；logs目录根据不同的引用存储了日志信息。因此，Git只需要代码根目录下的这一个.git目录就可以记录完整的版本控制信息，而不是像SVN那样根目录和子目录下都有.svn目录。那么下面就来看一下Git与SVN的区别吧<br /></div><br />Git与SVN的不同<br />SVN（Subversion）是当前使用最多的版本控制工具。与它相比较，Git最大的优势在于两点：易于本地增加分支和分布式的特性。<br /><br />下面两幅图可以形象的展示Git与SVN的不同之处<br /><img id="cyqr" style="margin-top: 1em; margin-right: 1em; margin-bottom: 0pt; margin-left: 0pt; float: left" src="http://docs.google.com/File?id=dcvntvfs_188d9gc57ct_b" alt="" width="494" height="241" /><div style="padding-top: 1em; padding-right: 0pt; padding-bottom: 1em; padding-left: 0pt; text-align: left; margin-top: 0px; margin-bottom: 0px"><img id="j.e:" src="http://docs.google.com/File?id=dcvntvfs_190gp8hb5gv_b" alt="" width="495" height="242" /></div>对于易于本地增加分支，图中Git本地和服务器端结构都很灵活，所有版本都存储在一个目录中，你只需要进行分支的切换即可达到在某个分支工作的效果。而SVN则完全不同，如果你需要在本地试验一些自己的代码，只能本地维护多个不同的拷贝，每个拷贝对应一个SVN服务器地址。举一个实际的例子，以前我所在的小组使用SVN作为版本控制工具，当我正在试图增强一个模块，工作做到一半，由于会改变原模块的行为导致代码服务器上许多测试的失败，所以并没有提交代码。这时候上级对我说，现在有一个很紧急的Bug需要处理， 必须在两个小时内完成。我只好将本地的所有修改diff，并输出成为一个patch文件，然后回滚有关当前任务的所有代码，再开始修改Bug的任务，等到修改好后，在将patch应用回来。前前后后要完成多个繁琐的步骤，这还不计中间代码发生冲突所要进行的工作量。可是如果使用Git， 我们只需要开一个分支或者转回到主分支上，就可以随时开始Bug修改的任务，完成之后，只要切换到原来的分支就可以优雅的继续以前的任务。只要你愿意，每一个新的任务都可以开一个分支，完成后，再将它合并到主分支上，轻松而优雅。<br /><br />分布式对于Git而言，你可以本地提交代码，所以在上面的图中，Git有利于将一个大任务分解，进行本地的多次提交，而SVN只能在本地进行大量的一次性更改，导致将来合并到主干上造成巨大的风险。Git的代码日志是在本地的，可以随时查看。SVN的日志在服务器上的，每次查看日志需要先从服务器上下载下来。我工作的小组，代码服务器在美国，每次查看小组几年前所做的工作时，日志下载就需要十分钟，这不能不说是一个痛苦。后来我们迁移到Git上，利用Git日志在本地的特性，我用Ruby编写了一个Rake脚本，可以查看某个具体任务的所有代码历史，每次只需要几秒钟，大大方便我的工作。当然分布式并不是说用了Git就不需要一个代码中心服务器，如果你工作在一个团队里，还是需要一个服务器来保存所有的代码的。<br /></div><div style="text-align: center; margin-top: 0px; margin-bottom: 0px"><br /></div>总结<br />本篇介绍了Git的基本概念、一些常用命令和原理，大家可以尝试动手体会一下，下一篇会重点介绍Git命令的使用技巧，Git附带的工具，最后会在Git Hub上创建一个开源项目，敬请期待。</div></span><!--sp--><div class="relpost"><br/><h3>随机文章：</h3><div><a href="http://phoenixtoday.blogbus.com/logs/35149540.html">活灵活现用Git-技巧篇</a> 2009-02-13</div><div><a href="http://phoenixtoday.blogbus.com/logs/28533541.html">ThoughtWorks University 取经记(续)</a> 2008-09-04</div><div><a href="http://phoenixtoday.blogbus.com/logs/27454013.html">ThoughtWorks University 取经记</a> 2008-08-09</div><div><a href="http://phoenixtoday.blogbus.com/logs/16550157.html">初探OSGi 的全文</a> 2008-03-07</div><div><a href="/logs/29434524.html">将欲强之，必故弱之──记 Mingle 性能调优</a> 2008-09-20</div></div><div class="addfav"><br />收藏到：<span class= "delicious"><a href="http://delicious.com/save?url=http%3A%2F%2Fphoenixtoday.blogbus.com%2Flogs%2F33458940.html&title=%E6%B4%BB%E7%81%B5%E6%B4%BB%E7%8E%B0%E7%94%A8Git--%E5%9F%BA%E7%A1%80%E7%AF%87">Del.icio.us</a></span></div><br /><br /><div class="sysmsg"><b><a href="http://pindao.blogbus.com/xingzhe?utm_source=blogbus&utm_medium=rss&utm_campaign=xingzhe" target="_blank">行者频道——从普通游客到资深背包族，跟随Ta们的镜头游遍全世界。</a></b></div><br /><br />]]></description>
   <link>http://phoenixtoday.blogbus.com/logs/33458940.html</link>
   <author></author>
   <pubDate>Mon, 05 Jan 2009 22:32:36 +0800</pubDate>
  </item>
  <item>
   <title>翻译的InfoQ 书评： 敏捷模式</title>
   <description><![CDATA[<p>嘿嘿，不好意思，又拿以前做得事情来充数了，我最近一定好好的总结总结自己，写写自己的心得，我发誓</p><p>&nbsp; InfoQ 上的书评链接在这里 <a href="http://www.infoq.com/cn/news/2008/10/agile-adoption-patterns-br " target="_blank">http://www.infoq.com/cn/news/2008/10/agile-adoption-patterns-br </a><!--[if IE]>
        <?XML:NAMESPACE PREFIX = GDOC />
      <![endif]-->                        </p><p>个人认为，除了翻译中所说的那么多适用情况，其实这它还非常适合拿去给别的企业做敏捷指导的时候使用，倒是本从传统软件开发向敏捷过度的好书 </p><h3>摘要</h3>

Ryan Cooper对Amr Elssamadisy的新书发表了评价，并认为书中提供了一种为实施敏捷量身定做的框架。本书并没有给出一种人人可用的敏捷方法，而是为读者提供一些模式和工具，用以找出哪些敏捷实践可以最有效地达到该组织机构的特定目标。

<h3>正文</h3>
<p>
在AmrElssamadisy最近的一本书《<a id="sqa0" href="http://www.amazon.com/Agile-Adoption-Patterns-Roadmap-Organizational/dp/0321514521" title="敏捷模式──指向成功的路标">敏捷模式──指向成功的路标</a>》
中，他使用了一种概念框架，用这个框架把具体应用环境和敏捷策略一一对应。他没有建议人人都使用一系列相同的实践方法，而是针对公司所想达到的目标，帮助
你找出哪些实践方法是最适合的。这些实践方法不但会引领你走上敏捷的道路，而且会将迁移过程的花费，以及所出现的失望情绪降至最低。<em>
</em>
</p>
<p>
成功实施敏捷开发方法，对于一个企业而言，将会获益匪浅。敏捷过程提供更为精确的项目评估；在项目正在进行的同时也能给予更好的控制（提供更有用的功能，
而不只是需求文档上所要求的）；产生更高质量和更易于维护的软件产品；以及提高开发团队的士气和信心以及彼此之间的信任。不幸的是，正如我们许多人在敏捷
开发者社区里所了解到的，从传统的软件开发过程迁移到敏捷软件开发过程非常困难。针对具体的企业环境，找到合适的敏捷方法并进行实践，是一件很让人头疼的
任务。因此，许多企业在转换过程中经历了很多困惑和失望，而且许多企业在发现敏捷开发方法的益处之前，就放弃尝试了。
</p>
<p>Elssamadisy在书中提供了一些行之有效的方法，可以帮助你避开在实施敏捷中的种种陷阱。举例来说，尝试&ldquo;大跃进&rdquo;式的迁移是很常见的错
误，而作者为你提供了一种逐步进行、迭代采纳敏捷开发方法的计划。他鼓励使用敏捷的方式来实施敏捷：在（希望是）正确的方向上小步前进，利用短期回馈来收
集信息，用于调整方案和确定下一步的计划。同时，作者会帮你达到投资回报率最大化，他提供的技巧可以找出对组织最重要的商业价值，并且告诉你如何选择一开
始采取的实践组合，以强化这些价值。
</p>
<p>
如果你对敏捷有所了解，而且希望知道如何在真正的项目中卓有成效地实施敏捷，这本书就是你的不二之选。如果你非常愿意帮助采用传统软件开发方法的企业转而实施敏捷开发，那么这本书非常适合放在你的书架上。
</p>
<h2>
上下文驱动的实施方式
</h2>
<p>
该书的前两部分（<strong><em>第一部分：关于软件开发的想法；第二部分：实施敏捷的艺术</em></strong>）是全书的核心。
</p>
<p>
第一部分介绍了两个可供敏捷指导者采纳的指导原则：
</p>
<ul><li><strong>

原则1：学习是瓶颈。</strong>
<br />

对于给定的流程和任务，如果不知道如何实施，要找到可以加快学习速度的途径。Elssamadisy主张使用敏捷实践者普遍采用的一种方法─周期性得信息回馈 ：<br />
<p>
1）设立目标
2）采取有助于达成目标的行动
3）将行动结果与目标进行比较
4）调整行动并回到步骤2
<br />
学习的过程发生在步骤3，并在步骤4中得以应用。
</p>
<p>
Elssamadisy同时强调了沟通对于强化学习效果的重要性，个体之间的信息传播，可有效地使他们融入软件开发过程。</p>
</li><li><strong>
原则2：个体敏捷性</strong>
<br />
Elssamadisy借用了Chris Avery的&ldquo;<a id="u_bz" href="http://www.christopheravery.com/concept.htm" title="责任过程模型">责任过程模型</a>&rdquo;，
以帮助读者在组织变化的过程中，保留富有成效的想法。该部分提出的建议包括：如何避免常见的陷阱，包括盲目指责、妄下结论、自怨自艾、羞愧难当，以及自感
无助而没有主控权的状况。为了产生（并且保持住）责任感，必须创建&ldquo;思想上为自己负责的状态。用行动解决我们不喜欢的东西。这就是达到个体敏捷性的起点。
&rdquo;</li></ul>
<p>
该书的第二部分是我最喜欢的。它阐述敏捷实践的方式，是我不曾在其他书中看到的。它明确描绘了各种各样的&ldquo;业务价值&rdquo;（就是诸如&ldquo;缩减生产时间&rdquo;和&ldquo;提高
质量&rdquo;这样的目标），这些价值及其目标可以利用敏捷方法达成。如此描述方式，可以帮助读者在采纳敏捷时，照顾到组织的客观环境：首先，确定对于组织最重要
的业务价值；然后，根据上述的目标来应用敏捷实践，从而提升业务价值。
</p>
<p>

Elssamadisy同样描述了一些经常碰到的&ldquo;坏味道&rdquo;，利用敏捷方法可以有效的去除它们。（一般来说，坏味道比业务价值更易于发现。因此，从企业目前的坏味道开始，确定采用哪种敏捷实践，通常是一种相对简单的途径。）
</p>
<p>

进一步地，Elssamadisy解释了各种敏捷方法的联系。很多时候，如果不首先实施某种敏捷方法，那么很多基于它的敏捷方法就很难实施下去。针对特定的商业价值和坏味道，Elassamadisy提出了一个草图，用于排序和分组对应的敏捷实践。
</p>
<p>

这种以上下文驱动来实施敏捷的方式，是敏捷出版物中早就应该出现的，我非常高兴地看到它成为本书的核心。由于体验过许多艰难的过渡经历，我可以断言：以基于上下文的、迭代的方式实施敏捷会大行其道，<em>尤其适合于大型组织机构</em>。
</p>
<h2>
敏捷模式
</h2>
<p>
敏捷模式的章节几乎包含了敏捷领域中所有的模式。它们被分成五个群组：
</p>
<ul><li>
<strong>目标和周期：</strong><br />
两个基本的模式构成了许多敏捷实践的基础。

</li><li>
<strong>
信息反馈实践：
</strong><br />
迭代、启动会议、待办事项列表、规划扑克、站立会议、完成状态、演示、回顾、时常发布、&ldquo;联合驻扎&rdquo;团队、自组织团队、跨职能团队、客户作为团队成员、唤醒式文档、用户故事、用例、和信息辐射器。
</li><li>
<strong>

技术实践：
</strong><br />

自动化测试、测试后行开发、测试先行开发、重构、持续集成、简单设计、功能测试、代码集体所有制、结对编程。
</li><li>
<strong>

辅助实践：</strong><br />

指导、加入社区、阅读周期、研讨会、教室式培训。
</li><li>
<strong>

模式集群：</strong><br />

迭代集群、沟通集群、演化的设计、测试驱动开发、测试驱动需求。

</li></ul>
<p>
<em>辅助实践</em>也包含于其中，是非常令人高兴的。从本质上来讲，它们不是敏捷实践，而是帮助学习新知识的方法。但是，如果忽视了这些实践，将会使学习举步维艰。
</p>
<p>每个模式都包含一些有用的工具,有助于判断这个模式的实践是否适合于你的敏捷实施计划。这些工具包括：对当前模式所提升的业务价值的解释，特定模式
适用环境的介绍，和对于某些模式试图解决的阻力的深入说明。仔细阅读每个模式的上述内容，读者可以确定在自己所处的环境中，实施特定的模式会有多少价值。
</p>
<p>

拿&ldquo;演示&rdquo;模式为例，列举一些帮助你判定该模式是否&ldquo;合身&rdquo;的内容：
</p>
<p>&nbsp;</p>
<ul><li>&nbsp;<ul><li>
将需求和设计用文档记录是可以的，但是不足以提供信心，让组织相信应用可以满足他们的需要。
</li><li>
通过增强项目透明度，并且提供定期演示的流程，可以增强信心。
</li><li>
可工作的软件会给投资者树立信心，让他们看到不断推进的、卓有成效的工作成果。
</li><li>

&ldquo;我们完成了需求和设计的编写和复查，这就表示完成了30%的工作量&rdquo;，类似的片面完成度统计是错误的。开发者们一向过于乐观。
</li><li>

完成可工作的软件所付出的努力，还包括在软件开发的后续阶段减少许多瑕疵。
</li><li>

越早发现缺陷，修复付出的代价越小。
</li><li>

查找和修复缺陷是一个学习的过程，而学习是软件开发过程的瓶颈。
</li><li>

一些早先设想的解决方案并不总是我们真正需要的。有时候虽然软件开发完成并通过测试，而且是完全按照需求完成的，但不能解决真正的问题。
</li></ul></li><strong>
业务价值：
</strong><br />
&ldquo;演示&rdquo;增加了项目对于干系人的<em>透明度</em>，让客户评估具体的系统，这也增加了产品的实用性，同时对迭代也是支持。迭代可以直接提升业务价值，而演示在这方面起到了二次影响。
<br /><br /><strong>
上下文：
</strong><br />
你处在一个开发团队中，此团队施行迭代开发，投资者在开发团队之外，但对项目的进度感兴趣。
<br /><br /><strong>
阻力：
</strong></ul>
<p>
接下来，关于模式的章节介绍了如何帮助你有效实施敏捷方法，同时避免很多实践者曾落入的陷阱：
</p>
<ul><strong>
因此：
</strong><br />
当前模式的描述。该模式如何解决已知上下文环境下的种种阻力。
<br /><br /><strong>
采纳方法：
</strong><br />
步骤，顺序，一些实施当前模式的建议。
<br /><br /><strong>
但是：
</strong><br />
采用当前模式可能产生的消极结果。
<br /><br /><strong>
变种：
</strong><br />
该模式的变种，不同于&ldquo;因此&rdquo;部分的描述，同样能成功实施。
<br /><br /><strong>
引用：
</strong><br />
深入阅读资料。
</ul>
<p>
这些部分用精炼的语句总结了许多敏捷社区诞生的智慧，并且与实际问题丝丝相扣。如果你正在进行某种实践的尝试，但是并未体会到它提供的任何价值，那么这些部分可以帮助你进行调整，以从实践中获得更多的价值。
</p>
<p>
我非常喜欢&ldquo;但是&rdquo;部分。很多常见的敏捷实践都非常容易出错，而且经常很难找到有关这些错误的描述。阅读这一部分的内容，新的敏捷实践团队就可以设置切合
实际的目标（不是一切都能顺利推进，实施敏捷实践时有很多歧途），这部分内容还能给新的团队以警示，确保他们不走弯路。大多数情况下，&ldquo;但是&rdquo;部分会包含
很多建议，告诉你要是走错了路该如何扭转局势。由于许多敏捷实践都曾在这些情况下出了问题，能看到相关内容实在是读者的一大福音。
</p>
<h2>
实例研究
</h2>
<p>
该书的第三部分，研究了两个应用敏捷实践的真实案例。有关敏捷的出版物中，常会描述一种&ldquo;完全敏捷&rdquo;的团队，这样的团队与缓慢向敏捷迁移的团队大相径庭。很多倡导敏捷的人都是通过看书学习的，可他们却很难像书中描述的一样马上达到收效，也因此而遭受打击。
</p>
<p>敏捷在真正实施时，并不是一帆风顺的，能够读这些真实的情况使人耳目一新。现实世界中，尤其在大的企业，改变个人和组织的习惯是一个长久、艰难的过
程。事情不会一帆风顺，但是只要假以时日，那些持之以恒的个人和团队总会获益匪浅。这两个敏捷案例清晰刻画了目前的现实情况。帮助组织机构向敏捷迈进的过
程是漫长而又艰难的。相信别人也曾遇到类似的问题，这会让你摆脱疑虑，从而看到自己正在取得卓有成效的改进。
</p>
<h2>
结论
</h2>
<p>这本书并不适用于所有人。我不会将它推荐给完全不了解敏捷的人。Elssamadisy认为，本书适合对常用的敏捷实践和原则有所了解的读者。所以
初学者可能会发现这本书在某些方面缺乏细节描述。我同样不会给资深的敏捷教练推荐这本书；他们很可能对本书的绝大部分内容烂熟于心了。
</p>
<p>不过，如果你已经阅读了大量的书籍，并且对敏捷软件开发充满好奇，却不知道从哪里着手，那么这本书对你再合适不过了。如果你对敏捷实践有一些基本的
了解，但对于自己能否成为团队中的敏捷专家没有信心，这本书同样适用于你。如果你身在一个敏捷团队中，已经实施的敏捷实践对你来说似乎没有产生预期的好
处，你也可以好好读一读这本书。
</p>
<p>
<em>注意：这本书同样可以通过<a id="f8ya" href="http://safari.informit.com/9780321514523" title="Safari在线书店">Safari在线书店</a>获得。</em>
</p>
<h2>
关于作者
</h2>
<p>
Ryan Cooper是一位敏捷软件开发者和教练。他是Ryan Cooper咨询公司的创立者。在他的家乡Halifax，他还是敏捷用户小组的创建人之一。他的博客可以通过<a id="oq67" href="http://www.onagile.com/" title="www.onagile.com">www.onagile.com</a>访问。 </p>
<br /><p>&nbsp;</p><!--sp--><div class="relpost"><br/><h3>随机文章：</h3><div><a href="http://phoenixtoday.blogbus.com/logs/38881265.html">翻译Agile Adoption Patterns: A Roadmap to Organizational Success 一书发现的一些常见问题</a> 2009-05-03</div><div><a href="http://phoenixtoday.blogbus.com/logs/28533541.html">ThoughtWorks University 取经记(续)</a> 2008-09-04</div><div><a href="http://phoenixtoday.blogbus.com/logs/27454013.html">ThoughtWorks University 取经记</a> 2008-08-09</div><div><a href="http://phoenixtoday.blogbus.com/logs/25557507.html">体验真正的敏捷</a> 2008-07-25</div><div><a href="http://phoenixtoday.blogbus.com/logs/16034205.html">内部黄金时间与外部黄金时间对于敏捷</a> 2008-02-26</div></div><div class="addfav"><br />收藏到：<span class= "delicious"><a href="http://delicious.com/save?url=http%3A%2F%2Fphoenixtoday.blogbus.com%2Flogs%2F30107647.html&title=%E7%BF%BB%E8%AF%91%E7%9A%84InfoQ+%E4%B9%A6%E8%AF%84%EF%BC%9A+%E6%95%8F%E6%8D%B7%E6%A8%A1%E5%BC%8F">Del.icio.us</a></span></div><br /><br /><div class="sysmsg"><b><a href="http://tuijian.blogbus.com/" target="_blank">推荐：让我们寻找最优秀的Blogger！</a></b></div><br /><br />]]></description>
   <link>http://phoenixtoday.blogbus.com/logs/30107647.html</link>
   <author></author>
   <pubDate>Fri, 10 Oct 2008 18:10:35 +0800</pubDate>
  </item>
  <item>
   <title>将欲强之，必故弱之──记 Mingle 性能调优</title>
   <description><![CDATA[<p>《老子》第三十六章： </p><p>将欲歙之，必故张之；将欲弱之，必故强之；将欲废之，必故兴之；将欲夺之，必故与之。是谓微明。柔弱胜刚强。鱼不可脱于渊，国之利器不可以示人。</p><p>大意：</p><p>想要让它缩小，就一定先要让它扩张；想要使它削弱，就一定要使它增强；想要灭掉它，就一定要振兴它；想要剥夺它，就一定要给予它。这叫做隐藏意图。柔软的战胜刚直的，弱小的战胜强大的。鱼不可离开深渊，国家的锐利武器不可以在别人面前显示。</p><p>之所以对老子这段话特别有感触，是在其中的一句&ldquo;将欲弱之，必故强之&rdquo;的逆过来应用&ldquo;将欲强之，必故弱之&rdquo;。意思是你要增强它，就先要削弱它。</p><p>最近有幸与一位无论是公司还是世界范围都堪称顶级的开发大师结对编程了两天，获益匪浅。其实主要的收获不在具体技术细节，而在解决问题的方式。因为Mingle 接近2.1版本的Release 了，所以最近有些工作是在做性能调优。我和这位大师第一天所做的工作就是调整Card 的属性编辑性能。之前也与团队里面的一些成员进行过部分模块的性能调优。而这位大师做了一件与众不同的事情，让这句&ldquo;将欲强之，必故弱之&rdquo;强烈的撞击了我的脑袋。以至于这几天细细回顾起来，还觉得很有味道。大师在进行性能调优之前，将Mingle底层的JRuby Runtime 实例调整为一个，并且将所有的后台无关任务全部删掉。这也就使得，Mingle在每个请求下，只运行在一个线程中，而且功能不完善，速度甚至可能会因此变得缓慢，大大的&ldquo;弱&rdquo;化了Mingle。性能调优，本意在强化Mingle，为什么先要这样的弱化它呢？</p><p>开始的时候，我很不解的看着大师。后来大师给我仔细的解释了这样的好处：首先，所有的请求都会在一个线程中处理，那么你看到的东西是机器真的一个接一个的处理问题，很容易一眼看出最耗时的地方，虽然可能比实际的情况稍慢，但却一针见血；其次，去掉后台任务，的确让Mingle少了许多功能，这种性能调优的数据，跟实际会有些出入，可是后台任务的运行，经常会打印出一些日志，干扰了性能调优的日志文件，使你不容易发现问题，虽然跟实际的数据有些出入，但最慢的地方依然最慢，你优化了它，真实的数据也就得到了优化。也就是这样的弱化，是为了增强Mingle 未来的性能！</p><p>大师出手，不一样就是不一样！回来后，越揣摩越有味道！朱雀服了！朱雀服了！</p><p>&nbsp;&ldquo;将欲强之，必故弱之&rdquo;，什么时候才可以修炼到这种地步呢？朱雀服了！</p><!--sp--><div class="relpost"><br/><h3>随机文章：</h3><div><a href="http://phoenixtoday.blogbus.com/logs/45855234.html">关于REST API设计的一些小经验</a> 2009-09-05</div><div><a href="/logs/35149540.html">活灵活现用Git-技巧篇</a> 2009-02-13</div><div><a href="/logs/33458940.html">活灵活现用Git--基础篇</a> 2009-01-05</div><div><a href="/logs/26994984.html">Textmate 快捷键总结</a> 2008-08-04</div><div><a href="/logs/17246727.html">开发你自己的XMPP IM</a> 2008-03-18</div></div><div class="addfav"><br />收藏到：<span class= "delicious"><a href="http://delicious.com/save?url=http%3A%2F%2Fphoenixtoday.blogbus.com%2Flogs%2F29434524.html&title=%E5%B0%86%E6%AC%B2%E5%BC%BA%E4%B9%8B%EF%BC%8C%E5%BF%85%E6%95%85%E5%BC%B1%E4%B9%8B%E2%94%80%E2%94%80%E8%AE%B0+Mingle+%E6%80%A7%E8%83%BD%E8%B0%83%E4%BC%98">Del.icio.us</a></span></div><br /><br /><div class="sysmsg"><b><a href="http://pindao.blogbus.com/xingzhe?utm_source=blogbus&utm_medium=rss&utm_campaign=xingzhe" target="_blank">行者频道——从普通游客到资深背包族，跟随Ta们的镜头游遍全世界。</a></b></div><br /><br />]]></description>
   <link>http://phoenixtoday.blogbus.com/logs/29434524.html</link>
   <author></author>
   <pubDate>Sat, 20 Sep 2008 21:27:19 +0800</pubDate>
  </item>
  <item>
   <title>中秋到来，忙碌，丰收，总结</title>
   <description><![CDATA[<p>今天是中秋节，月儿更加圆，为了美好的明天，应该回头看看</p><p>工作已来快六个月了，这半年生活丰富多彩，也做了许多事情。嗯，我该冷静冷静，回头看看。 </p><p>半年来收获最为丰硕的是加入Mingle 的四个月。也是我接触RoR 的四个月，真的很感谢小组的朋友们，包括PC，晓哥，还有QianQian。他们不但让我熟悉了RoR，更能从如何写出好的代码方面上给我提供了许多帮助。所以最近的一个月，我会逐步将一些心得总结出来，回头看看是为了将来走得更远</p><p>在程序方面，还有最近在研究的Python 和PyGame，这要感谢我的TWU 朋友Matty 和Sanjay，他们一个多月前拉我加入一个叫PyWeek 的游戏编程竞赛，我们一起做了一个叫strlen 的游戏，我也贡献了不少代码噢，哇哈哈。这是我们放在Google Code 上的链接 <a href="http://code.google.com/p/strlen/" target="_blank">strlen</a>，你们想玩的话，可以去下载来玩玩噢，这是游戏截图<img src="http://phoenixtoday.blogbus.com/files/12213659410.png" border="0" alt="" width="409" height="306" /></p><p>写游戏，我可是非常感兴趣的，所以以后也会将如何用Python 写游戏的过程，以及如何写出好的游戏代码的心得写出来</p><p>嗯，最近没事的时候还在研究战国和秦国的历史，春秋战国时代是中国文化大爆发的时代，音乐、文学、机关（工匠学）各个方面的人才辈出，只可惜汉代以后，废百家独尊儒家，使得许多值得保留的东西逐渐销声匿迹了。这是中国与西方不同的地方，西方文艺复兴后，科学和艺术大爆炸，从此强盛起来。我对这段历史一直很感兴趣，所以最近研究研究，打算重拾《史记》，再好好研读下正史。之后，也会总结总结的</p><p>最后啦，自然就是最近在学习的钢琴了。现在可以弹一些简单的练习曲了，希望年底会有大得提高吧</p><p>总结看似回头，实际上会让你跑得更快更远</p><p>&nbsp;</p><!--sp--><div class="relpost"><br/><h3>随机文章：</h3><div><a href="http://phoenixtoday.blogbus.com/logs/26994984.html">Textmate 快捷键总结</a> 2008-08-04</div><div><a href="/logs/27511139.html">Wanted</a> 2008-08-10</div><div><a href="/logs/20413686.html">I'm in India - 续</a> 2008-05-07</div><div><a href="/logs/17952762.html">北京生活的第一天</a> 2008-03-30</div><div><a href="/logs/16521801.html">要有新的开始了吧</a> 2008-03-06</div></div><div class="addfav"><br />收藏到：<span class= "delicious"><a href="http://delicious.com/save?url=http%3A%2F%2Fphoenixtoday.blogbus.com%2Flogs%2F29001085.html&title=%E4%B8%AD%E7%A7%8B%E5%88%B0%E6%9D%A5%EF%BC%8C%E5%BF%99%E7%A2%8C%EF%BC%8C%E4%B8%B0%E6%94%B6%EF%BC%8C%E6%80%BB%E7%BB%93">Del.icio.us</a></span></div><br /><br /><div class="sysmsg"><b><a href="http://pindao.blogbus.com/sejie?utm_source=blogbus&utm_medium=rss&utm_campaign=sejie" target="_blank">色界频道——这里有顶尖的摄影大师，也有摄影爱好者，他们用相机收纳大千世界。</a></b></div><br /><br />]]></description>
   <link>http://phoenixtoday.blogbus.com/logs/29001085.html</link>
   <author></author>
   <pubDate>Sun, 14 Sep 2008 12:02:44 +0800</pubDate>
  </item>
  <item>
   <title>ThoughtWorks University 取经记(续)</title>
   <description><![CDATA[<p>Friends, this is the second and final part of our TWU stories, it is more concentrated on techniques. And also pubulished on the local IT magzied &quot;Programmers&quot;</p><p>&nbsp;                              ThoughtWorks University 取经第二记</p><div id="q6522"><font face="Verdana" size="2" id="q6523"><br />接
续上一篇文章关于ThoughtWorks 公司文化和敏捷开发思想的传承，这篇文章主要描述的是我在ThoughtWorks
University所接受的敏捷开发技术培训的内容和方式，在一些介绍中会穿插一些对我的真实工作所起到的影响。下面就请跟我一起走入TWU的课堂。<br /><br />ThoughtWorks对于技术培训的方式很特别，<font style="color: #000000" id="rp67" color="#ff0000"><font face="宋体" id="rp670">总体感觉是更频繁的获得反馈保证更高效的沟通。其中值得一提的是每周一进行的&ldquo;期望与担忧&rdquo;和每早的&ldquo;站立会议。</font><span style="font-family: Verdana"><font size="2" id="bckb">&ldquo;</font></span><span style="font-family: 宋体"><font size="2" id="bckb0">期望与担忧</font></span><span style="font-family: Verdana"><font size="2" id="bckb1">&rdquo;</font></span><span style="font-family: 宋体"><font size="2" id="bckb2">进行方式很有趣，每周一一到你会发现老师在墙上挂了一张大白纸上面写着一周我们将要学习的课程，每个课程下面都有耐人寻味的留白。从老师简短的介绍里得知，他是想通过这个环节与学生进行第一轮的互动。</font></span></font>我
们用颜色不同的贴纸用以表示不同的寓意，正如照片所展示的，所有学员会用十五分钟的时间，审查每一个课程的名称，然后在红色的（代表担忧）或者绿色的（代
表期待）贴纸写上内容，并贴在相应的课程下面。例如，所有学员对于叫做&ldquo;编程中所用到的设计模式&rdquo;的课程就会有&ldquo;什么叫设计模式？&rdquo;，&ldquo;我怕我无法辨别什
么时候使用设计模式&rdquo;等各方面的担心，而也会有&ldquo;我想上课的过程中编程体验一下设计模式的应用&rdquo;，&ldquo;我要学Strategy
模式&rdquo;等方面的期待。而每堂课结束的最后几分钟，老师们会审查这些期望与担忧，看看自己所讲得内容是不是覆盖到了各个部分。这个流程所起到的效果就是让学
员们有针对性的去上课，在上课前就思考一下自己想获得什么，都会有哪些困难从而达到了良好吸收知识的效果。每天早上的&ldquo;站立会议&rdquo;也很有意思，之所以叫站
立会议是因为大家开会的时候都站着，这样大家就会集中精力，好好利用每一秒钟的时间，以便不用站得太久累到自己。在站立会议的时候，我们会站成一个大圈让
彼此能够正面相对，为了避免大家争抢说话，每个人要说话的时候都要拿一个标志（学员们用的是我们自己命名的俄罗斯吉祥物──小象Gima）。站立会议的基
本内容是你昨天都学了（或做了）什么，今天打算干些什么，以及老师从&ldquo;垃圾袋&rdquo;中翻出的另学员&ldquo;谈之变色&rdquo;的回顾问题（其实回答不出来只不过吐吐舌头罢
了），比起这些我个人认为最重要的是站立会议是一个信息共享的渠道，这个时候是最好的分享经验心得和寻求帮助的时候，这种有效沟通的方式可以让你一天的工
作效率大大提升。好了，下面就该进入真正的主题了，看看ThoughtWorks是怎么进行软件开发技术的培训了。</font></div>
<div id="azyq0">&nbsp;</div>
<div id="pjhd" style="padding: 1em 0pt; text-align: left"><img id="ehpc" src="http://docs.google.com/File?id=dcvntvfs_178x8nhk2ff_b" alt="" width="454" height="340" /><br /><br />
<div id="b:63" style="padding: 1em 0pt; text-align: left"><font face="Verdana" size="2" id="ysuy0"><img id="m4si" src="http://docs.google.com/File?id=dcvntvfs_179dztng6fq_b" alt="" width="453" height="339" /><br /><br />老师给我们准备了，<font face="Verdana" size="2" id="e.w40">TDD（Test Driven Development测试驱动开发）、</font><font face="Verdana" size="2" id="cr.s0">结对开发、</font>面向对象编程、测试与Mock、重构、自动化测试、<font face="Verdana" size="2" id="snw20">持续集成</font>等课程大餐。通过学习这些知识和技术，使所有学员可谓真真正正窥见了软件开发的流程，为以后在工作中大战拳脚打下了扎实的基础。即使是针对这些具体的技术培训，与国内大学所使用的以讲为主的授课方式完全相反，<font face="Verdana" size="2" id="s6ww0">ThoughtWorks
采用让学员主动参与，随时提问，动手实践，及时总结等方式，争取让每次课程的内容被消化在课堂上。我们培训的地点就是公司租用旁边一家五星级酒店的会议
厅，整个大厅非常宽敞，学员们可以随时更换自己的位置，老师们平时使用投影仪和白板进行授课，如果需要他们会坐在学员旁边亲手指导，学员在实践过程中有了
问题，也可以立即跑到老师跟前询问解决方案，这样的环境非常便于学员之间、学员与老师之间的交流。例如在培训测试驱动开发的时候，老师并没有立即告诉我们
什么是测试驱动开发，而是让我们分成四个小组自己讨论二十分钟，每个小组在大厅的一面拥有一个白板，讨论结束后每个小组选派一个代表，根据白板上的记录向
所有学员和老师介绍你们小组理念中的测试驱动开发是什么</font>，如下面的照片所展示，Kunal正在向全体同学介绍他们小组的观点，而所有其他的学员随时可以提出质疑，老师也可以纠正一些错误的观点。经过小组讨论的环节后，老师<font face="Verdana" size="2" id="w0qw0">会对大家所阐述的各种观点进行查漏补缺和总结，通常总结的行为方式也是多种多样的，有可能直接用大白纸写出来然后贴在墙上，也有可能用思维图的方式画在白板上等等，这些方式都增强了我们收集内容的可视性也使讨论过程更高效。</font>最后，老师再现了一个用测试驱动开发的完整实例，反复的强掉了测试驱动开发中设计大于测试的理念──即用测试书写你的思想，用代码实现该思想，而不仅仅只是一种测试开发方法</font><font face="Verdana" size="2" id="i-_n">的原理</font><font face="Verdana" size="2" id="i-_n0">。这种让学员积极参与和进行演讲的教学方式，使得所有人对教学的内容都有了自己的理解，并深深地印在了脑海中。<br /><br /></font>
<div id="vtuc" style="padding: 1em 0pt; text-align: left"><img id="zb6:" src="http://docs.google.com/File?id=dcvntvfs_180gdk3hvgn_b" alt="" width="454" height="340" /></div><font face="Verdana" size="2" id="ysuy2"><br />其实对于ThoughtWorks，结对并不仅仅是应用在编程中，我们几乎做什么事情都结对，老师们结对讲课，学员们结对演讲，结对研究新技术，结对做课后作业，当然还有著名的结对编程了。<font id="y1u4" color="#000000">结对的方式促使我们更频繁的沟通，更高效的知识分享，</font>这
也是为什么我在上文中使用了结对开发而不是结对编程这个词的原因了。很有趣的事情是，老师们在上课时给我们传授结对思想的时候，让我们讨论的主题是结对的
好处和坏处。当被问到结对有什么坏处的时候，学员们怎么想都想不出来，没想到身为资深开发者的老师Khali大声地说到：&ldquo;结对编程非常的累，因为你总是
全神贯注，而且总是有人盯着你，你必须工作呀。每天结对完之后，我都累得不想动了，当然结对的时候还是很有趣的。&rdquo;对于这样的诚恳的答案所有的学员都爽朗
的笑了起来。回国后在ThoughtWorks项目管理产品Mingle团队的实际工作，让我体验到了结对的种种好处，业务分析员结对给我介绍软件的各种
功能，让我很快的了解到我们要做什么。资深的开发者跟我结对编程，保证项目进度的同时，也教给我许多编写代码的知识和技巧，更值得一提的是让我学会了他们
遇到问题的思维方式和解决问题的处理方法，这如果靠一个人独自摸索，真的不知道要花多长时间。直到工作几个月后，才真正理解到结对给团队带来的巨大好处，
当然每天也的确很累。<br /><br /></font>
<div id="wsll" style="padding: 1em 0pt; text-align: left"><img id="q9up" src="http://docs.google.com/File?id=dcvntvfs_1803mdtf4ns_b" alt="" width="421" height="316" /></div><font face="Verdana" size="2" id="ysuy4"><br /><font face="Verdana" size="2" id="bat82">面向对象编程、测试与Mock、重构都是敏捷开发方法中所涉及的具体内容。</font>ThoughtWorks
University的老师通过两个小故事的开发让我们真的体会到了为什么以及什么时候使用与之对应的技术。老师们用一个关于飞机场的开发素材让我们了解
到面向对象编程中良好的封装性、单一职责原则、Liskov
替换原则（LSP）、递归算法、Strategy设计模式等开发知识。另外一个关于停车场的开发故事，让我们了解到了Mock对象在测试中的使用、重构的
必要性和艺术、Composite设计模式等知识点。拿飞机场故事为例，老师们在课堂开始的时候会给我们描述完整故事的一个小部分，然后每次给每个结对
（Pair）十分钟的理解需求和发问时间，五分钟的设计时间，十五分钟的开发时间；在开发的过程中要灵活的使用测试驱动开发、结对编程和重构的各个技巧；
在每个开发周期之后，如果没有任何一个结对完成了功能，则进行下一个十五分钟的开发周期，否则就会请一个结对上台展示他们的代码，在展示的过程中首先运行
测试保证功能全部完成，然后由该结对的成员讲述他们的实现思路和具体方法，可以随时发问和提出更好的方案，最后老师会进行总结并展示自己编写的代码以供大
家仔细分析。还有一点在培训开发方法的时候非常值得注意，其实对ThoughtWorks有过接触的朋友通常对ThoughtWorks的开发人员有一点
印象非常深刻，就是他们是一群使用开发工具尤为流畅的群体，他们不但可以熟练的运用各种开发工具，更能够飞快的使用工具的快捷键进行代码的编写。其实我们
在实现这些开发素材的时候，老师专门给我们培训过相关工具的快捷键，并且把最常见的快捷键书写在大白纸挂在我们的头顶，我们只要抬头便看得见，真正在开发
的过程中我们也会很努力的使用这些快捷键，很快得就可以灵活运用了。使用快捷键可以极大的提高开发速度，而且它更有助于开发者保持开发思路，如果你使用快
捷键非常熟练，往往在开发的过程中，不需要思考就可以实现几个视图、类的切换，否则使用鼠标时为了寻找按钮的那段停顿期，往往会让你的思路受到干扰，这也
可能是为什么那么多ThoughtWorker为快捷键乐此不疲的原因之一吧。<br /><br /><font face="Verdana" size="2" id="snw21"><font face="Verdana" size="2" id="y:qc1">自动化测试、</font></font><font face="Verdana" size="2" id="snw23">持续集成是敏捷开发技术中的重中之重。在ThoughtWorks University的培训课程中我们会学习，利用JUnit编写单元测试，利用Selenium进行功能性测试，利用Ant编写运行自动化测试的脚本，利用Subversion进行代码的持续集成，</font></font><font face="Verdana" size="2" id="eb-d"><font face="Verdana" size="2" id="eb-d0">使用Cruise（或Cruise Control）作为自动化构建的工具等课程。老师给我们</font></font><font face="Verdana" size="2" id="ctna"><font face="Verdana" size="2" id="ctna0">传授这些知识的</font></font><font face="Verdana" size="2" id="ctna1"><font face="Verdana" size="2" id="ctna2">的
最佳方法也就是让我们实际在开发过程中演练这些技术和工具。其实这些课程展现了在ThoughtWorks的真实工作流程：我们在测试驱动开发的过程中通
常会使用测试框架（JUnit）先编写测试，在开发完一个简单的功能后，会运行测试脚本（Ant），在本地运行所有的测试以确保编写的代码没有对别的功能
有所破坏；然后</font></font><font face="Verdana" size="2" id="eb-d1">会用版本控制工具
（Subversion）将代码提交到代码库中；代码库中还包括测试人员编写的Selenium测试脚本；这时自动化构建工具（Cruise）就会开始自
动运行所有的测试，如果失败会给团队亮出红灯，表示软件处于不可用的状态，这时团队的成员就会集中精力来解决错误，自动构建工具还可以自动生成可运行的软
件以供客户试用。总之，代码库中的软件始终要处于可运行的状态，这在某种程度上也保证了用户可以直接试用软件，从而提出有价值的回馈信息。在
ThoughtWorks中国分公司有很多关于持续集成的小故事，其中最有趣的是同事李晓告诉我的关于一个下午听那首经典的&ldquo;Only
You&rdquo;的故事：李晓根据构建的情况开发出了一个构建结果自动提醒的语音程序，如果构建失败就会播放指定的歌曲和最后提交代码的开发者的名字，有一次某人
提交了一段代码使构建失败了，结果始终找不到错误的来源地，整整一个下午办公室都激荡着这首著名的歌曲和某人的大名，据他所说那个时候该团队空前的一致集
中精力找错误。在ThoughtWorks中跟这些很有创意的同事们一起工作，总是会有新的惊喜和收获。<strong><br /><br />最后的测试──项目评估</strong><br /></font></div><font face="Verdana" size="2" id="ysuy5">前五周的知识积累，使所有学员都迫不及待的希望在某个项目上灵活运用一下，这就是最后一周的实战内容──一个公司内部使用的项目<font id="kzhf0" color="#ff0000">，</font>这
个项目完全由学员自行开发，老师们扮演客户的角色，开发结束后会直接供公司内部使用或者由别的团队接管继续开发。在紧张的一周开发过程中，所有学员每天九
点到下午三点是实际的开发过程，下午三点到五点是向客户展示，询问意见，以及对当天团队情况进行总结和信息回馈的过程。每天学员中都会有人扮演
IM（Iteration Manager）负责管理开发的具体事宜，首席BA（Business
Analyst业务分析员）负责所有BA事宜的决断，首席DEV（开发人员）管理开发团队，首席QA（测试人员）调空测试人员的任务。各个不同的领导者角
色每天都会在不同的学员中进行轮换，以满足绝大多数愿意尝试管理角色的学员都有机会尝试。整整一周的评估，真正地体验了什么叫&ldquo;魔鬼客户&rdquo;的难缠程度，也
许老师们的目的就是让我们体验一下大强度、高压力、多任务的工作环境。第一天，意料中的混乱，有人把未经测试的代码提交到代码库中去了，所以构建库对我们
展示了一整天晚霞般红通通的笑脸，在当天的展示阶段，我们战战兢兢的向脸上阴云密布的客户展示了惟一一个能拿得出手的开发功能。不过当天之后的总结和信息
反馈阶段，学员们一起努力提出了很多有效地解决方案，之后的每一天都会有很大的改观，最后我们成功的提交了七个完全复合客户需求的功能，老师们对我们的表
现也非常的满意。终于，我们成功的毕业了！！！<br /><br />
</font><div id="j9lx" style="padding: 1em 0pt; text-align: left"><font face="Verdana" size="2" id="bckb3"><img id="bq3b" src="http://docs.google.com/File?id=dcvntvfs_181fqcg54d2_b" alt="" width="444" height="331" /><br /><br /><strong>总结</strong><br /></font></div><font face="Verdana" size="2" id="bckb4">其
实还有许多有趣的故事还记忆犹新，比如为了驱散每日中午的困顿，大家会把各个国家的游戏集合起来，每天中午都一起玩一个，我们称这种活动为&ldquo;振奋精神&rdquo;；
每天下课后都会有学员自己主持的技术介绍演讲，学员可自愿参加，切身体会一下当前又新又优秀的各种技术，从而更好地面对自己即将到来的工作。就这样思维活
跃的人走在了一起，迎面遇到的每一个困难都去努力解决，大家团结在一起体验了一次软件开发的盛宴，最后告别终究还是会来临，不过美好的记忆和所学的知识却
永远的伴随左右。仅以此文献给我ThoughtWorks University的各位好友，同时也希望本文对各位读者能有所启迪。<br /></font></div><br /><a id="w91v0" name="0.1_01000004" title="0.1_01000004"></a><!--sp--><div class="relpost"><br/><h3>随机文章：</h3><div><a href="http://phoenixtoday.blogbus.com/logs/27454013.html">ThoughtWorks University 取经记</a> 2008-08-09</div><div><a href="http://phoenixtoday.blogbus.com/logs/20413686.html">I'm in India - 续</a> 2008-05-07</div><div><a href="http://phoenixtoday.blogbus.com/logs/18714348.html">I'm in India</a> 2008-04-09</div><div><a href="http://phoenixtoday.blogbus.com/logs/38881265.html">翻译Agile Adoption Patterns: A Roadmap to Organizational Success 一书发现的一些常见问题</a> 2009-05-03</div><div><a href="http://phoenixtoday.blogbus.com/logs/35149540.html">活灵活现用Git-技巧篇</a> 2009-02-13</div></div><div class="addfav"><br />收藏到：<span class= "delicious"><a href="http://delicious.com/save?url=http%3A%2F%2Fphoenixtoday.blogbus.com%2Flogs%2F28533541.html&title=ThoughtWorks+University+%E5%8F%96%E7%BB%8F%E8%AE%B0%28%E7%BB%AD%29">Del.icio.us</a></span></div><br /><br /><div class="sysmsg"><b><a href="http://tuijian.blogbus.com/" target="_blank">推荐：让我们寻找最优秀的Blogger！</a></b></div><br /><br />]]></description>
   <link>http://phoenixtoday.blogbus.com/logs/28533541.html</link>
   <author></author>
   <pubDate>Thu, 04 Sep 2008 18:13:50 +0800</pubDate>
  </item>
  <item>
   <title>Wanted</title>
   <description><![CDATA[<p>Yesterday, I watched a movie name Wanted. It is about a killer's story with some fantastic actions. This is the introduction of the movie which published on Youku(one duplication of Youtube in China).</p><p><a href="http://player.youku.com/player.php/sid/XMjAyNjI5OTI=/v.swf" target="_blank">movie link </a></p>
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" width="480" height="400" align="middle"><param name="align" value="middle" /><param name="allowscriptaccess" value="sameDomain" /><param name="height" value="400" /><param name="width" value="480" /><param name="quality" value="high" /><param name="src" value="http://player.youku.com/player.php/sid/XMjAyNjI5OTI=/v.swf" /><embed type="application/x-shockwave-flash" align="middle" allowscriptaccess="sameDomain" height="400" width="480" quality="high" src="http://player.youku.com/player.php/sid/XMjAyNjI5OTI=/v.swf"></embed></object>
<p>&nbsp;The story is kind of old, but one thing interested me. The whole story is telling the man wanna figure out who he is and who he wanna be. This is similar with one story put on www.kaixin001.com by one of my friends who is a ThoughtWorker, too. That story is telling about one business man tried to change one fisher's life. Both of the stories ask me one question:&quot;Who are you? Who you wanna be?&quot;</p><p>&nbsp;I think I'm lucky, I have my plan, and I exactly know what I wanna be. But some people can't, especially those young people(sorry, I'm young, too) , they just lost their destination. Their lives are not what they want, they work because they need to. This maybe not only happenning in China, also in other countries</p><p>&nbsp;If you are not happy, and you don't know why you should live in this way, So you may find what you wanna be. Ask yourself, nobody can answer instead of you. But only one thing more, don't lose your confidence</p><p>&nbsp;everyday is a new day close to your dream</p><p>&nbsp;OK, too much philosophy. That's not my style, to be honest </p><!--sp--><div class="relpost"><br/><h3>随机文章：</h3><div><a href="/logs/18714348.html">I'm in India</a> 2008-04-09</div><div><a href="/logs/17818020.html">要走了，有些舍不得呀</a> 2008-03-28</div><div><a href="/logs/16521801.html">要有新的开始了吧</a> 2008-03-06</div><div><a href="/logs/15761109.html">一些2008 年想看的商业大片（预告片），送给大家做元宵节礼物</a> 2008-02-21</div><div><a href="/logs/14095749.html">将技能云搬进新家</a> 2008-01-18</div></div><div class="addfav"><br />收藏到：<span class= "delicious"><a href="http://delicious.com/save?url=http%3A%2F%2Fphoenixtoday.blogbus.com%2Flogs%2F27511139.html&title=Wanted">Del.icio.us</a></span></div><br /><br /><div class="sysmsg"><b><a href="http://pindao.blogbus.com/shenghuo?utm_source=blogbus&utm_medium=rss&utm_campaign=shenghuo" target="_blank">生活频道——笑谈生活，坐看人生，这里有着小人物的健康生活。</a></b></div><br /><br />]]></description>
   <link>http://phoenixtoday.blogbus.com/logs/27511139.html</link>
   <author></author>
   <pubDate>Sun, 10 Aug 2008 22:36:07 +0800</pubDate>
  </item>
  <item>
   <title>ThoughtWorks University 取经记</title>
   <description><![CDATA[<p>This is another article written by me published on the local IT magzine Programmers. Sorry my freinds in other countries, it is written in Chinese. It is about our stories in TWU. To be honesy(yeah, again and again), I miss you guys.</p><p>这篇文章可能与程序员上的略有不同，因为后来L MM 帮我改得更好了，不过这是我的Blog 所以贴出来的自然是原文 </p><div id="x_on" style="text-align: center">
<div id="x_on0" style="text-align: center"><font size="5" id="erul"><strong><span style="font-family: SimSun,宋体,MS Song,serif">ThoughtWorks University 取经记</span></strong></font><br /><br /></div></div><font size="2" id="x_on4"><span style="font-family: SimSun,宋体,MS Song,serif"><font id="cv8:">四月份我加入了ThoughtWorks公司，由于是应届毕业生的缘故，紧接着就被派到印度班加罗尔分公司进行了六周的公司培训。六周的生活是紧张、繁忙而
又非常开心的，不但与敏捷开发方法进行了亲密接触也结识了许多聪明、勤奋富有激情的外国同事。在这六周的生活中，前两周主要是进行公司文化和敏捷开发思想
的培训，后三周就主要进行技能的培训，最后一周是给所有培训的ThoughtWorker一个项目，来评估整体培训的结果。培训这些内容的主要目的是让新
员工尽快的融入到公司文化中，成为公司的一份子；还有就是理解敏捷软件开发的原理并亲身体验真正的敏捷软件开发方法，从而体会到这种开发方式的种种好处；
最后的一个目的当然就是增强新员工的技术水平。本文会分为两部分，第一部分介绍ThoughtWorks对公司文化和敏捷开发思想的培训，第二部分介绍
ThoughtWorks针对具体的团队开发技能是如何进行培训的，全文中会穿插一些真实有趣的小故事以及我对相应培训的一些感想。<br /><br /><font id="n6u1"><span style="font-family: SimHei,黑体,MS Hei,sans-serif">公司文化的传承</span></font><br /><br />对ThoughtWorks有所了解的人都知道，公司的文化都是围绕人与人之间的平等、尊重和加强沟通这几个方面的。作为一个新员工，给你带来的最大感受就是公司自由平等的氛围和人与人之间和谐友好的关系。<br /><br />这些平等、自由的思想当然会渗透在培训课程的点点滴滴之中。第一天的课程中，我们就做了很多的游戏，其中有两个很有趣的游戏，第一个游戏是老师们给每个人发
了一份表格，上面写了二十多条内容，每一条内容会对应一位老师或学员，例如会有这样的内容&ldquo;有一个人拥有iPhone&rdquo;，&ldquo;有一个人的体重小于50公斤
&rdquo;，或者&ldquo;有一个人要坐超过二十小时的飞机才能来到班加罗尔&rdquo;等等，这些问题每一个都是特别设计的，而你的任务就是要在五分钟之内将所有的内容与人对号入
座。游戏开始的时候，大家跑得跑，叫得叫，笑得笑，整个大厅沸腾了，好不热闹，最终有一两个学员将所有人对号入座，然后大家就集体将所有匹配的结果大声朗
读了出来。其实到底谁赢了游戏，并不重要，真正重要的是在这个过程中，大家增进了了解，进行了有效地沟通，如果你都不了解你的团队，那如何进行软件开发
呢？从这一个简单的游戏，我们所有学员和老师，就从陌生人向朋友迈进了一大步。第二个游戏叫做&ldquo;人人都会犯错误&rdquo;，传达的人人平等的理念更加强烈一些。游
戏规则类似于中国饭桌上经常玩的报数字（遇到含七的数字和七的倍数要说Pass），只不过我们加了一条，就是在你犯了错误后，要大声地说&ldquo;YES&rdquo;，同时
手脚并用的摆一个姿势，然后站到圈的末尾。结果在游戏的过程中一位印度裔的老师Reshema经常出错，长相可爱的老师Reshema再加上大声吼叫的
YES以及怪异的手脚并用姿势，把所有人逗的前俯后仰。这个游戏使我们明白了，犯错误是很正常的事情，你没有理由去责怪别人，ThoughtWorks也
是允许你犯错误的，关键是犯了错误你从中能学到什么，以及帮助别人怎么从错误中进步。<br /><br />其实公司的第一堂课根本与敏捷软件开发和技术无关，可能大家根本无发猜出是讲什么的，连所有的学员都很惊讶公司培训的第一堂课，竟然是告诉我们什么是公司认为
的歧视和不平等，在这一堂课中，老师会提出一些问题来让学员投票，让我们分辨什么是歧视和不平等，然后再给出公司的答案，如果大家有疑问可以充分的表达自
己的意见，然后再投票。从这第一堂课的内容就可以看到ThoughtWorks是何等的重视人与人之间的平等和尊重了。注重人与人的沟通也体现在公司文化
的各个方面，最简单的一个例子就是宿舍的安排，我本想着可能是不同分公司的员工会住在一起，没想到刚下飞机就得知自己会和一个澳大利亚的同事还有一个印度
的同事住在一间公寓里，这对于英语不是母语的中国人来说，也真的是捏了一把汗。但是仔细想想，这样的住宿方式，不但会加强不同学员之间的交流，而且可以更
好的了解不同区域的文化，了解你将来可能一起工作的同事，了解他们的想法和行为方式，这样才可能达到真正的尊重和平等。<br /><br />了解ThoughtWorks的人可能都知道，平等和尊重在公司的极致体现不能不说是那些公司的领导层了，每一期学员培训，Roy（不要说你不知道Roy是
谁啊）都会单独做一次演讲，其中的主要内容包括创建ThoughtWorks的原因和历史，公司经历过哪些困难以及他本人的一些传奇经历。Roy的演讲是
很有趣的，不过学员们提的问题更加有趣，我和我的舍友就提了一个&ldquo;假如你被绑架了，你会怎么办？&rdquo;的离奇问题。结果Roy的回答让人瞠目&ldquo;其实我是被绑架
过的！&rdquo;然后他就娓娓道来那一次班加罗尔分公司的ThoughtWorker是如何乔装成绑匪，然后在飞机场对Roy实行了一次&ldquo;绑架&rdquo;，之后Roy又爆
料出许多被ThoughtWorkers戏弄的故事。从这些Roy的小故事中，你可以发现公司的头头脑脑们，喜欢和员工打成一片，有的时候他们会上来拍你
的肩膀然后叫你的新外号，有的时候他们会跟你谈论他们最近的尴尬经历，甚至吃饭的时候他们也会被员工灌醉。可见平等和尊重的理念已经深深的植入
ThoughtWorks的文化精神之中。<br /><br />ThoughtWorks公司的平等和尊重还体现在公司的管理很透明，甚至包括财务收益、开销等信息都会公开的呈现在新员工的面前。印象中</font></span></font><font size="2" id="s906"><span style="font-family: SimSun,宋体,MS Song,serif">关于</span></font><font size="2" id="a9eu"><span style="font-family: SimSun,宋体,MS Song,serif"><font id="a9eu1">管
理很透明有两个小故事很深刻，其中之一就是第一周一门课程的内容就是将公司这几年的收益和开销完完整整的展现在所有员工的面前，包括总共有多少收入，总共
有多少支出，这些支出用在培训、新建分公司、股东收益等等方面的具体支出数目，并且在课程的最后每个学员还要扮演公司财务部门的角色，模拟体验一下公司财
务部门是如何进行资金运转和保证现金流的。第二个故事就是Roy在他的演讲中提起了2001-2003年公司曾经裁员的事情，原因就是当时IT产业大萧
条，公司处于窘境，Roy说那时是他最为困难的时期，直到现在都很内疚，仔细想想在绝大多数的公司中，这些内幕消息哪是一个刚进公司还不到十天的人可以接
触到的，但是ThoughtWorks确毫无保留的给我们展现在眼前。其实管理的透明在回国后，也时时刻刻都可以体验到，ThoughtWorks
北京分公司每月都会做一次月报，让全公司的同事都知道这个月我们分公司的经营状况。对于我们这些新员工，在短期内就对公司的各种状况有了一个整体的了解，
从而很快的建立起了一种强烈的主人翁精神。<br /><font style="font-family: SimHei,黑体,MS Hei,sans-serif" id="y8a81"><br />敏捷软件开发思想的传承</font><br /><br />对于前两周敏捷开发思想的培训是非常有趣的，几乎每节课都有互动的过程，每节课都会有生动的实例让你体验到什么是真正的敏捷软件开发，为什么要使用敏捷软件开发。<br /><br />在介绍整体培训的过程之前，首先介绍一下ThoughtWorks敏捷软件开发团队的构成。一般一个开发团队主要有以下几种角色：PM，Project Manager项目经理；BA，Business Analyst业务分析<font style="background-color: #ffffff" id="mz-5">员</font>；DEV，Developer
开发人员；QA，Quality Analyst测试人员。PM对项目进行全局掌控（有的时候，还会有IM，Iteration
Manager对具体的迭代开发进行掌控）；BA，主要与客户进行沟通和业务分析，与开发人员进行交流，与测试人员对整体功能进行讨论等等；DEV，主要
就是开发应用程序，但同时也要协助业务分析员和测试人员进行工作；QA，主要对开发人员开发出的系统，进行全方位的测试，包括功能测试、性能测试等等。对
于团队整体的开发流程，是一个有序、小步、渐进的过程。ThoughtWorks对敏捷软件开发思想的培训也主要针对如何了解用户需求，团队共享代码，迭
代开发，总结与回顾。<br /><br />在软件开发的过程中，能够准确的理解用户的需求，将用户的需求转变为开
发团队理解的用例，是一件紧迫而重要的事情。但是，如何才算好的理解用户的需求呢？如何能让我们这些从没与客户打过交道的毕业生尽快的学会与客户沟通的方
法呢？这就是我个人非常喜欢ThoughtWorks
University的一个方面，在敏捷软件开发的所有课程，包括对需求理解的课程，设计的非常精妙，不但能够让这些观念深深地扎根人心，而且能让你体会
到真正的软件开发其实就是应当这样做得。我们上过一堂用橡皮泥做电话的课程，老师们把大家分成许多小组，每个小组由3-4个学员和一位扮演客户的老师组
成，老师们扮演的客户是非常的苛刻的，我们的任务就是要做出让客户满意的电话来，每一次开发的过程只有十五分中，分三次开发完成一部完整的电话。在整个开
发的流程中，我们体会到客户的需求是随时改变的，当他们看到了原型系统，甚至可能推翻之前的所有需求，这时候作为一个开发人员或者业务分析人员，在你了解
客户的需求过程中，不但要求你具有能够充分理解客户需求的技巧，更需要你能启发客户思考一些它们没有想到的方面，从而少走一些弯路。在制造电话的过程中，
我们几个小组在第一个开发周期的行动，几乎都是闷头造电话，完全忘记了我们有一位客户坐在我们的桌字旁，当我们有疑问的时候，为什么不去直接找客户进行沟
通呢？老师向我们提出了这样的问题后，我们在后面两次的迭代中，和客户进行了频繁的沟通，最终做出了让客户满意的电话系统。下图就是我们做出的橡皮泥电话
系统之一，你看Reshema老师拿着电话，多么高兴。<br /></font></span></font><font size="2" id="p7n-"><span style="font-family: SimSun,宋体,MS Song,serif">
<div id="zjql" style="padding: 1em 0pt; text-align: left"><font id="hm2y"><img id="cjs6" src="http://docs.google.com/File?id=dcvntvfs_167jn6wk9hq_b" alt="" width="348" height="464" /><font id="vjm20"><span style="font-family: SimSun,宋体,MS Song,serif">
<div id="d46x" style="padding: 1em 0pt; text-align: left"><font id="hm2y0"><img id="vjm23" src="http://docs.google.com/File?id=dcvntvfs_168fsrhwxf2_b" alt="" width="347" height="460" /><br /><br />在有些人的眼中，ThoughtWorks是一群拿着卡片到处贴，到处走的奇怪人群组成的软件咨询公司。其实为什么使用卡片作为理解用户需求的主要机载体，
在我去TWU之前也很疑惑。后来，在一堂介绍如何使用卡片理解需求的课程中，终于了解到原来其中包含了这么多奥妙。首先卡片很小，这就迫使业务分析员不能
将太多的内容放在同一张卡中，由于一个迭代周期通常是两到三周，需要给用户展示一些能用的系统功能出来，这样就会引起整个团队思考许多有价值的问题，什么
是最紧要的？什么是系统的核心？我们要用多长时间来完成这些卡片上的内容？第一个迭代周期能完成多少卡片？我们的团队开发速度是多少？等等。其次，卡片在
卡片墙上是可移动的，因此它很灵活，就如下图所示，可以将卡片放置在不同的队列中，通常我们用&ldquo;在分析中&rdquo;、&ldquo;在开发中&rdquo;、&ldquo;在测试中&rdquo;、&ldquo;结束&rdquo;等一些
状态表示卡片所处的不同状态。这样，当所有团对人员，需要了解当前项目的进度状况时，只要站到卡片墙前，就可以一目了然，如果处理不同卡片的小组需要彼此
沟通，在卡片墙上，可以用最快的速度找到相应的人员，甚至，当你有疑惑的时候，卡片可以拿下来仔细研究，只要记得最后放回去就好。卡片的最后一个优点就是
对当前项目进行评估，举一个简单的例子，当一个团队的开发状态是绝大多数的卡片都集中在&ldquo;在开发&rdquo;的队列中，就表示当前开发团队处于业务分析员和测试人员
无事可干，但是开发人员又过于繁忙的不健康状态。什么原因导致的呢？可能是开发速度过慢或者是业务分析员写的卡片粒度过大，导致开发人员无法及时的完成。
由此，当我们站到一个团队的卡片墙之前，我们看到的不仅仅是一些简单的卡片，更是整个开发团队的开发状态的展示。一张张小小的卡片却包含了如此多的内容，
这真的是我们始料不及的。当然卡片并不是完美无缺的，对分布式团队开发就是卡片墙的致命弱点，但这些问题在ThoughtWorks的Mingle软件中
都得到了很好的解决，卡片对我们来说更是一种以用户为中心，以团队沟通为中心的开发思想，而不仅仅是一种开发方法。<br /></font>
<div id="hfs1" style="padding: 1em 0pt; text-align: left"><font id="hm2y1"><img id="wdev" src="http://docs.google.com/File?id=dcvntvfs_169gttrr2f5_b" alt="" width="342" height="455" /></font></div><font id="hm2y2">针
对眼前的需求，小步前进，不做过多的设计，也是敏捷软件开发的核心思想之一。ThoughtWorks
University通过一个早上的摆积木课程（Lego
Game）让我们充分的理解了过多设计的弊病。这次课程的整体任务是创造未来物种，类似于造电话课程，同样分为三个迭代周期，有一位老师作为客户伴随着我
们进行开发。这一次，老师们一下给了我们许多点数不同的需求，每个需求对应一张卡，每张卡上有不同的分数表示这张卡的难度，每次迭代有五分钟的讨论，需要
确定这次迭代都要完成哪些功能，有十分钟的设计，还有十五分钟的开发过程，每次迭代后大家要讨论哪些做得好，哪些做得不好的地方。第一次的迭代往往是犯错
误最多的地方，我所在的小组向客户许诺了总共加起来十分的卡片，在设计过程中又做了许多不必要的假想，过多的专注于给未来的需求留下余地，而将自己开发的
过程束缚住。最后仅仅搭起来了动物的头和身体，可是客户要求的是一个完整的动物，所以第一次迭代我们只有零分，客户非常的失望。ThoughtWorks
就是这样，通过学员的犯错误，让我们自己体会，然后通过讨论，让我们自己总结出具体的方法，老师们则是在旁边指引，这样的感受怎么能不深刻呢？经过讨论，
我们制订了自己的方针：少许诺，少设计，好好做核心模块。就这样，最后我们创造出了未来的一个物种（还有它的孩子）。<br /><br /></font>
<div id="fpml" style="padding: 1em 0pt; text-align: left"><font id="hm2y3"><img id="w9dg" src="http://docs.google.com/File?id=dcvntvfs_170d2vx4td2_b" alt="" width="419" height="314" /></font></div><font id="hm2y4">迭代的过程也是ThoughtWorks进行敏捷过程培训的一个重要方面。还是继续我们的游戏旅程吧：这一次老师让我们分成三个小组，分别从培训大厅的一端
将气球搬运到另一端，每一组有两个人负责装运，两个人负责撑袋子，一个人负责搬运，哪一组能在最短的时间内，将最多的气球从一个口袋中运到另一侧的口袋中
就算胜利，如果过程中任何气球掉在路途中，则不可拾取。第一次的规则是只能运一次，整个过程给人的感觉就是搬运的人花了很多的时间，承担了过多的责任，而
其他的四名队员起不到任何的作用，只能边喊边焦心的等待。第二次的规则几乎与第一次一样，但搬运人可以多次的运输。结果第二次，我们不但出色的运输了所有
的气球，而且还比第一次所花的时间更少。玩完游戏的讨论过程中，我们逐渐的明白了，第一次运输就好比传统的瀑布式开发，开发人员承担了许多的压力，缺少沟
通和其他人员必要的帮助，闭门造车造出来的东西，往往并不是客户心目中想要的东西；而第二次运输就好比多次迭代的开发过程，开发人员得到更多的信息回馈以
及业务分析员和测试人员的帮助，因此能够开发出更好的软件产品。就这样，我们不但理解了迭代开发的原理，更通过亲身的体验明白了这样做是行之有效的。</font></div></span></font></font></div></span></font><font size="2"><br /></font><font size="2" id="p7n-2"><span style="font-family: SimSun,宋体,MS Song,serif"><font id="p7n-4"><font id="xy5a"><span style="font-family: SimHei,黑体,MS Hei,sans-serif">不得不提起的回馈信息<br /><br /><font face="SimSun,宋体,MS Song,serif" id="nczq"><font id="nczq0">加
入ThoughtWorks以来，发现回馈信息是公司非常注重的一个方面。在TWU的生活中，不但学员之间两周会互相给一次书面的回馈信息，每周需要对这
一周发生的小到食物好吃与否大到老师的培训方式等都要提供回馈信息，平时课堂上即使给出的回馈信息更是数不胜数了。由于我们中国学员的母语不是英语，因此
在前两周培训的过程中，我们有的时候跟不上老师们的语速。结果在第一周五的回顾课程中，不光中国学员，还有许多我们新认识的朋友帮我们提出了这个问题，讨
论的结果就是我们不但在墙上挂起了&ldquo;说慢点！&rdquo;的大幅标语，还发明了一个手势用于提醒老师讲话慢点。回馈信息其实确保了大家都在尽自己最大的努力去做好每
一个方面，同时也培养出一种公正公开的气氛，让我们都朝着自己所树立的目标前进。<br /><br />总结<br /><br />现在想想，公司的一系列生动的培训课程，不但让我们了解公司文化的本质，更重要的是让敏捷软件开发思想深深的扎在了我们心中，我们看到了原来软件开发的过程
可以这样的丰富多彩。TWU的洗礼其实只是带我们入门，不过这些课程在我们真正进入项目后，才会逐渐发挥出一步步深远的作用，例如我现在从事的项目，就时
常让我想起TWU的课程中老师说的方方面面，再结合当前的亲身体验，可谓是获益匪浅。希望本篇的内容也能够对读者有所启迪。<br /></font></font></span></font><br /></font></span></font><p><font size="2">&nbsp;</font></p><!--sp--><div class="relpost"><br/><h3>随机文章：</h3><div><a href="http://phoenixtoday.blogbus.com/logs/28533541.html">ThoughtWorks University 取经记(续)</a> 2008-09-04</div><div><a href="http://phoenixtoday.blogbus.com/logs/35149540.html">活灵活现用Git-技巧篇</a> 2009-02-13</div><div><a href="http://phoenixtoday.blogbus.com/logs/25557507.html">体验真正的敏捷</a> 2008-07-25</div><div><a href="http://phoenixtoday.blogbus.com/logs/38881265.html">翻译Agile Adoption Patterns: A Roadmap to Organizational Success 一书发现的一些常见问题</a> 2009-05-03</div><div><a href="http://phoenixtoday.blogbus.com/logs/33458940.html">活灵活现用Git--基础篇</a> 2009-01-05</div></div><div class="addfav"><br />收藏到：<span class= "delicious"><a href="http://delicious.com/save?url=http%3A%2F%2Fphoenixtoday.blogbus.com%2Flogs%2F27454013.html&title=ThoughtWorks+University+%E5%8F%96%E7%BB%8F%E8%AE%B0">Del.icio.us</a></span></div><br /><br /><div class="sysmsg"><b><a href="http://icity.cn" target="_blank">《城客》：第一本中文互动杂志！</a></b></div><br /><br />]]></description>
   <link>http://phoenixtoday.blogbus.com/logs/27454013.html</link>
   <author></author>
   <pubDate>Sat, 09 Aug 2008 10:00:38 +0800</pubDate>
  </item>
 </channel>
</rss>
