﻿<?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-子在川上曰-随笔分类-项目日记</title><link>http://www2.blogjava.net/chengang/category/8413.html</link><description>　　　　逝者如斯乎不舍昼夜</description><language>zh-cn</language><lastBuildDate>Wed, 28 Feb 2007 04:18:17 GMT</lastBuildDate><pubDate>Wed, 28 Feb 2007 04:18:17 GMT</pubDate><ttl>60</ttl><item><title>"知识管理及信息传递"是项目成功的关键点</title><link>http://www.blogjava.net/chengang/archive/2006/08/30/66565.html</link><dc:creator>陈刚</dc:creator><author>陈刚</author><pubDate>Wed, 30 Aug 2006 01:31:00 GMT</pubDate><guid>http://www.blogjava.net/chengang/archive/2006/08/30/66565.html</guid><wfw:comment>http://www.blogjava.net/chengang/comments/66565.html</wfw:comment><comments>http://www.blogjava.net/chengang/archive/2006/08/30/66565.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/chengang/comments/commentRss/66565.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/chengang/services/trackbacks/66565.html</trackback:ping><description><![CDATA[公司项目太庞大了（30多个子项目，数百万行的代码），在最近的系统大重构后，版本发布推迟了两月。老大让我提提意见，于是我提了如下意见。<br /><br /><br /><h2 style="MARGIN: 12pt 0cm"><span style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">代码质量</span></h2><ul><li><div class="a" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span style="mso-tab-count: 1"> </span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">定期</span><span lang="EN-US">Code review</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。总结他人经验，学习他人之长。</span></div></li><li><div class="a" style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">开放maven的单元测试。一步步来，至少要强制性的要求每远程交互接口都有单元测试代码。同时，单元测试代码也要为</span><span lang="EN-US">code review</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的一部份。</span></div></li></ul><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><span style="mso-tab-count: 1">       </span></span></p><h2 style="MARGIN: 12pt 0cm"><span style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">知识管理及信息的有交传递</span></h2><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">知识管理及信息的有效传递的效率低下，我认为这是本次版本发布延期的根本原因。为此我提出以下建议：</span></p><h3 style="MARGIN: 12pt 0cm 6pt"><font face="宋体, MS Song" size="3">一、利用<span lang="EN-US">google</span>的桌面搜索，让信息获取的简单、快速、全面。实现步骤如下：</font></h3><p class="a" style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 39.0pt"><span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">1.<span style="FONT: 7pt 'Times New Roman'">         </span></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在局域网内创建一个专用于文档的共享文件夹。</span></p><p class="a" style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 39.0pt"><span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">2.<span style="FONT: 7pt 'Times New Roman'">         </span></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">文件夹中存在公司所有文档，最好是分类分目录存放</span></p><p class="a" style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 39.0pt"><span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">3.<span style="FONT: 7pt 'Times New Roman'">         </span></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在文件共享服务器上安装一个网页抓取器，把</span><span lang="EN-US">jira</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">上的信息每天抓取保存。</span></p><p class="a" style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 39.0pt"><span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">4.<span style="FONT: 7pt 'Times New Roman'">         </span></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">各同事的在自己的电脑里创建一个“公文包”，将局域网的文件复制到本机公文包中。</span></p><p class="a" style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 39.0pt"><span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">5.<span style="FONT: 7pt 'Times New Roman'">         </span></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">各同事定期更新公文包</span></p><p class="a" style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 39.0pt"><span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">6.<span style="FONT: 7pt 'Times New Roman'">         </span></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">各同事在本机安装</span><span lang="EN-US">GOOGLE</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的桌面搜索。</span></p><p class="a" style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 39.0pt"><span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">7.<span style="FONT: 7pt 'Times New Roman'">         </span></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">将公文包设置到</span><span lang="EN-US">GOOGLE</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的桌面搜索</span></p><p class="a" style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 39.0pt"><span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">8.<span style="FONT: 7pt 'Times New Roman'">         </span></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">将本机项目源文件目录，以及一切你自己的文档设置到</span><span lang="EN-US">GOOGLE</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的桌面搜索</span></p><p class="a" style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 39.0pt"><span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">9.<span style="FONT: 7pt 'Times New Roman'">         </span></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在初始化时</span><span lang="EN-US">google</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">会花一些时间去创建搜索库，之后再用就会很快了。</span></p><p class="a" style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -21pt; mso-list: l0 level1 lfo1; tab-stops: list 39.0pt"><span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'"><span style="mso-list: Ignore">10.<span style="FONT: 7pt 'Times New Roman'">     </span></span></span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">各同事如果在工作中遇到问题，使用</span><span lang="EN-US">GOOGLE</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的桌面搜索，就可以全面快速的搜索到你想要的资料。</span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">实现过程详见，操作视频：</span><span lang="EN-US"><a href="file://corpserver/share/software/google/GoogleDesktopEnterprise.avi">\\corpserver\share\software\google\GoogleDesktopEnterprise.avi</a><b style="mso-bidi-font-weight: normal"><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /?><o:p></o:p></b></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><o:p> </o:p></span></p><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><o:p> </o:p></span></p><img src ="http://www.blogjava.net/chengang/aggbug/66565.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/chengang/" target="_blank">陈刚</a> 2006-08-30 09:31 <a href="http://www.blogjava.net/chengang/archive/2006/08/30/66565.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[项目日记] 源代码管理出现麻烦</title><link>http://www.blogjava.net/chengang/archive/2006/04/29/43919.html</link><dc:creator>陈刚</dc:creator><author>陈刚</author><pubDate>Sat, 29 Apr 2006 00:30:00 GMT</pubDate><guid>http://www.blogjava.net/chengang/archive/2006/04/29/43919.html</guid><wfw:comment>http://www.blogjava.net/chengang/comments/43919.html</wfw:comment><comments>http://www.blogjava.net/chengang/archive/2006/04/29/43919.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/chengang/comments/commentRss/43919.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/chengang/services/trackbacks/43919.html</trackback:ping><description><![CDATA[
		<div>这个月Neil回加拿大休假三周。谁知，他一走系统就出现了问题，一些紧急的新需求又接踵而来。程序员忙于Fix Bug实现新需求，一晃眼，出现了三个CVS活动分支，程序员把代码都在分支上修改和fix。现在的结果是，源代码变得难以控制，分支上fix的bug在主干上没有fix，你要保证主干＋三分活动分支上都fix bug谈何容易，源代码乱成了一锅粥。<br /><br />Neil回来后专门就此事开了一个会，参考现在Open Source流行的做法，定下了这样的做法和原则：<br /><br />（1）每发布一个版本，打一个分支，用分支固定住代码。然后，在这个分支进行版本分布。<br />（2）所有fix bug都应在主干上，保证主干上的代码永远是最新。<br />（3）如果分支的分布版本（也是正在生产系统工作的版本），出现严重bug，则在分布上打一个Patch，而不是在分支上fix bug，分支上代码是应该被冻结的。如果不是严重到必须要fix，则bug应该等到下一个发布版本。<br />（4）新需求不能在分支上代码添加，要在主干上实现，并在下一个版本分布。<br />（5）根据新需求的数量要紧急程序，加快新版本的发布步骤（由原来三个月，改为一个月）。增加测试员（现2人，再增2人）。<br /><br />越来越有点敏捷的开发方式的味道了。我提出要着手推行自动单元测试，这样才能以支撑住快的发布频率。Neil同意，但并没有采纳，只建议程序员尽量写自动单元测试。<br /><br />效果如何，下一步会怎么样，轼目以待吧。<br /><br /></div>
<img src ="http://www.blogjava.net/chengang/aggbug/43919.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/chengang/" target="_blank">陈刚</a> 2006-04-29 08:30 <a href="http://www.blogjava.net/chengang/archive/2006/04/29/43919.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>给RCP系统添加全局快捷键</title><link>http://www.blogjava.net/chengang/archive/2006/04/28/43873.html</link><dc:creator>陈刚</dc:creator><author>陈刚</author><pubDate>Fri, 28 Apr 2006 13:35:00 GMT</pubDate><guid>http://www.blogjava.net/chengang/archive/2006/04/28/43873.html</guid><wfw:comment>http://www.blogjava.net/chengang/comments/43873.html</wfw:comment><comments>http://www.blogjava.net/chengang/archive/2006/04/28/43873.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/chengang/comments/commentRss/43873.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/chengang/services/trackbacks/43873.html</trackback:ping><description><![CDATA[
		<div>               文/陈刚 from <a href="http://www.chengang.com.cn/"><font color="#1111cc">www.chengang.com.cn</font></a>　at 2006年4月28日<br /><br />一个RCP系统，给它添加一个象Eclipse中Ctrl+Shift+O一样的全局快捷键，怎么加？<br /><br />参考了RCP的Email项目示例，给我RCP项目中MonitorAction（显示一个监视器的命<br />令）添加一个快捷键Ctrl+1。简单把添加的过程概述如下：<br /><br />1、首先在plugin.xml中添加两个扩展点如下<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 78.81%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; HEIGHT: 334px; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">   </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">extension<br />         point</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">org.eclipse.ui.bindings</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br />      </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">key<br />            commandId</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">org.eclipse.ui.file.exit</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br />            schemeId</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">org.eclipse.ui.defaultAcceleratorConfiguration</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br />            sequence</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">CTRL+X</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">/&gt;</span><span style="COLOR: #000000"><br />      </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">key<br />            commandId</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">adminconsole.monitor</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br />            schemeId</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">org.eclipse.ui.defaultAcceleratorConfiguration</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br />            sequence</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">CTRL+1</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">/&gt;</span><span style="COLOR: #000000"><br />   </span><span style="COLOR: #000000">&lt;/</span><span style="COLOR: #000000">extension</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><br />   </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">extension<br />         point</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">org.eclipse.ui.commands</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br />      </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">category<br />            id</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">adminconsole.perspective</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br />            name</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Perspective</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">/&gt;</span><span style="COLOR: #000000"><br />      </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">command<br />            categoryId</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">adminconsole.perspective</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br />            id</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">adminconsole.monitor</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br />            name</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Open Monitor Perspective</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">/&gt;</span><span style="COLOR: #000000"><br />   </span><span style="COLOR: #000000">&lt;/</span><span style="COLOR: #000000">extension</span><span style="COLOR: #000000">&gt;</span></div></div>
		<br />说明：<br /><span style="COLOR: #000000">。org.eclipse.ui.file.exit是另一个退出系统命令，是复用了Eclipse本身的那个，它和本例无关。<br />。commandId要求唯一<br />。cmmands扩展点的category是一个组，估计不要也可以，最后还是加上吧。<br />。bindings扩展点中的commandId对应于cmmands扩展点中的id<br /><br /><br /><br />2、创建一个类，专门保存所有commandId<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 81.01%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; HEIGHT: 52px; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">interface</span><span style="COLOR: #000000"> ICommandIds {<br />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">final</span><span style="COLOR: #000000"> String CMD_MONITOR </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">adminconsole.monitor</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">;<br />}<br /></span></div>    <br /><br />3、创建Action类，在构造函数里用两个方法注册一下<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 81.69%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; HEIGHT: 161px; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> MonitorAction </span><span style="COLOR: #0000ff">extends</span><span style="COLOR: #000000"> Action {<br />        </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> MonitorAction() {<br />            setText(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">监视</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br />            </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> The id is used to refer to the action in a menu or toolbar</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">            setId(ICommandIds.CMD_MONITOR);<br />            </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> Associate the action with a pre-defined command, to allow key bindings.</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">            setActionDefinitionId(ICommandIds.CMD_MONITOR);<br />        }<br /><br />        ...<br />    }<br /></span></div><div></div></span><br />4、在ApplicationActionBarAdvisor的makeActions方法，给monitorAction对象加上这样一句 
<div> </div><div><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 81.01%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; HEIGHT: 25px; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">register(monitorAction);</span></div><br />注意：如果你没有在plugin.xml和makeActions做上面讲过的设置，加上这一句将可能导致<br />你的RCP系统无法启动。</div><img src ="http://www.blogjava.net/chengang/aggbug/43873.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/chengang/" target="_blank">陈刚</a> 2006-04-28 21:35 <a href="http://www.blogjava.net/chengang/archive/2006/04/28/43873.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>RCP中包更新后的处理</title><link>http://www.blogjava.net/chengang/archive/2006/04/27/43494.html</link><dc:creator>陈刚</dc:creator><author>陈刚</author><pubDate>Thu, 27 Apr 2006 02:33:00 GMT</pubDate><guid>http://www.blogjava.net/chengang/archive/2006/04/27/43494.html</guid><wfw:comment>http://www.blogjava.net/chengang/comments/43494.html</wfw:comment><comments>http://www.blogjava.net/chengang/archive/2006/04/27/43494.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/chengang/comments/commentRss/43494.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/chengang/services/trackbacks/43494.html</trackback:ping><description><![CDATA[
		<div>我gef、emf的包还是以前老的，现在用的是Eclipse 3.2M6，于是去eclipse.org下载了相应版gef/emf，更新一下。<br /><br />这一更新问题来了，项目运行不起来了。报名application id找不到（或product找不到，记不太清）。以下是处理的过程。<br /><br /><br />（1）把????.product依赖包重新弄了一遍。不行。<br />（2）把run..中的依赖包重新弄了一遍，用run来运行。成功。<br />（3）通过????.product的项目导出功能，导出项目后运行。运行失败。<br />（4）嗯，可能是????.product中依赖包没有调整。于是和（1）一样重新弄了依赖包。再次导出项目还是不行。并且用run来运行，又失败了。<br />（5）看来run..对????.product没有影响，????.product反过来对run..里的设定产生的影响。<br />（6）重做了（2）步，再删除????.product，重新生成????.product。所有问题都解决，运行成功，项目导出后也运行成功。<br /><br />总结，看来更新依赖包后，至少要做以下处理<br />（1）在run..中调整依赖包.<br />（2）重建???.product文件。</div>
<img src ="http://www.blogjava.net/chengang/aggbug/43494.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/chengang/" target="_blank">陈刚</a> 2006-04-27 10:33 <a href="http://www.blogjava.net/chengang/archive/2006/04/27/43494.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[TDD开发的全过程] 三、抽取公共类 </title><link>http://www.blogjava.net/chengang/archive/2006/04/19/41915.html</link><dc:creator>陈刚</dc:creator><author>陈刚</author><pubDate>Wed, 19 Apr 2006 07:22:00 GMT</pubDate><guid>http://www.blogjava.net/chengang/archive/2006/04/19/41915.html</guid><wfw:comment>http://www.blogjava.net/chengang/comments/41915.html</wfw:comment><comments>http://www.blogjava.net/chengang/archive/2006/04/19/41915.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/chengang/comments/commentRss/41915.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/chengang/services/trackbacks/41915.html</trackback:ping><description><![CDATA[
		<div>                    文/陈刚  at 2006年4月19日 from <a href="http://www.chengang.com.cn/">http://www.chengang.com.cn</a><br /><br />一、前言<br /><br />在前面一章中，我有这样的想法。<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">在这里我面临一个选择，是先写界面呢？还是先写底层API？我想，先写界面很难写测试代码，而且界面在设计时已经定下来了，基本不会变了</span></div></div>
		<br />后来我又想，界面固然变化很少了，但界面内容需要调用的后台API却是未曾定型，所以如果在TDD时从界面写起也许更合适，因为界面本身和测试用例一样，也算是后台API的一个用户。<br /><br />在写SWT的界面很烦的是无法应用TDD，甚至无法写自动单元测试代码。单元测试在界面开发中显得特别无力，在&lt;&lt;JUnit in Action&gt;&gt;这本书中虽然说到JSP的测试，但Swing的自动测试没有提及，更不要说SWT了。我曾多方寻找SWT的自动测试框架，在eclips.org上有eclipse-test-framework，不过使用很复杂，至今还没怎么搞懂。虽然界面测试很困难，但我们还是可以通过一些小技术来加速界面开发，和进行半自动测试的。<br /><br />不过本篇且不是讲SWT界面的测试的，这里只是临时记下自己的一些想法。这篇主要讲的抽取公共类。<br /><br />二、抽取公共类类<br /><br />TDD有一个基本思想：拒绝代码的复制/粘帖。也就是说一段相同的代码，在项目中应该只存在一处。同理，从更高处来说，几个项目中常用的类也应该只存在于一处。其实，我们平时编程就已经发现很多类和代码是通用的，不过我们依然习惯于去老项目中翻看代码，然后复制粘贴于新项目中来。这样的做法是违反TDD“拒绝代码的复制/粘帖”原则的，所以在平时我们就应该注意提炼自己的公共代码库，说不定几年后我们就能形成自己的一个框架，很多框架和类库不就是这样形成的吗，比如 appache 的commons系列，比如Struts、比如Spring。<br /><br />今天我抽取的公共类是一个图标闪烁类，和一个时间显示Label。如下图，图中上部左边的“邮件图标”和右边的“时间显示”，可以抽取出来做成公共类，在各种SWT项目中使用。特别是邮件图标的闪烁显示，因为SWT还不支持动态GIF，所以只能用多线程轮换图片的方式来实现图标闪烁，我想这样的类提取出来，用作还是挺大的。<br /><br /><img height="270" alt="3-1.jpg" src="http://www.blogjava.net/images/blogjava_net/chengang/others/3-1.jpg" width="190" border="0" /><br /><br /><br /><br />三、FlashImage类<br /><br />这里没有让FlashImage 继承自Label，而是内嵌了一个Label。这是应用于组合优先于继承的原则，并且Label是不可继承的，虽然SWT中并没有把它定义成Final ，但却会在其内部做一个子类检查，如果是继承自Label则会报出异常。和Label一样的还是Shell，虽然没有final 修饰符，但也是不可继承的。<br /><br />这里还涉及SWT的多线程编程，在停止线程时不能用Thead#stop方法的，这个方法已经禁用了。另外，线程要在label#dispose后也关闪掉，所以在label加了一个disponse的事件监听。<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">package</span><span style="COLOR: #000000"> cn.com.chengang.myswt;<br /><br /></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000"> org.eclipse.core.runtime.Assert;<br /></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000"> org.eclipse.swt.events.DisposeEvent;<br /></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000"> org.eclipse.swt.events.DisposeListener;<br /></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000"> org.eclipse.swt.events.MouseListener;<br /></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000"> org.eclipse.swt.graphics.Image;<br /></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000"> org.eclipse.swt.widgets.Composite;<br /></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000"> org.eclipse.swt.widgets.Display;<br /></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000"> org.eclipse.swt.widgets.Label;<br /><br /></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000"> cn.com.chengang.common.util.CommonUtil;<br /><br /></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> FlashImage {<br />    </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000"> Label flashLabel;<br />    </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000"> Image stopImage;<br />    </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000"> Image[] flashImages;<br />    </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">long</span><span style="COLOR: #000000"> flashSpaceTime </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">100</span><span style="COLOR: #000000">; </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">闪动间隔时间</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000"><br />    </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">boolean</span><span style="COLOR: #000000"> progressStop </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">; </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">处理是否停止的标志</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000"><br />    </span><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"><br />     * </span><span style="COLOR: #808080">@param</span><span style="COLOR: #008000"> comp<br />     * </span><span style="COLOR: #808080">@param</span><span style="COLOR: #008000"> style 与Label的style相同<br />     * </span><span style="COLOR: #808080">@param</span><span style="COLOR: #008000"> flashImages 闪动的图像<br />     * </span><span style="COLOR: #808080">@param</span><span style="COLOR: #008000"> stopImage 停止时的图像<br />     </span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> FlashImage(Composite comp, </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> style, Image[] flashImages, Image stopImage) {<br />        Assert.isTrue(flashImages </span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000"> flashImages.length </span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">);<br />        flashLabel </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> Label(comp, style);<br />        </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.flashImages </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> flashImages;<br />        </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.stopImage </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> stopImage;<br />        flashLabel.setImage(stopImage);<br />        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">监听Dispose事件,在其销毁时停掉线程</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">        flashLabel.addDisposeListener(</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> DisposeListener() {<br />            </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> widgetDisposed(DisposeEvent e) {<br />                progressStop </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">;<br />            }<br />        });<br />    }<br /><br />    </span><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"><br />     * 开始闪动<br />     </span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> flash() {<br />        </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">progressStop)<br />            </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">;<br /><br />        progressStop </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">false</span><span style="COLOR: #000000">;<br />        </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> ImageFlashThread().start();<br />    }<br /><br />    </span><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"><br />     * 停止闪动<br />     </span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> flashStop() {<br />        progressStop </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">;<br />    }<br /><br />    </span><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"><br />     * 设置闪动间隔的时间<br />     * </span><span style="COLOR: #808080">@param</span><span style="COLOR: #008000"> time 默认100(100毫秒)<br />     </span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> setFlashSpaceTime(</span><span style="COLOR: #0000ff">long</span><span style="COLOR: #000000"> time) {<br />        </span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">.flashSpaceTime </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> time;<br />    }<br /><br />    </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000"> Display getDisplay() {<br />        </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> Display.getDefault();<br />    }<br /><br />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> addMouseListener(MouseListener listener) {<br />        flashLabel.addMouseListener(listener);<br />    }<br /><br />    </span><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"><br />     * 闪动图像线程<br />     </span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br />    </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> ImageFlashThread </span><span style="COLOR: #0000ff">extends</span><span style="COLOR: #000000"> Thread {<br />        </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> run() {<br />            </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> i </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br />            </span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000"> (</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">progressStop) {<br />                </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (i </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> flashImages.length)</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">到头循环</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">                    i </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br />                setCurrentImage(flashImages[i]);<br />                CommonUtil.sleep(flashSpaceTime);</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">闪动间隔</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">                i</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">;<br />            }<br />            setCurrentImage(stopImage);<br />        }<br /><br />        </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> setCurrentImage(</span><span style="COLOR: #0000ff">final</span><span style="COLOR: #000000"> Image image) {<br />            getDisplay().asyncExec(</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> Runnable() {<br />                </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> run() {<br />                    flashLabel.setImage(image);<br />                }<br />            });<br />        }<br />    }<br /><br />}<br /></span></div><br /><br /><br />给出一个客户端使用的示例：<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">                Image[] flashs </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> Image[] {<br />                        ImagesContext.getImage(ImagesContext.MAIL),    //ImagesContext是我自己写的一个管理Image的类<br />                        ImagesContext.getImage(ImagesContext.MAIL_GRAY) };<br />                Image stopImage </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> ImagesContext.getImage(ImagesContext.MAIL);<br /><br />                flashImage </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> FlashImage(c, SWT.NONE, flashs, stopImage);<br />                flashImage.setFlashSpaceTime(</span><span style="COLOR: #000000">800</span><span style="COLOR: #000000">);<br />                flashImage.addMouseListener(</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> MouseAdapter() {<br />                    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> mouseDown(MouseEvent e) {<br />                            //do something......<br />                    }<br />                });</span></div><br /><br /><br />四、TimeLabel类<br /><br />时间显示Label则和FlashImage类似，可以说是它的一个简化版<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><div><span style="COLOR: #0000ff">package</span><span style="COLOR: #000000"> cn.com.chengang.myswt;<br /><br /></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000"> java.text.DateFormat;<br /></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000"> java.text.SimpleDateFormat;<br /></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000"> java.util.Date;<br /><br /></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000"> org.eclipse.swt.events.DisposeEvent;<br /></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000"> org.eclipse.swt.events.DisposeListener;<br /></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000"> org.eclipse.swt.layout.GridData;<br /></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000"> org.eclipse.swt.widgets.Composite;<br /></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000"> org.eclipse.swt.widgets.Display;<br /></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000"> org.eclipse.swt.widgets.Label;<br /><br /></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000"> cn.com.chengang.common.util.CommonUtil;<br /><br /></span><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"><br /> * </span><span style="COLOR: #808080">@author</span><span style="COLOR: #008000"> chengang 2006-4-19<br /> </span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br /></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> TimeLabel {<br />    </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000"> Label timeLabel;<br />    </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">long</span><span style="COLOR: #000000"> flashSpaceTime </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">480</span><span style="COLOR: #000000">; </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">闪动间隔时间</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">boolean</span><span style="COLOR: #000000"> progressStop </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">false</span><span style="COLOR: #000000">; </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">处理是否停止的标志</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000"> DateFormat dateFormat </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> SimpleDateFormat(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">HH:mm:ss</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br /><br />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> TimeLabel(Composite comp, </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> style) {<br />        timeLabel </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> Label(comp, style);<br />        timeLabel.setText(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">sssssssssssssssssss</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br />        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">监听Dispose事件,在其销毁时停掉线程</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">        timeLabel.addDisposeListener(</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> DisposeListener() {<br />            </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> widgetDisposed(DisposeEvent e) {<br />                progressStop</span><span style="COLOR: #000000">=</span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">;<br />            }<br />        });<br />        </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> ShowTimeThread().start();<br />    }<br /><br />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> dispose() {<br />        progressStop </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">;<br />    }<br /><br />    </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000"> Display getDisplay() {<br />        </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> Display.getDefault();<br />    }<br /><br />    </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> ShowTimeThread </span><span style="COLOR: #0000ff">extends</span><span style="COLOR: #000000"> Thread {<br />        </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> run() {<br />            </span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000"> (</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">progressStop) {<br />                String str </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> dateFormat.format(</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> Date());<br />                setText(str);<br />                CommonUtil.sleep(flashSpaceTime);</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">闪动间隔<br /><span style="COLOR: #008000">                       //CommonUtil是我自己写的一个常用工具方法类，sleep的代码如下</span><br /></span><span style="COLOR: #008000">                       //public class CommonUtil {<br /></span><span style="COLOR: #008000"><span style="COLOR: #008000"><span style="COLOR: #008000">                       </span>//</span>    public static void sleep(long millis) {<br /><span style="COLOR: #008000"><span style="COLOR: #008000">                       </span>//</span>        try {<br /><span style="COLOR: #008000"><span style="COLOR: #008000">                       </span>//</span>            Thread.sleep(millis);<br /><span style="COLOR: #008000"><span style="COLOR: #008000">                       </span>//</span>        } catch (InterruptedException e) {<br /><span style="COLOR: #008000"><span style="COLOR: #008000">                       </span>//</span>            e.printStackTrace();<br /><span style="COLOR: #008000"><span style="COLOR: #008000">                       </span>//</span>        }<br /><span style="COLOR: #008000"><span style="COLOR: #008000">                       </span>//</span>    }<br /></span><span style="COLOR: #000000">            }<br />        }<br /><br />        </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> setText(</span><span style="COLOR: #0000ff">final</span><span style="COLOR: #000000"> String time) {<br />            getDisplay().asyncExec(</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> Runnable() {<br />                </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> run() {<br />                    timeLabel.setText(time);<br />                }<br />            });<br />        }<br />    }<br /><br />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> setLayoutData(GridData data) {<br />        timeLabel.setLayoutData(data);<br />    }<br /><br />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> setDateFormate(DateFormat format) {<br />        dateFormat </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> format;<br />    }<br /><br />}</span></div></div><br /><br />客户端的使用代码示例：<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">                TimeLabel timeLabel </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> TimeLabel(topComp, SWT.NONE);<br /></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">                timeLabel.setDateFormate(new SimpleDateFormat("HH:mm:ss"));</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">                timeLabel.setLayoutData(</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> GridData(GridData.END, GridData.CENTER, </span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">, </span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">));<br /></span></div><br /><br /><h5><font size="4">作者简介</font></h5><p>陈刚，广西桂林人，著作有《Eclipse从入门到精通》<br />您可以通过其博客了解更多信息和文章：<a href="http://www.chengang.com.cn/" target="_blank" &#111;nfocus="this.blur()"><font color="#000033">http://www.ChenGang.com.cn</font></a><br />版权声明：本博客所有文章仅适用于非商业性转载，并请在转载时注明出处及作者的署名</p><img src ="http://www.blogjava.net/chengang/aggbug/41915.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/chengang/" target="_blank">陈刚</a> 2006-04-19 15:22 <a href="http://www.blogjava.net/chengang/archive/2006/04/19/41915.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[TDD开发的全过程] 二、开发PhoneManager等类</title><link>http://www.blogjava.net/chengang/archive/2006/04/13/40878.html</link><dc:creator>陈刚</dc:creator><author>陈刚</author><pubDate>Thu, 13 Apr 2006 05:59:00 GMT</pubDate><guid>http://www.blogjava.net/chengang/archive/2006/04/13/40878.html</guid><wfw:comment>http://www.blogjava.net/chengang/comments/40878.html</wfw:comment><comments>http://www.blogjava.net/chengang/archive/2006/04/13/40878.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/chengang/comments/commentRss/40878.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/chengang/services/trackbacks/40878.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 文/陈刚 at 2006年4月13日　from www.ChenGang.com.cn一、前言今天我把文章的名称改了一下，想把它写成关于TDD实践的一系列文章。前一篇是设计，这一篇开始是开发。TDD我是闻名已久，在过去实际开发中也经常用junit来写单元测试，但真正的TDD却从来没有尝试过。不过单元测试写得久了，发现TDD确实有它诱人的地方，也许它真的可以带我领略一个新的编程世界。于是，又再次翻开...&nbsp;&nbsp;<a href='http://www.blogjava.net/chengang/archive/2006/04/13/40878.html'>阅读全文</a><img src ="http://www.blogjava.net/chengang/aggbug/40878.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/chengang/" target="_blank">陈刚</a> 2006-04-13 13:59 <a href="http://www.blogjava.net/chengang/archive/2006/04/13/40878.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[TDD开发的全过程] 一、设计阶段</title><link>http://www.blogjava.net/chengang/archive/2006/04/12/40684.html</link><dc:creator>陈刚</dc:creator><author>陈刚</author><pubDate>Wed, 12 Apr 2006 08:51:00 GMT</pubDate><guid>http://www.blogjava.net/chengang/archive/2006/04/12/40684.html</guid><wfw:comment>http://www.blogjava.net/chengang/comments/40684.html</wfw:comment><comments>http://www.blogjava.net/chengang/archive/2006/04/12/40684.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://www.blogjava.net/chengang/comments/commentRss/40684.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/chengang/services/trackbacks/40684.html</trackback:ping><description><![CDATA[
		<div align="left">　　　　　　　　　　　　文/陈刚 at 2006年4月12日　from <a href="http://www.chengang.com.cn/">www.ChenGang.com.cn</a><br /><br /><br />前段时间把一个界面框架完成了，今天基于这个框架开发一个小模块，在这里把这个模块设计的全过程记录下来，希望大家讨论并指正。<br /><br />一、起因<br /><br />公司交给我一个任务，为测试员写一个手机模拟界面，以方便她们的手机短信测试。过去她们都是用MC4J直接调用公司服务器的MBean服务来模拟进行测试，以验证我们整个系统平台。这种测试主要是检查收发短信是否正常，而我的要做的工作就是，让她们在测试的时候更方便更直观。<br /><br />二、需求<br /><br />我和测试员陈MM（也就是软件的使用者）约定了一个时间，大家一起来讨论这个软件的需求。<br /><br />1、首先，我大概了解了一下她们的测试工作，知道我要做个什么东东。<br /><br />2、然后我回去思考了一下，再次找她详细了解其测试的具体步骤，并在一张<strong>白纸</strong>上以UML用例图的方式，记录下需求的功能。<strong>用例是什么？用例就是需求，就是你的软件应该具有的功能</strong>，当然用例图只是概括性的对功能进行了描述。<br /><br />3、最后，我坐在我的电脑前开始用MagicDraw UML来画用例图（我不喜欢用Rose，那玩意太笨重了，界面友好性也不好）。在画用例图的时候，我发现了一些隐含的功能，这些是陈MM在和我做需求时没有考虑到的<strong>（注：开发者应该为用户挖掘隐含需求）</strong>。我和陈MM一一确定了这些我新发现的需求，最后得到如下的用例图。<br /><br />（1）手机前台测试操作的用例图（说明：include是指某用例<strong>包含(include)</strong>子用例）<br /><br /><img style="WIDTH: 623px; HEIGHT: 330px" height="410" alt="[用例]手机.jpg" src="http://www.blogjava.net/images/blogjava_net/chengang/others/[用例]手机.jpg" width="1429" border="0" /><br /> （2）后台管理<br /><img height="258" alt="[用例]后台管理.jpg" src="http://www.blogjava.net/images/blogjava_net/chengang/others/[用例]后台管理.jpg" width="392" border="0" /><br /><br /><br />三、界面设计<br /><br />接下来是界面设计。既然是手机模拟，我很自然就拿我的motorola手机的操作界面来做参考。不过这里应该注意到，手机操作环境和电脑操作环境不尽相同（比如说电脑有鼠标，还有键盘可以输入文字），所以没有必要唯妙唯肖的完全模枋，还是以使用者操作方便为主。<br /><br />界面设计是很重要的一步，不要一上来就写程序，一定要先做到心中有个大概，否则返工的可能性就很大。而且，把界面拿出来给客户看，客户也就能做到心中有数，还能尽早提出一些新需求和意见来。千万不要等到软件做完了再拿给客户看，到时客户看了如果要修改，那就做太多白费工了。<br /><br />由于软件界面相对简单，陈ＭＭ基本没有提修改意见，但这不是个好兆头。不过极限编程就是要拥抱变化不是^_^。咱不怕她改，只要大致的界面她能定下来就行了。<br /><br />界面我喜欢用Visio来画，当然也听说有人喜欢用ＶＢ来快速构建界面原型的，看个人喜好了。整个界面如下：<br /><img height="611" alt="[界面设计]手机.jpg" src="http://www.blogjava.net/images/blogjava_net/chengang/others/[界面设计]手机.jpg" width="556" border="0" /><br /><br /><br /><br />这个是后台管理界面<br /><img height="480" alt="[界面设计]号码管理.jpg" src="http://www.blogjava.net/images/blogjava_net/chengang/others/[界面设计]号码管理.jpg" width="478" border="0" /><br /><br /><br /><br />四、类图<br /><br />类图反映了软件的数据模型。在设计数据模型，我参考了界面设计图和用例图，找出一个个的类。然后参照用例图的一个个功能，设计出了各类的属性和方法。设计初始的类图当然不可能很详细，但至少应该看到个大概。有错误不要紧，后期可以慢慢修正，但大体关系就算定下来了。<br /><br /><strong>Neil（公司ＣＴＯ，一个40岁左右的真正的资深程序员）说：看一个软件的设计主要看两个类：类图和时序图。类图确定了软件数据模型的静态关型，时序图则是数据模型的动态关系。</strong><br /><br />类图如下，看英文大致可以知道类／属性／方法的含义和作用了，就不一一介绍了。<br /><br /><br /><img height="562" alt="[类图].jpg" src="http://www.blogjava.net/images/blogjava_net/chengang/others/[类图].jpg" width="625" border="0" /><br /><br /><br /><br />五、时序图<br /><br />时序图是本文最后一个图，时序图表明了<strong>用例图</strong>中各功能的实现方案，同时也反应了<strong>类图</strong>中各类的交互关系。以后程序的逻辑和时序图基本一致。不过，有些人会去画得很详细的时序图，详细到都快赶上伪代码级别了，我觉得这没必要。我把时序图看做反映自己思路的大概过程，所以也就画个大概。<br /><br />我认为时序图要简洁易懂，这样以后你的后继维护者，拿到这个软件的时序图（当然也包括用例图、类图），就能明白你的大概设计思路。另外，画时序图也能整理自己的思路，同时还可以对类图的设计进行验证。在画这个时序图的过程中，我就纠正了在类图中的几处考虑不周的地方。<br /><br />总结：时序图可以（１）整理思路（２）验证类的设计（３）是很好的软件文档，对维护者理解代码很有帮助。<br /><br />这里仅给出其中几个时序图（实际上我也没有把用例都画完，有些类似的简单的，就忽略了）<br /><br />（１）新增一个手机号码<br /><img height="327" alt="[时序图]add phone number.jpg" src="http://www.blogjava.net/images/blogjava_net/chengang/others/[时序图]add%20phone%20number.jpg" width="583" border="0" /><br /><br />（２）关机<br /><img height="255" alt="[时序图]power off.jpg" src="http://www.blogjava.net/images/blogjava_net/chengang/others/[时序图]power%20off.jpg" width="293" border="0" /><br />（３）开机<br /><img height="337" alt="[时序图]power on.jpg" src="http://www.blogjava.net/images/blogjava_net/chengang/others/[时序图]power%20on.jpg" width="407" border="0" /><br />（４）发送短信<br /><img height="381" alt="[时序图]send message.jpg" src="http://www.blogjava.net/images/blogjava_net/chengang/others/[时序图]send%20message.jpg" width="405" border="0" /><br /><br /><br /><br />到这里设计阶段就完成了，用时一天。下一步是编码，将应用ＴＤＤ先写测试代码的方式来写代码，下次再介绍了。<br /><br /><br /><h5><font size="4">作者简介</font></h5><p>陈刚，广西桂林人，著作有《Eclipse从入门到精通》<br />您可以通过其博客了解更多信息和文章：<a href="http://www.chengang.com.cn/" target="_blank" &#111;nfocus="this.blur()"><font color="#000033">http://www.ChenGang.com.cn</font></a><br />版权声明：本博客所有文章仅适用于非商业性转载，并请在转载时注明出处及作者的署名。</p></div>
<img src ="http://www.blogjava.net/chengang/aggbug/40684.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/chengang/" target="_blank">陈刚</a> 2006-04-12 16:51 <a href="http://www.blogjava.net/chengang/archive/2006/04/12/40684.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一个界面框架的设计</title><link>http://www.blogjava.net/chengang/archive/2006/03/14/35179.html</link><dc:creator>陈刚</dc:creator><author>陈刚</author><pubDate>Tue, 14 Mar 2006 01:48:00 GMT</pubDate><guid>http://www.blogjava.net/chengang/archive/2006/03/14/35179.html</guid><wfw:comment>http://www.blogjava.net/chengang/comments/35179.html</wfw:comment><comments>http://www.blogjava.net/chengang/archive/2006/03/14/35179.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/chengang/comments/commentRss/35179.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/chengang/services/trackbacks/35179.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 一个图形界面框架的设计，包括了它的用例图、类图、时序图，以及相应的说明。&nbsp;&nbsp;<a href='http://www.blogjava.net/chengang/archive/2006/03/14/35179.html'>阅读全文</a><img src ="http://www.blogjava.net/chengang/aggbug/35179.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/chengang/" target="_blank">陈刚</a> 2006-03-14 09:48 <a href="http://www.blogjava.net/chengang/archive/2006/03/14/35179.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>