﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>语源科技BlogJava-OOPAA</title><link>http://www.blogjava.net/mingj/</link><description>Focusing on OO, Patterns, Architecture, and Agile</description><language>zh-cn</language><lastBuildDate>Tue, 28 Apr 2026 18:58:44 GMT</lastBuildDate><pubDate>Tue, 28 Apr 2026 18:58:44 GMT</pubDate><ttl>60</ttl><item><title>让非技术人员理解设计</title><link>http://www.blogjava.net/mingj/archive/2010/12/23/341419.html</link><dc:creator>mingj</dc:creator><author>mingj</author><pubDate>Thu, 23 Dec 2010 15:55:00 GMT</pubDate><guid>http://www.blogjava.net/mingj/archive/2010/12/23/341419.html</guid><wfw:comment>http://www.blogjava.net/mingj/comments/341419.html</wfw:comment><comments>http://www.blogjava.net/mingj/archive/2010/12/23/341419.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/mingj/comments/commentRss/341419.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mingj/services/trackbacks/341419.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 作为技术人员，我们经常需要跟客户、业务分析人员等非技术人员沟通软件设计方面的问题。如何比较直观地向这些非技术人员解释设计、软件质量对项目的影响，解释糟糕设计、不干净代码给项目带来的风险，解释我们必须开始关注软家设计问题？这里有两个概念（metaphor）可以帮助我们达到这一点。&nbsp;&nbsp;<a href='http://www.blogjava.net/mingj/archive/2010/12/23/341419.html'>阅读全文</a><img src ="http://www.blogjava.net/mingj/aggbug/341419.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mingj/" target="_blank">mingj</a> 2010-12-23 23:55 <a href="http://www.blogjava.net/mingj/archive/2010/12/23/341419.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>持续检查之sonar初体验</title><link>http://www.blogjava.net/mingj/archive/2010/12/22/341350.html</link><dc:creator>mingj</dc:creator><author>mingj</author><pubDate>Wed, 22 Dec 2010 14:55:00 GMT</pubDate><guid>http://www.blogjava.net/mingj/archive/2010/12/22/341350.html</guid><wfw:comment>http://www.blogjava.net/mingj/comments/341350.html</wfw:comment><comments>http://www.blogjava.net/mingj/archive/2010/12/22/341350.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/mingj/comments/commentRss/341350.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mingj/services/trackbacks/341350.html</trackback:ping><description><![CDATA[<p>安装、启动Sonar：</p>
<p>Sonar的安装很容易，按照Sonar官方主页的安装指南解压缩即可。</p>
<p>Sonar默认使用derby作为数据库，你只需要在sonar.properties文件中去掉对derby数据库属性的注释，然后启动Apache derby数据库。</p>
<p>按照文档介绍，启动Sonar，默认的主页地址是http://localhost:9000，登录用户名和密码是sonar/sonar。</p>
<p>使用Sonar检查代码：</p>
<p>要使用Sonar检查代码，也很容易。</p>
<p>如果待检查项目是maven项目，则只需要安装sonar maven
plugin即可；如果是非maven项目，则需要在项目根目录下创建pom.xml，内容按照文档配置。具体参
见：http://docs.codehaus.org/display/SONAR/Analyzing+Java+Projects</p>
<p>现在只需要项目根目录下，运行mvn sonar:sonar就可以运行sonar maven plugin来检查项目中的代码了。</p>
<p>注意：</p>
<p>如果项目源文件使用的编码与系统的默认字符集不同，比如操作系统是GBK，而源文件编码为UTF-8。为了能够正常地检查代码，需要在pom.xml的properties元素下增加一项配置如:</p>
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">project</span><span style="color: #ff0000;">.build.sourceEncoding</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;">UTF-8</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">project.build.sourceEncoding</span><span style="color: #0000ff;">&gt;</span></div>
<p>否则，sonar在生成checkstyle.xml的时候，不会将正确的编码传进去，导致checkstyle在做AST分析的过程中使用了错误
的字符集，从而提示字符错误：&#8220;expecting 'xxx', but got '&lt;EOF&gt;'&#8221;。即使是在调用mvn
sonar:sonar的时候，增加参数如：</p>
<pre>mvn -Dfile.encoding=UTF-8 -DsourceEncoding=UTF-8 sonar:sonar<br />
</pre>
<p>也无法生效，虽然通过-e开关是可以看到系统的默认字符集已经改成了UTF-8。</p>
<p>好了，sonar已经安装完毕，而且也顺利地完成了代码的分析和检查。</p>
<p>下一步，我们就可以分析sonar输出的报告，判断代码的质量，制定改善的措施了。</p>
<img src ="http://www.blogjava.net/mingj/aggbug/341350.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mingj/" target="_blank">mingj</a> 2010-12-22 22:55 <a href="http://www.blogjava.net/mingj/archive/2010/12/22/341350.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>浮潜与水肺潜水</title><link>http://www.blogjava.net/mingj/archive/2010/09/24/332771.html</link><dc:creator>mingj</dc:creator><author>mingj</author><pubDate>Fri, 24 Sep 2010 13:05:00 GMT</pubDate><guid>http://www.blogjava.net/mingj/archive/2010/09/24/332771.html</guid><wfw:comment>http://www.blogjava.net/mingj/comments/332771.html</wfw:comment><comments>http://www.blogjava.net/mingj/archive/2010/09/24/332771.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mingj/comments/commentRss/332771.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mingj/services/trackbacks/332771.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 浮潜潜水员游弋于海水表层，看鱼戏浅滩，望影掠深海。水肺潜水员可以潜过海水表层的深度；他能潜到更深的地方，在一定的区域内研究那些影子以发现鱼类、沉船残骸以及珊瑚的细节。在相同的时间内，浮潜潜水员可以游历更宽阔的水域；而水肺潜水员则在潜游深度上占据优势。成功的项目团队在项目的整个过程中会把浮潜和水肺潜水这两种方式结合起来使用，在特定的时刻明智地选择合适的方法，从而有效地利用了时间。&nbsp;&nbsp;<a href='http://www.blogjava.net/mingj/archive/2010/09/24/332771.html'>阅读全文</a><img src ="http://www.blogjava.net/mingj/aggbug/332771.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mingj/" target="_blank">mingj</a> 2010-09-24 21:05 <a href="http://www.blogjava.net/mingj/archive/2010/09/24/332771.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>浓浓的特性汤</title><link>http://www.blogjava.net/mingj/archive/2010/09/14/331943.html</link><dc:creator>mingj</dc:creator><author>mingj</author><pubDate>Mon, 13 Sep 2010 23:42:00 GMT</pubDate><guid>http://www.blogjava.net/mingj/archive/2010/09/14/331943.html</guid><wfw:comment>http://www.blogjava.net/mingj/comments/331943.html</wfw:comment><comments>http://www.blogjava.net/mingj/archive/2010/09/14/331943.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/mingj/comments/commentRss/331943.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mingj/services/trackbacks/331943.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 在一开始的时候，一切都显得那么美好。市场部有一个来自于客户的请求——添加额外的下拉菜单。然后，在产品中添加一个输出接口的需求来了，产品经理想要加上一份新的分析报表，DBA要求在数据库里增加一个新字段以改变背景的颜色。所有这些需求以及其他更多的需求，都交由开发人员负责加进到产品里面。随着需求的不断添加，产品的特性集不断增长，但过了一段时间之后，每个人——市场部、客户和开发团队——对如何将所有这些碎片整合在一起、这些碎片如何帮助实现业务目标，失去了理解。曾经带着明确目标出发的项目变成了难以下咽的、由各种无关特性炖成的一锅汤。&nbsp;&nbsp;<a href='http://www.blogjava.net/mingj/archive/2010/09/14/331943.html'>阅读全文</a><img src ="http://www.blogjava.net/mingj/aggbug/331943.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mingj/" target="_blank">mingj</a> 2010-09-14 07:42 <a href="http://www.blogjava.net/mingj/archive/2010/09/14/331943.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>同事预审</title><link>http://www.blogjava.net/mingj/archive/2010/08/31/330455.html</link><dc:creator>mingj</dc:creator><author>mingj</author><pubDate>Tue, 31 Aug 2010 13:19:00 GMT</pubDate><guid>http://www.blogjava.net/mingj/archive/2010/08/31/330455.html</guid><wfw:comment>http://www.blogjava.net/mingj/comments/330455.html</wfw:comment><comments>http://www.blogjava.net/mingj/archive/2010/08/31/330455.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mingj/comments/commentRss/330455.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mingj/services/trackbacks/330455.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 在如今大部分的组织里面，是否给申请技术职位的人提供工作机会——这个最终决定权属于管理部门。经理们雇人，经理们裁人：一切都天经地义。然而在某些组织里面，这些技术人员能否得到工作机会却是取决于——至少部分取决于——他们将来的同事。这种同事预审的最终结果只有一种：当经理们让技术职员拥有发言权的时候，每一个人——申请人、职员和经理——都会和盘托出自己的想法。&nbsp;&nbsp;<a href='http://www.blogjava.net/mingj/archive/2010/08/31/330455.html'>阅读全文</a><img src ="http://www.blogjava.net/mingj/aggbug/330455.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mingj/" target="_blank">mingj</a> 2010-08-31 21:19 <a href="http://www.blogjava.net/mingj/archive/2010/08/31/330455.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一叶知秋</title><link>http://www.blogjava.net/mingj/archive/2010/08/04/327880.html</link><dc:creator>mingj</dc:creator><author>mingj</author><pubDate>Tue, 03 Aug 2010 17:04:00 GMT</pubDate><guid>http://www.blogjava.net/mingj/archive/2010/08/04/327880.html</guid><wfw:comment>http://www.blogjava.net/mingj/comments/327880.html</wfw:comment><comments>http://www.blogjava.net/mingj/archive/2010/08/04/327880.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/mingj/comments/commentRss/327880.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mingj/services/trackbacks/327880.html</trackback:ping><description><![CDATA[（一）<br />
与客户吃饭。客户抱怨，&#8220;我司人员流失大，无法建设团队文化。&#8221;我说，&#8220;以你司推行的工具为例，其思路就是把团队定位于低级、傻瓜式的水平。那么，超出这个水平的人离去、不足这个水平的人加入，不正是延续并巩固了这种傻瓜式的团队文化么？&#8221;<br />
<br />
（二）<br />
工具或许无关好坏，但要警惕的是工具传递的创建者的价值观。推广工具遭遇困境，原因就在于推广者的价值观与接受者不合，双方价值观上面的认同没有到位。如果以外力强制推行，甚至上升为价值标准，孔夫子曰：始作俑者，其无后乎？<br />
<img src ="http://www.blogjava.net/mingj/aggbug/327880.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mingj/" target="_blank">mingj</a> 2010-08-04 01:04 <a href="http://www.blogjava.net/mingj/archive/2010/08/04/327880.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>玩的就是心跳（Adrenaline Junkies）</title><link>http://www.blogjava.net/mingj/archive/2010/07/30/327612.html</link><dc:creator>mingj</dc:creator><author>mingj</author><pubDate>Fri, 30 Jul 2010 14:44:00 GMT</pubDate><guid>http://www.blogjava.net/mingj/archive/2010/07/30/327612.html</guid><wfw:comment>http://www.blogjava.net/mingj/comments/327612.html</wfw:comment><comments>http://www.blogjava.net/mingj/archive/2010/07/30/327612.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/mingj/comments/commentRss/327612.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mingj/services/trackbacks/327612.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 组织相信忙乱的工作状态象征了健康的生产率。&nbsp;&nbsp;<a href='http://www.blogjava.net/mingj/archive/2010/07/30/327612.html'>阅读全文</a><img src ="http://www.blogjava.net/mingj/aggbug/327612.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mingj/" target="_blank">mingj</a> 2010-07-30 22:44 <a href="http://www.blogjava.net/mingj/archive/2010/07/30/327612.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>保姆型项目经理</title><link>http://www.blogjava.net/mingj/archive/2010/07/26/327179.html</link><dc:creator>mingj</dc:creator><author>mingj</author><pubDate>Mon, 26 Jul 2010 15:38:00 GMT</pubDate><guid>http://www.blogjava.net/mingj/archive/2010/07/26/327179.html</guid><wfw:comment>http://www.blogjava.net/mingj/comments/327179.html</wfw:comment><comments>http://www.blogjava.net/mingj/archive/2010/07/26/327179.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/mingj/comments/commentRss/327179.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mingj/services/trackbacks/327179.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 项目经理的很多技能都与传统的英式保姆有共同之处。&nbsp;&nbsp;<a href='http://www.blogjava.net/mingj/archive/2010/07/26/327179.html'>阅读全文</a><img src ="http://www.blogjava.net/mingj/aggbug/327179.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mingj/" target="_blank">mingj</a> 2010-07-26 23:38 <a href="http://www.blogjava.net/mingj/archive/2010/07/26/327179.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>欢乐的鼓掌会议</title><link>http://www.blogjava.net/mingj/archive/2010/07/20/326676.html</link><dc:creator>mingj</dc:creator><author>mingj</author><pubDate>Tue, 20 Jul 2010 13:54:00 GMT</pubDate><guid>http://www.blogjava.net/mingj/archive/2010/07/20/326676.html</guid><wfw:comment>http://www.blogjava.net/mingj/comments/326676.html</wfw:comment><comments>http://www.blogjava.net/mingj/archive/2010/07/20/326676.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/mingj/comments/commentRss/326676.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mingj/services/trackbacks/326676.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 高涨的士气永远象征着组织的健康。与之类似，低弱的士气则说明肯定有什么地方做错了。有一种管理理念就是奉这种关系如圭臬，试图从相反的方向来利用这种关系。逻辑是这样的：把士气鼓舞起来，其他美好的东西也就跟随而至。&nbsp;&nbsp;<a href='http://www.blogjava.net/mingj/archive/2010/07/20/326676.html'>阅读全文</a><img src ="http://www.blogjava.net/mingj/aggbug/326676.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mingj/" target="_blank">mingj</a> 2010-07-20 21:54 <a href="http://www.blogjava.net/mingj/archive/2010/07/20/326676.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一次非典型性JSF调试过程</title><link>http://www.blogjava.net/mingj/archive/2009/09/28/296707.html</link><dc:creator>mingj</dc:creator><author>mingj</author><pubDate>Sun, 27 Sep 2009 18:01:00 GMT</pubDate><guid>http://www.blogjava.net/mingj/archive/2009/09/28/296707.html</guid><wfw:comment>http://www.blogjava.net/mingj/comments/296707.html</wfw:comment><comments>http://www.blogjava.net/mingj/archive/2009/09/28/296707.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/mingj/comments/commentRss/296707.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mingj/services/trackbacks/296707.html</trackback:ping><description><![CDATA[<h2>问题</h2>
<p> 前一阵子使用JSF开发web应用程序的过程中，碰到一个需求：A页面上存在一个链接，用户点击链接会被重定向B页面。页面B上存在一个单选框，如果是通过A页面的链接过来，会把单选框置为&#8220;选择&#8221;的状态。这是非常典型的页面转向，根据JSF的页面转向配置，以及对JSF隐含对象param的介绍，下面的代码&#8220;貌似&#8221;可行：
</p>
<blockquote> A页面：
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;">
<span style="color: #0000ff;">&lt;</span><span style="color: #800000;">h:commandLink&nbsp;</span><span style="color: #ff0000;">value</span><span style="color: #0000ff;">="Add"</span><span style="color: #ff0000;">&nbsp;action</span><span style="color: #0000ff;">="add"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">f:param&nbsp;</span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="type"</span><span style="color: #ff0000;">&nbsp;value</span><span style="color: #0000ff;">="student"</span><span style="color: #ff0000;">&nbsp;</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">h:commandLink</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"> <br />
</span></div>
B页面：
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;">
<span style="color: #0000ff;">&lt;</span><span style="color: #800000;">h:form</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">h:selectOneRadio&nbsp;</span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">="type"</span><span style="color: #ff0000;">&nbsp;value</span><span style="color: #0000ff;">="#{param.type}"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">f:selectItem&nbsp;</span><span style="color: #ff0000;">itemlabel</span><span style="color: #0000ff;">="student"</span><span style="color: #ff0000;">&nbsp;itemvalue</span><span style="color: #0000ff;">="student"</span><span style="color: #ff0000;">&nbsp;</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">f:selectItem&nbsp;</span><span style="color: #ff0000;">itemlabel</span><span style="color: #0000ff;">="teacher"</span><span style="color: #ff0000;">&nbsp;itemvalue</span><span style="color: #0000ff;">="teacher"</span><span style="color: #ff0000;">&nbsp;</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">h:selectOneRadio</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">h:commandButton&nbsp;</span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">="add"</span><span style="color: #ff0000;">&nbsp;action</span><span style="color: #0000ff;">="#{backingBean.add}"</span><span style="color: #ff0000;">&nbsp;</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">h:form</span><span style="color: #0000ff;">&gt;</span></div>
</blockquote>
<p> 编译、部署、重新刷新页面。不错，B页面上单选框的状态能根据是否来自A页面的链接呈现选中或否的状态：一切看上去都很美，似乎已经完成了功能开发。但是，等等，让我们提交表单。浏览器刷新了一遍，又回到了这个页面。通过检查后台数据库以及日志文件，我们发现：
</p>
<ul>
    <li>数据库里面并没有添加新的记录</li>
    <li>系统也没有按照配置的navigation转向正确的页面</li>
    <li>glassfish的日志文件中没有add方法执行打印的日志，也没有任何异常信息</li>
</ul>
这三点说明，#{backingBean.add}方法并没有调用，原来可以工作的添加功能出现了bug。JSF在处理页面提交请求的过程中发生了什么？让我们来调试一下。
<h2>原则</h2>
<p> 在软件开发中，调试的目的是解决&#8220;如何定位系统问题所在&#8221;的问题。一般意义上，解决问题的原则，套用胡适先生的话，就是&#8220;大胆假设，小心求证&#8221;；套用《麦肯锡方法》，则是&#8220;以事实为基础，以假设为导向，结构化推理&#8221;。具体来看，调试是这样一种分析问题的方法，面对复杂的问题，通过逐步确定正确或者错误的事情，缩小问题范围，直到定位问题所在为止。把事情确定化，也可以细分为以下步骤：
</p>
<ul>
    <li>提出猜想</li>
    <li>验证猜想 or 捕获异常</li>
    <li>提出新的猜想</li>
</ul>
在调试过程中，上面的步骤周而复始，并借助于严密的逻辑论证来推动，直到定位最终的问题原因为止。同时，因为调试的过程中，开发人员面对的是已经&#8220;编码完成&#8221;的系统。&#8220;编码完成&#8221;的系统可以从如下两个层面来看分解：
<ul>
    <li>技术层面</li>
    <li>业务层面</li>
</ul>
如何高效调试不仅仅是调试工具的问题，更是人对技术和业务领域的理解问题。在面对具体问题的时候，是采用&#8220;步步为营&#8221;，还是&#8220;分而治之&#8221;，都是依赖于当时的具体问题，以及开发人员对问题场景的理解程度和技术熟悉程度。那么，高效地调试应该是什么样子呢？我觉得应该是这样的：
<ul>
    <li>划定问题域边界</li>
    <li>选择确定的出发点</li>
    <li>借助其他已经确定的点走查问题域，缩小问题域</li>
</ul>
好，来看看针对JSF的这个问题如何调试。
<h2>步骤</h2>
<p>
我们先来划定我们初始的问题域：JSF请求提交后，JSF不能正常调用后台方法进行处理。我们想知道，JSF处理请求过程中哪个地方出问题了。那么我们确定的点是什么呢？JSF规范。因为我们使用的是SUN开发的JSF RI，所以它必然满足JSF规范。在规范中，JSF的请求处理过程一共分成六个阶段：
</p>
<ol>
    <li>Restore View</li>
    <li>Apply Request Values</li>
    <li>Process Validations</li>
    <li>Update Model Values</li>
    <li>Invoke Application</li>
    <li>Render Response</li>
</ol>
<p> 我们可以定义一个PhaseListener，注册到faces-configs.xml文件里面，看整个请求过程发生了什么？通过查看 glassfish的日志文件，我们发现update model values之后就直接render response，没有 invoke application。 如果一切正常，应该是从第一步执行到第六步，但现在跳过了第五步，直接从第四步到了第六步，是哪里出现了问题？好，从&#8220;JSF的处理过程&#8221;到&#8220;第四步 Update Model Values&#8221;，我们已经缩小了问题域的范围，现在确定的点已经有JSF规范和 &#8220;Update Model Values&#8221;了。继续，从JSF规范对步骤&#8220;&#8221;中寻找&#8220;Update Model Values&#8221;的说明：
</p>
<blockquote>
If any of the updateModel() methods that was invoked, or an event listener that processed a queued event, called renderResponse() on the FacesContext instance for the current request, clear the remaining events from the event queue and transfer control to the Render Response phase of the request processing lifecycle. Otherwise, control must proceed to the Invoke Application phase.
</blockquote>
<p> 这里提到如果我们在updateModel()方法或者事件监听器里面调用了FacesContext的renderResponse()方法，就会从事件队列里面直接清空剩下的事件，转向Render Response步骤。但是我们没有注册任何的事件监听器，也没有自定义任何组件的 updateModel()方法，那就只能是在系统组件的updateModel()方法里面抛出异常被JSF引擎捕获，然后直接 render response。现在进一步缩小范围了，让我们来看看Javaapi doc里面是如何介绍UIInput.updateModel() 方法的。 </p>
<blockquote cite="http://java.sun.com/javaee/javaserverfaces/1.2_MR1/docs/api/javax/faces/component/UIInput.html#updateModel(javax.faces.context.FacesContext)"> Call setValue() method of the ValueExpression to update the value that the ValueExpression points at. </blockquote>
<p>问题转移到javax.el.ValueExpression的setValue()方法，我们来看看这个方法的API：</p>
<blockquote cite="http://java.sun.com/products/jsp/2.1/docs/jsp-2_1-pfd2/javax/el/ValueExpression.html#setValue(javax.el.ELContext, java.lang.Object)"> Evaluates the expression relative to the provided context, and sets the result to the provided value.<br />
<strong>Throws:</strong><br />
PropertyNotFoundException - if one of the property resolutions failed because a specified variable or property does not exist or is not readable. </blockquote>
<p> 再来看看组件的ValueExpression，我们写的是&#8220;${param.key}&#8221;，从文档里面可以得知param就是 externalContext.getRequestParameterMap()，而 ExternalContext.getRequestParameterMap()的文档描写是这样的：
</p>
<blockquote>Return an immutable Map whose keys are the set of request parameters names included in the current request, and whose values (of type String) are the first (or only) value for each parameter name returned by the underlying request. </blockquote>
<p> 因为表单提交时的request跟之前页面转向时的Request肯定不是一样，那是否由于该ValueExpression导致的问题。让我们来验证一下，把B页面上单选框组件的值改成字符串字面值&#8220;student&#8221;。现在B页面的单选框组件就变成了：
</p>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;">
<span style="color: #0000ff;">&lt;</span><span style="color: #800000;">h:form</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">h:selectOneRadio&nbsp;</span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">="type"</span><span style="color: #ff0000;">&nbsp;value</span><span style="color: #0000ff;">="student"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">f:selectItem&nbsp;</span><span style="color: #ff0000;">itemLabel</span><span style="color: #0000ff;">="student"</span><span style="color: #ff0000;">&nbsp;itemValue</span><span style="color: #0000ff;">="student"</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">f:selectItem&nbsp;</span><span style="color: #ff0000;">itemLabel</span><span style="color: #0000ff;">="teacher"</span><span style="color: #ff0000;">&nbsp;itemValue</span><span style="color: #0000ff;">="teacher"</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">h:selectOneRadio</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">h:commandButton&nbsp;</span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">="add"</span><span style="color: #ff0000;">&nbsp;action</span><span style="color: #0000ff;">="#{backingBean.add}"</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">h:form</span><span style="color: #0000ff;">&gt;</span></div>
<p> 部署，运行。不错，现在的页面组件能保持选中的状态，也能顺利创建新纪录，日志文件中也有add方式的执行信息：说明的确是因为#{param.key} 表达式的求值出错导致异常。这里的#{param}已经不再是上一步的#{param}，自然无法从externalContext的 RequestParameterMap里面找到参数名为type的值。因此，JSF运行到这里，因为无法取到参数值去更新页面的单选框组件，所以就跳出了处理过程。</p>
<p>
现在，回过头来看一下问题的原因：JSF在处理请求的时候，会对页面组件树上的所有组件进行递归更新，它会根据组件定义的EL表达式来重新计算值，更新组件状态，以保证JSF页面组件的状态性。我们得到的教训是param等JSF隐含对象或许能用，但最好不要放在JSF组件里面。&#8220;进什么庙，拜什么神&#8221;，我们还是选择JSF推荐的backingbean来保持组件的值。
</p>
<h2>结语</h2>
<p> 软件调试是一项很有意思的活动，常常给开发人员带来解谜般的快感，或者一团乱麻的纠结。导入代码、设置断点、逐步调试并不是最好的办法，清楚地划分问题域，找准确定点可能会事半功倍。当然，在找出水面下面的暗礁之后，别忘记给自己、给其他人mark上这块区域的暗礁位置，能极大减少以后触礁的痛苦。
</p>
<img src ="http://www.blogjava.net/mingj/aggbug/296707.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mingj/" target="_blank">mingj</a> 2009-09-28 02:01 <a href="http://www.blogjava.net/mingj/archive/2009/09/28/296707.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>浅谈软件开发的权利和权力</title><link>http://www.blogjava.net/mingj/archive/2009/07/11/286378.html</link><dc:creator>mingj</dc:creator><author>mingj</author><pubDate>Sat, 11 Jul 2009 09:37:00 GMT</pubDate><guid>http://www.blogjava.net/mingj/archive/2009/07/11/286378.html</guid><wfw:comment>http://www.blogjava.net/mingj/comments/286378.html</wfw:comment><comments>http://www.blogjava.net/mingj/archive/2009/07/11/286378.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mingj/comments/commentRss/286378.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mingj/services/trackbacks/286378.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 在日常生活中，有各种各样的法律规则和道德准则来约束、指导行为。比如在初次的商业合作中，双方都会选择制定一份详尽的合约来规约双方，包括双方拥有的具体权利、以及单方出错时对方享有的权利等。软件开发，在商业上面也必然会有详尽的合约，处理的是两个组织之间的利害关系。但是，软件开发同时作为紧密involve商业客户与开发团队的活动，正如Alistair Cockburn把它比喻称为game——由客户、管理层和开发人员共同play的game，其中也需要由参与play game的各方利害人来共同制定规则，让大家都能玩得开心、尽兴，甚至长久。这样，围绕着多赢长赢的出发点来play game，就同样需要这样一份“权利法案”，对开发过程中的三方利益利害人的权利做出基本的原则上的规定。在敏捷软件开发方法中，特别是极限编程中，就存在这样一份“权利法案”。&nbsp;&nbsp;<a href='http://www.blogjava.net/mingj/archive/2009/07/11/286378.html'>阅读全文</a><img src ="http://www.blogjava.net/mingj/aggbug/286378.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mingj/" target="_blank">mingj</a> 2009-07-11 17:37 <a href="http://www.blogjava.net/mingj/archive/2009/07/11/286378.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>AgileChina 2009: Pragmatic Agile [转]</title><link>http://www.blogjava.net/mingj/archive/2009/07/06/285699.html</link><dc:creator>mingj</dc:creator><author>mingj</author><pubDate>Mon, 06 Jul 2009 11:57:00 GMT</pubDate><guid>http://www.blogjava.net/mingj/archive/2009/07/06/285699.html</guid><wfw:comment>http://www.blogjava.net/mingj/comments/285699.html</wfw:comment><comments>http://www.blogjava.net/mingj/archive/2009/07/06/285699.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mingj/comments/commentRss/285699.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mingj/services/trackbacks/285699.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 由在敏捷领域最具有影响力的技术社区InfoQ中文站、敏捷方法论的领导厂商 ThoughtWorks共同主办的敏捷中国技术大会（Agile China 2009），将于9月11日~12日（周五、周六）在北京举行。届时将有超过500人来自电信、金融、互联网、教育等行业在内的高级软件开发人员、项目管 理人员等参加。本次大会将特别邀请敏捷宣言缔造者、敏捷编程（XP）方法学创始人Kent Beck，敏捷开发权威人士、敏捷宣言的创始人之一，Dave Thomas，敏捷宣言签署人之一Steve Freeman等国际敏捷领域专家，以及在团队中成功应用敏捷的阿尔卡特、赛门铁克、诺基亚-西门子、华为、腾讯等公司的项目负责人参与此次大会并分享他 们的心得。&nbsp;&nbsp;<a href='http://www.blogjava.net/mingj/archive/2009/07/06/285699.html'>阅读全文</a><img src ="http://www.blogjava.net/mingj/aggbug/285699.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mingj/" target="_blank">mingj</a> 2009-07-06 19:57 <a href="http://www.blogjava.net/mingj/archive/2009/07/06/285699.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>线上出版社的一些想法</title><link>http://www.blogjava.net/mingj/archive/2009/06/28/284456.html</link><dc:creator>mingj</dc:creator><author>mingj</author><pubDate>Sun, 28 Jun 2009 03:12:00 GMT</pubDate><guid>http://www.blogjava.net/mingj/archive/2009/06/28/284456.html</guid><wfw:comment>http://www.blogjava.net/mingj/comments/284456.html</wfw:comment><comments>http://www.blogjava.net/mingj/archive/2009/06/28/284456.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/mingj/comments/commentRss/284456.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mingj/services/trackbacks/284456.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 上周末参加openparty，来自译言的几个朋友详细解释了他们预想的译言的收费模式。简单来说，译言会出面买下一些文章或书刊的版权，签约译者进行申领翻译。当译文通过审核，译言就把原文以及译文打包作为收费文章挂在译言收费频道上，按点击率来收费；或者转卖给其他网站，也可以按整文收费。最后，原文作者、译文作者和译言三方来分取利润。如果受好评足够高，译言还可能将译文提供出版，不再仅仅局限在网络上面，而是进入广大的书店。本文着重谈谈译言的出版计划，试图分析在这个时代，谁更有可能脱颖而出，引领行业浪潮？&nbsp;&nbsp;<a href='http://www.blogjava.net/mingj/archive/2009/06/28/284456.html'>阅读全文</a><img src ="http://www.blogjava.net/mingj/aggbug/284456.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mingj/" target="_blank">mingj</a> 2009-06-28 11:12 <a href="http://www.blogjava.net/mingj/archive/2009/06/28/284456.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>敏捷，把纪律留下（下）</title><link>http://www.blogjava.net/mingj/archive/2009/06/18/282983.html</link><dc:creator>mingj</dc:creator><author>mingj</author><pubDate>Thu, 18 Jun 2009 01:42:00 GMT</pubDate><guid>http://www.blogjava.net/mingj/archive/2009/06/18/282983.html</guid><wfw:comment>http://www.blogjava.net/mingj/comments/282983.html</wfw:comment><comments>http://www.blogjava.net/mingj/archive/2009/06/18/282983.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/mingj/comments/commentRss/282983.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mingj/services/trackbacks/282983.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 在很多人看来，实施了敏捷，似乎就等于纵容程序员，允许他们不把纪律放在眼里。事实是这样子么？本文发表于《程序员》杂志2009年6期，因篇幅较长，故分为两段，本篇为下篇。&nbsp;&nbsp;<a href='http://www.blogjava.net/mingj/archive/2009/06/18/282983.html'>阅读全文</a><img src ="http://www.blogjava.net/mingj/aggbug/282983.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mingj/" target="_blank">mingj</a> 2009-06-18 09:42 <a href="http://www.blogjava.net/mingj/archive/2009/06/18/282983.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>敏捷，把纪律留下（上）</title><link>http://www.blogjava.net/mingj/archive/2009/06/18/282982.html</link><dc:creator>mingj</dc:creator><author>mingj</author><pubDate>Thu, 18 Jun 2009 01:40:00 GMT</pubDate><guid>http://www.blogjava.net/mingj/archive/2009/06/18/282982.html</guid><wfw:comment>http://www.blogjava.net/mingj/comments/282982.html</wfw:comment><comments>http://www.blogjava.net/mingj/archive/2009/06/18/282982.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mingj/comments/commentRss/282982.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mingj/services/trackbacks/282982.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 在很多人看来，实施了敏捷，似乎就等于纵容程序员，允许他们不把纪律放在眼里。事实是这样子么？本文发表于《程序员》杂志2009年6期，因篇幅较长，故分为两段，本篇为上篇。&nbsp;&nbsp;<a href='http://www.blogjava.net/mingj/archive/2009/06/18/282982.html'>阅读全文</a><img src ="http://www.blogjava.net/mingj/aggbug/282982.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mingj/" target="_blank">mingj</a> 2009-06-18 09:40 <a href="http://www.blogjava.net/mingj/archive/2009/06/18/282982.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>迭代经理是什么角色？（下）【译】</title><link>http://www.blogjava.net/mingj/archive/2009/06/14/282171.html</link><dc:creator>mingj</dc:creator><author>mingj</author><pubDate>Sun, 14 Jun 2009 07:45:00 GMT</pubDate><guid>http://www.blogjava.net/mingj/archive/2009/06/14/282171.html</guid><wfw:comment>http://www.blogjava.net/mingj/comments/282171.html</wfw:comment><comments>http://www.blogjava.net/mingj/archive/2009/06/14/282171.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mingj/comments/commentRss/282171.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mingj/services/trackbacks/282171.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 行业日新月异，敏捷、迭代式和迭代这些热门词已是“飞入寻常百姓家”，一个定义模糊的新角色——迭代经理，也浮出水面。这是新一代的项目经理么？抑或是美其名的团队带头人？又或者是管理上的一个新阶层？谁会被冠以这个“经理”头衔？本文将着重阐述迭代经理作为软件团队成员的工作内容和价值。我们将分析迭代经理的职责范围，同时讨论作为一个不可或缺的角色，迭代经理在面对组织和文化挑战的情况下，如何维持一个健康的工作环境。本文是全文的下部分。&nbsp;&nbsp;<a href='http://www.blogjava.net/mingj/archive/2009/06/14/282171.html'>阅读全文</a><img src ="http://www.blogjava.net/mingj/aggbug/282171.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mingj/" target="_blank">mingj</a> 2009-06-14 15:45 <a href="http://www.blogjava.net/mingj/archive/2009/06/14/282171.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>迭代经理是什么角色？（中）【译】</title><link>http://www.blogjava.net/mingj/archive/2009/06/13/282048.html</link><dc:creator>mingj</dc:creator><author>mingj</author><pubDate>Sat, 13 Jun 2009 08:31:00 GMT</pubDate><guid>http://www.blogjava.net/mingj/archive/2009/06/13/282048.html</guid><wfw:comment>http://www.blogjava.net/mingj/comments/282048.html</wfw:comment><comments>http://www.blogjava.net/mingj/archive/2009/06/13/282048.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/mingj/comments/commentRss/282048.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mingj/services/trackbacks/282048.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 行业日新月异，敏捷、迭代式和迭代这些热门词已是“飞入寻常百姓家”，一个定义模糊的新角色——迭代经理，也浮出水面。这是新一代的项目经理么？抑或是美其名的团队带头人？又或者是管理上的一个新阶层？谁会被冠以这个“经理”头衔？本文将着重阐述迭代经理作为软件团队成员的工作内容和价值。我们将分析迭代经理的职责范围，同时讨论作为一个不可或缺的角色，迭代经理在面对组织和文化挑战的情况下，如何维持一个健康的工作环境。本文是全文的中部分。&nbsp;&nbsp;<a href='http://www.blogjava.net/mingj/archive/2009/06/13/282048.html'>阅读全文</a><img src ="http://www.blogjava.net/mingj/aggbug/282048.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mingj/" target="_blank">mingj</a> 2009-06-13 16:31 <a href="http://www.blogjava.net/mingj/archive/2009/06/13/282048.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>迭代经理是什么角色？（上）【译】</title><link>http://www.blogjava.net/mingj/archive/2009/06/13/282007.html</link><dc:creator>mingj</dc:creator><author>mingj</author><pubDate>Sat, 13 Jun 2009 04:21:00 GMT</pubDate><guid>http://www.blogjava.net/mingj/archive/2009/06/13/282007.html</guid><wfw:comment>http://www.blogjava.net/mingj/comments/282007.html</wfw:comment><comments>http://www.blogjava.net/mingj/archive/2009/06/13/282007.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/mingj/comments/commentRss/282007.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mingj/services/trackbacks/282007.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 行业日新月异，敏捷、迭代式和迭代这些热门词已是“飞入寻常百姓家”，一个定义模糊的新角色——迭代经理，也浮出水面。这是新一代的项目经理么？抑或是美其名的团队带头人？又或者是管理上的一个新阶层？谁会被冠以这个“经理”头衔？本文将着重阐述迭代经理作为软件团队成员的工作内容和价值。我们将分析迭代经理的职责范围，同时讨论作为一个不可或缺的角色，迭代经理在面对组织和文化挑战的情况下，如何维持一个健康的工作环境。本文是全文的上部分。&nbsp;&nbsp;<a href='http://www.blogjava.net/mingj/archive/2009/06/13/282007.html'>阅读全文</a><img src ="http://www.blogjava.net/mingj/aggbug/282007.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mingj/" target="_blank">mingj</a> 2009-06-13 12:21 <a href="http://www.blogjava.net/mingj/archive/2009/06/13/282007.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>敏捷、生产力和商业价值</title><link>http://www.blogjava.net/mingj/archive/2009/05/22/277406.html</link><dc:creator>mingj</dc:creator><author>mingj</author><pubDate>Fri, 22 May 2009 12:19:00 GMT</pubDate><guid>http://www.blogjava.net/mingj/archive/2009/05/22/277406.html</guid><wfw:comment>http://www.blogjava.net/mingj/comments/277406.html</wfw:comment><comments>http://www.blogjava.net/mingj/archive/2009/05/22/277406.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/mingj/comments/commentRss/277406.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mingj/services/trackbacks/277406.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 我们曾举办了一次为期三天的敏捷培训，学员主要是一些知名软件公司的项目经理和资深开发人员。培训期间，我们带领学员进行了丰富的游戏，通过寓教于乐的方式让他们体验了敏捷方法学的大部分知名实践，并讲解了敏捷方法学推崇的价值和原则。从学员的回顾以及意见表上可以看出培训效果是显著的，但是在培训过程中学员也提到一些问题，主要是对敏捷方法学的实践和价值比较疑惑。在回答问题的同时，我们能感觉到随着敏捷方法学在国内被引入、被宣传，很多软件组织或人员对敏捷方法学都已经有了基本的了解，但是对敏捷方法学向软件行业承诺的价值还存在不同程度的顾虑。&nbsp;&nbsp;<a href='http://www.blogjava.net/mingj/archive/2009/05/22/277406.html'>阅读全文</a><img src ="http://www.blogjava.net/mingj/aggbug/277406.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mingj/" target="_blank">mingj</a> 2009-05-22 20:19 <a href="http://www.blogjava.net/mingj/archive/2009/05/22/277406.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一次 Refactoring to Functionality 的实践</title><link>http://www.blogjava.net/mingj/archive/2009/05/16/270988.html</link><dc:creator>mingj</dc:creator><author>mingj</author><pubDate>Sat, 16 May 2009 07:15:00 GMT</pubDate><guid>http://www.blogjava.net/mingj/archive/2009/05/16/270988.html</guid><wfw:comment>http://www.blogjava.net/mingj/comments/270988.html</wfw:comment><comments>http://www.blogjava.net/mingj/archive/2009/05/16/270988.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/mingj/comments/commentRss/270988.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/mingj/services/trackbacks/270988.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 对于软件开发，多少代工程师梦想能像堆积木一样堆出满足功能需求的软件。Brooks在No Silver Bullet一文中提到解决软件开发过程中复杂性的一种可能方案就是成熟的组件市场，人们可以购买需要的组件而不是再自行开发。但对于开发工作，有没有一种更高层面的模式，可以把原来混乱无序的开发过程分解成一段段明确定义的步骤？比如说，开发人员接到一个任务，他可以这样跟他的同伴解释他的计划：“我先要抽取类（extract class），然后移动方法（move method），就完成了。”这正是本文试图讨论的主题：通过一系列明确定义的重构步骤，以达到实现系统功能的目的。我们可以进一步假想，重构是否就是开发人员开发软件的领域专属语言呢（refactoring as DSLs to developers' development）&nbsp;&nbsp;<a href='http://www.blogjava.net/mingj/archive/2009/05/16/270988.html'>阅读全文</a><img src ="http://www.blogjava.net/mingj/aggbug/270988.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/mingj/" target="_blank">mingj</a> 2009-05-16 15:15 <a href="http://www.blogjava.net/mingj/archive/2009/05/16/270988.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>