﻿<?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-Read Sean-随笔分类-Project Management</title><link>http://www.blogjava.net/sean/category/38.html</link><description>Read me, read Sean.</description><language>zh-cn</language><lastBuildDate>Sat, 14 Apr 2007 06:57:44 GMT</lastBuildDate><pubDate>Sat, 14 Apr 2007 06:57:44 GMT</pubDate><ttl>60</ttl><item><title>[愚公移山] 团队CVS资源库从CVSNT迁移到Linux</title><link>http://www.blogjava.net/sean/archive/2007/04/14/110640.html</link><dc:creator>大胃</dc:creator><author>大胃</author><pubDate>Sat, 14 Apr 2007 06:54:00 GMT</pubDate><guid>http://www.blogjava.net/sean/archive/2007/04/14/110640.html</guid><wfw:comment>http://www.blogjava.net/sean/comments/110640.html</wfw:comment><comments>http://www.blogjava.net/sean/archive/2007/04/14/110640.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sean/comments/commentRss/110640.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sean/services/trackbacks/110640.html</trackback:ping><description><![CDATA[
		<br />
昨天(周五)大家下班后，一个人留在公司，把核心产品开发团队使用了整整1年的CVS资源库从CVSNT移到了Linux平台下，原本以为会很简单很顺利，因为之前类似的移植并不是没有做过，所以预估的时间包括验证在内是1~2个小时，不过最终却花掉4个小时。怎么回事呢？且听我慢慢道来。<br /><br />
经过1年的积累，资源库有400多M，大大小小的Java项目有206个之多。按照最初的计划，移植只需要原封不动的把资源库目录整个从CVSNT服务器拷贝到Linux服务器即可，所以资源库大小和项目多少本来不是啥大问题，但谁料半路却杀出个程咬金：.jar文件在新的资源库checkout到本地后无法正常使用，这还了得？<br /><br />
仔细一看，乖乖，原本"Binary"的文件，在新的资源库下，却变成了"ASCII -kkv"，不仅是.jar，其他的二进制文件如.jpg, .exe之类的也是同样的问题。第一反应是CVSNT和Unix经典的CVS在处理RCS文件时还是有些不同，以至于原本在CVSNT下文件类别的标记信息如"Binary"在移植过程中丢失了，变成默认的文本类型。之前有朋友提醒的.doc文件移植后无法打开应该也是同样问题。怎么办？一个文件一个文件的改？肯定不现实。<br /><br />
一种方案是把所有出现的二进制文件类型/后缀名找出来，然后在服务器端批量删除(Linux下写个脚本来做这件事并不难)，客户端这边从原资源库checkout最新版本，重定向资源库URL到新的资源库，同步，提交。这招比较狠，但最终没有用，因为在浏览现有资源库时，发现还有不少其他问题，如classes文件夹被加到版本控制中，类似还有.settings文件夹，甚至Thumbs.db，不一而足。时间有限，与其每个Java项目去找一遍，整理出需要删除的文件(夹)清单，然后写脚本，然后强行资源库重定向，不如一步一个脚印把现有资源库的所有Java项目捋一遍，至少心里踏实。于是一狠心、一咬牙，有洁癖的我开始了漫长的"愚公移山"：一个项目接一个项目，遇到Binary文件，服务器删之，客户端checkout后从原来的地方拷贝过来，必要的地方加上.cvsignore，再添加提交。*<br /><br />
经过4个小时的努力，终于大功告成：自动编译脚本正确运行，构建成功，客户端IDE(Eclipse)从新的资源库checkout，编译通过，没有红叉。<br /><br />
后记：自己认为计划得再好的事情，真正去做的时候，总还是会遇到这样那样的问题和意想不到的状况，这件事也告诉我自己其实我的前期准备远不够充分，算是自食其果吧。有没有更好的办法，我觉得肯定有，但是在特定的情况下(时间/效率/目标)，我相信我的方法还是能够让我自己满意的。还有一点提醒所有CVS的用户，不该提交的文件，最好第一时间加到.cvsignore。子曾经曰过：“纠正错误，时间最早，代价越小”。<br /><br />
* <em>请勿不假思索的模仿，这样做会丢失掉这些文件的历史版本信息，如果删除的时候不小心，同时还会把历史上存在过的同类型文件删掉。我这里之所以可以这么做，是因为我们的实际情况对这些二进制文件不需要保留历史信息。</em><br /><br /><br /><img src ="http://www.blogjava.net/sean/aggbug/110640.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sean/" target="_blank">大胃</a> 2007-04-14 14:54 <a href="http://www.blogjava.net/sean/archive/2007/04/14/110640.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>刚才见面，就说再见: 小记Subversion试用心得</title><link>http://www.blogjava.net/sean/archive/2007/03/14/103899.html</link><dc:creator>大胃</dc:creator><author>大胃</author><pubDate>Wed, 14 Mar 2007 15:07:00 GMT</pubDate><guid>http://www.blogjava.net/sean/archive/2007/03/14/103899.html</guid><wfw:comment>http://www.blogjava.net/sean/comments/103899.html</wfw:comment><comments>http://www.blogjava.net/sean/archive/2007/03/14/103899.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sean/comments/commentRss/103899.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sean/services/trackbacks/103899.html</trackback:ping><description><![CDATA[<br />
由于工作需要，最近在Linux服务器上试用Subversion，如果一切顺利，全公司的文档都将交给Subversion管理。我承认我对Subversion一直存在偏见，但为了给大家一个交代，还是硬着头皮小试了一下。结果运行数天以后，终于还是回到了CVS的老路上。<br />
<br />
Subversion的优点就不在这里重复了，网上很多介绍文章，也有很多忠实粉丝，不过没办法，我还是更喜欢CVS的简单和直接。熟悉Unix和类Unix系统的朋友一定有同感，CVS更加符合Unix的思维和解决问题的方式。<br />
让我们最终放弃Subversion主要有以下大大小小的原因：<br />
1- 一个新建的几乎是空的资源库，打包后大小即有39MB上下; << 经核实错怪SVN了，实测完全空白的资源库124K，向大家道歉！<br />
2- 资源库几乎是以一种完全不透明的方式存储用户资源库文件;<br />
3- 没有一个官方的、安全可靠的方式彻底删除一个误提交的文件，一旦提交上去，你的资源库将永远背着这个包袱; &lt;&lt; 这一条实在让我无法忍受。<br />
<br />
对于最后一条，官方说法是提供了一个svndumpfilter的方式，先把资源库dump出来，然后pipe到svndumpfilter过滤掉匹配的文件，最后再load回去。这几乎就是给我们判了死刑：dump文件动辄就会是好几个G，且随着时间增长，或者错误提交持续出现在超大型文件上，要完成这个dump和filter，以及周期性的备份，将要吃掉多少资源，不敢想象；svndumpfilter不支持wildcast，且这个字符串匹配由于是整个dump文件pipe到svndumpfilter，无法保证精确制导，尤其在生产环境，敏感文件被上传、有效文件被误删或者资源库遭到破坏的后果是很严重滴。<br />
<br /><br /><img src ="http://www.blogjava.net/sean/aggbug/103899.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sean/" target="_blank">大胃</a> 2007-03-14 23:07 <a href="http://www.blogjava.net/sean/archive/2007/03/14/103899.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> [阅读] Developer Testing Masters and Brain Surgeons</title><link>http://www.blogjava.net/sean/archive/2007/02/28/101118.html</link><dc:creator>大胃</dc:creator><author>大胃</author><pubDate>Wed, 28 Feb 2007 05:14:00 GMT</pubDate><guid>http://www.blogjava.net/sean/archive/2007/02/28/101118.html</guid><wfw:comment>http://www.blogjava.net/sean/comments/101118.html</wfw:comment><comments>http://www.blogjava.net/sean/archive/2007/02/28/101118.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sean/comments/commentRss/101118.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sean/services/trackbacks/101118.html</trackback:ping><description><![CDATA[<br/>
<a href="http://www.artima.com/forums/flat.jsp?forum=106&thread=196922" target="_blank">http://www.artima.com/forums/flat.jsp?forum=106&thread=196922</a><br/>
<br/>
Alberto Savoia在Artima上发表了一篇关于所谓Developer Testing Masters这个软件开发中的新角色的文章，把这个新的角色类比为脑外科医生。<br/>
<br/>
不知道大家在各自的项目中是如何处理QA和开发人员单元测试之间的平衡呢？是让QA提高自身的技术水平，越来越多的参与白盒测试，还是“逼”着开发工程师们做他们不情愿、通常也做不好的单元测试？这篇文章提供了另一种思路。<br/>
<br/>
<br/>
<img src ="http://www.blogjava.net/sean/aggbug/101118.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sean/" target="_blank">大胃</a> 2007-02-28 13:14 <a href="http://www.blogjava.net/sean/archive/2007/02/28/101118.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[链接] 承认错误、承认失败</title><link>http://www.blogjava.net/sean/archive/2007/02/18/100184.html</link><dc:creator>大胃</dc:creator><author>大胃</author><pubDate>Sun, 18 Feb 2007 10:35:00 GMT</pubDate><guid>http://www.blogjava.net/sean/archive/2007/02/18/100184.html</guid><wfw:comment>http://www.blogjava.net/sean/comments/100184.html</wfw:comment><comments>http://www.blogjava.net/sean/archive/2007/02/18/100184.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sean/comments/commentRss/100184.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sean/services/trackbacks/100184.html</trackback:ping><description><![CDATA[<br />
<a href="http://jroller.com/page/rolsen?entry=building_a_software_team_wrong" target="_blank">http://jroller.com/page/rolsen?entry=building_a_software_team_wrong</a><br />
<br />
关注这个Russ Olsen的blog有一段时间了，他最近的几篇blog贴子都和项目管理团队管理有关。我觉得相比成功的经验，有时失败带给我们的收获会更多。这篇最新的blog中Russ Olsen和我们分享关于他的一个失败的项目，以及他如何向团队承认自己的失误。<br />
<br />
当一个项目失败的时候，也许承认错误、承认失败是件尴尬的事，但作为项目负责人的PM，如果他的某个决定造成了整个团队的失败，就应该拿出勇气去承担。<br />
<br />
&quot;It goes against something in us, especially as we get into management jobs, to admit that we were wrong. But when you are wrong, especially when you are wrong in a way that causes the whole team to fail, you gotta own up. Not that 'mistakes were made'. Not that 'it could have been done better'. Not even 'I did the best I could'. No, it has to be 'I was wrong'.&quot;<br />
<br /><br />
<img src ="http://www.blogjava.net/sean/aggbug/100184.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sean/" target="_blank">大胃</a> 2007-02-18 18:35 <a href="http://www.blogjava.net/sean/archive/2007/02/18/100184.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[链接] 管理分布式软件团队</title><link>http://www.blogjava.net/sean/archive/2007/02/17/100134.html</link><dc:creator>大胃</dc:creator><author>大胃</author><pubDate>Sat, 17 Feb 2007 08:59:00 GMT</pubDate><guid>http://www.blogjava.net/sean/archive/2007/02/17/100134.html</guid><wfw:comment>http://www.blogjava.net/sean/comments/100134.html</wfw:comment><comments>http://www.blogjava.net/sean/archive/2007/02/17/100134.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sean/comments/commentRss/100134.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sean/services/trackbacks/100134.html</trackback:ping><description><![CDATA[<br />
<a href="http://www.extremeplanner.com/blog/2007/02/managing-distributed-software-teams.html" target="_blank">http://www.extremeplanner.com/blog/2007/02/managing-distributed-software-teams.html</a><br />
<br />
这篇blog文章讲的是如何管理分布式的软件开发团队。现如今许许多多的软件开发团队都面临跨办公室、跨楼层、甚至是跨地域、跨时区的协同合作开发，一个完整的团队被拆散成2个或者更多的小团队，如何管理好这样的&ldquo;分布式&rdquo;团队，值得我们思考。<br />
<br />
这篇blog的作者给我们开了个好头，他整理了如下几点：<br />
1- 让开发人员结对完成设计和编码，让组员保持沟通；<br />
2- 让项目的信息可以在线看到；<br />
3- 周期性的让组员面对面交流；<br />
4- 每天都开会，会议不必很正式很长，主要目的是让所有人都对项目现状、自己的工作和组员们遇到的困难有所了解；<br />
5- 使用多种沟通和交流的工具/平台，如电话、IM、blog、Wiki。<br />
<br />
我觉得尤为重要的是：<br />
1- 把项目信息放在一个方便的、大家都能看到的地方，并保持更新，这个可以通过Wiki来做，关键是需要专人维护，Wiki是死的人是活的，Wiki有多大价值完全在于维护它的人给它多少信息如何组织这些信息；<br />
2- 保持沟通的畅通，随时掌握团队其他人的现状和遇到的问题，也让他人掌握自己的进展和困难，这就体现出daily meeting的重要。<br />
<br /><br /><img src ="http://www.blogjava.net/sean/aggbug/100134.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sean/" target="_blank">大胃</a> 2007-02-17 16:59 <a href="http://www.blogjava.net/sean/archive/2007/02/17/100134.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[阅读] 丰田模式在新时代的挑战</title><link>http://www.blogjava.net/sean/archive/2007/02/16/100068.html</link><dc:creator>大胃</dc:creator><author>大胃</author><pubDate>Fri, 16 Feb 2007 09:39:00 GMT</pubDate><guid>http://www.blogjava.net/sean/archive/2007/02/16/100068.html</guid><wfw:comment>http://www.blogjava.net/sean/comments/100068.html</wfw:comment><comments>http://www.blogjava.net/sean/archive/2007/02/16/100068.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sean/comments/commentRss/100068.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sean/services/trackbacks/100068.html</trackback:ping><description><![CDATA[<br />
<a href="http://www.nytimes.com/2007/02/15/business/worldbusiness/15toyota.html" target="_blank">http://www.nytimes.com/2007/02/15/business/worldbusiness/15toyota.html</a><br />
<br />
来自纽约时报的文章: &quot;The &lsquo;Toyota Way&rsquo; Is Translated for a New Generation of Foreign Managers&quot;。在丰田全球扩张的过程中，在全球各地都建立了分支机构和生产工厂，雇佣了大量当地的工人和管理人员，如何将丰田多年积累的所谓&ldquo;丰田模式&rdquo;贯彻到所有海外工厂的日常管理，成为了一项颇具挑战的工作。<br />
<br />
丰田模式，如果我的理解没有错，其最核心最基本的概念是&ldquo;集体思考&rdquo;，强调可视性和持续改进。展开来说，比较有趣的几点：<br />
1- 问题是大家共同的，有问题大家一起解决。<br />
2- 在出现问题的现场解决问题而不是在办公桌。<br />
3- 任何人都可以指手画脚，发现质量问题，工人有权直接停掉生产线。<br />
4- 持续发现问题并解决。<br />
5- 建立共识。<br />
6- 对人，尤其是一线工人的尊重。<br />
7- 危机意识。<br />
<br />
&ldquo;丰田模式&rdquo;有很多概念来自日本本土文化，并不能简单的复制。如今很多生产企业已经在活学活用丰田模式，把适用的部分应用到日常的开发工作中。那么对于软件开发的企业和团队，有什么可以借鉴的经验？<br />
<br />
对于一个团队的软件产品或者项目组产出的代码/文档等提交件，首先是共同拥有，功劳是大家的，出现的问题也是大家的；其次是大家需要一个很方便很直接的途径看到团队的目标和当前的问题；对于发现的问题，团队任何人都有权指手画脚，甚至叫停整个开发来解决这些问题。<br />
<br />
只有共同拥有和担当，才能最大化团队所有人的责任感和成就感；只有大家都清楚的看到共同的目标，看到需要面对的困难和问题，才能有目的的工作；当有人发现团队出现问题，遇到困难，必须有一个合理的途径报告和解决。并且一个团队应该有这种鼓励和包容&ldquo;指手画脚&rdquo;的文化，鼓励大家发现问题，持续改进。<br />
<br />
这里面可能最难被接受的一点就是任何人都可以对发现的问题指手画脚并不惜停掉整个开发。这一开始看上去有些过激，但是细想起来则很有深意：叫停的权力带来的最直接的好处是最终产品和提交件的质量，可能有不少人认为软件质量并没有那么严重，或者觉得为了一点点质量问题影响整个进度不值得，但是叫停的权力的真正威力来自它隐含的东西。当所有人都明白质量的重要性，也都明白一旦停产，带来的严重后果就是整个进度的delay，整个团队的效率和产出都会受到牵连，大家就会很小心的遵守开发的规范，大家对待自己的产出也更加有责任感，让&ldquo;坏分子&rdquo;和&ldquo;懒惰&rdquo;无处容身。一旦叫停的权力成为团队文化的一部分，团队也就自然而然走上了持续改进的道路。<br />
<br/>
<br/><img src ="http://www.blogjava.net/sean/aggbug/100068.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sean/" target="_blank">大胃</a> 2007-02-16 17:39 <a href="http://www.blogjava.net/sean/archive/2007/02/16/100068.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[闲侃DRY] Don't Repeat Others</title><link>http://www.blogjava.net/sean/archive/2007/01/30/96806.html</link><dc:creator>大胃</dc:creator><author>大胃</author><pubDate>Tue, 30 Jan 2007 15:09:00 GMT</pubDate><guid>http://www.blogjava.net/sean/archive/2007/01/30/96806.html</guid><wfw:comment>http://www.blogjava.net/sean/comments/96806.html</wfw:comment><comments>http://www.blogjava.net/sean/archive/2007/01/30/96806.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sean/comments/commentRss/96806.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sean/services/trackbacks/96806.html</trackback:ping><description><![CDATA[<br/>
<a href="http://www.alittlemadness.com/?p=76" target="_blank">http://www.alittlemadness.com/?p=76</a><br/>
<br/>
今天读到这篇文章，原来和<a href="http://www.blogjava.net/sean/archive/2007/01/22/95424.html" target="_blank">我想的</a><a href="http://www.blogjava.net/sean/archive/2007/01/26/96071.html" target="_blank">一样</a>，不过DRO这个提法的提法比我提炼的要更好，呵呵。<br/>
<br/>
<br/>
<img src ="http://www.blogjava.net/sean/aggbug/96806.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sean/" target="_blank">大胃</a> 2007-01-30 23:09 <a href="http://www.blogjava.net/sean/archive/2007/01/30/96806.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[闲侃DRY] 自制框架 vs. 开源框架</title><link>http://www.blogjava.net/sean/archive/2007/01/26/96071.html</link><dc:creator>大胃</dc:creator><author>大胃</author><pubDate>Thu, 25 Jan 2007 16:32:00 GMT</pubDate><guid>http://www.blogjava.net/sean/archive/2007/01/26/96071.html</guid><wfw:comment>http://www.blogjava.net/sean/comments/96071.html</wfw:comment><comments>http://www.blogjava.net/sean/archive/2007/01/26/96071.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sean/comments/commentRss/96071.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sean/services/trackbacks/96071.html</trackback:ping><description><![CDATA[<br/>
<p>接着<a href="http://www.blogjava.net/sean/archive/2007/01/22/95424.html" target="_blank">上一篇</a>的思路聊。既然我们可以把开发者社群看作一个整体，copy-paste别人的blog文章就是在违背DRY的精神，其实所谓"重造轮子"道理也是一样，既然别人都已经做了相同的事情，并且把它开源了，并且你看了它的代码以后，觉得做得不错，为什么还要自己费心去实现同样的功能呢？自己来实现能给你带来什么好处呢？</p>
<p>我可以列举一些我认为可能会让我们选择自己来做的理由:</p>
<p>
<ol>
<li>我比其他人更了解我们自己的需求。</li>
<li>自己实现起来更容易，代码量更小，也更好用。</li>
<li>我是做技术的，能够DIY，就DIY，这样更能体现我的价值。</li>
</ol>
</p>
<p>这些理由有它的道理，但是我们有必要仔细掂量掂量:</p>
<p>
<ol>
<li>我比其他人更了解我们自己的需求。这是软件开发中很常见的一个误区，客户的需求难以把握，随着时间的推移，我们自己的技术层面的需求实际上也在不断变化，开源的框架往往经历了更多的考虑和验证，并且有一群热心的维护者帮你做bug-fix和升级，甚至我们自己就可以成为这群热心人中的一员。</li>
<li>自己实现起来更容易，代码量更小，也更好用。一开始确实是这样的，开源的框架为了满足不同的需要，往往需要比我们自己写代码要更加复杂和冗余，但是自制框架意味着我们自己定义的接口规范，这个接口规范能不能够在整个项目周期保持稳定暂且不谈，就算接口实现的再简单，项目中其他人也需要时间去理解和消化，然后记住一个定义好的调用方式，今后新加入的工程师也需要学习这个接口规范。开源框架则做得更好，一方面在这个项目中积累和学习到的知识，可以直接用在其他采用同一框架的项目中，另一方面新加入的人如果有过该开源框架的开发经验，上手时间可以缩短。</li>
<li>我是做技术的，能够DIY，就DIY，这样更能体现我的价值。我必须承认，我本人就亲身经历过这样的情况。在即将结束的这个项目中，我甚至自己DIY了一个简易的.NET报表引擎，为的是甩开Crystal Reports。一开始能够DIY报表引擎的想法让我兴奋得睡不着觉，最终前后花了3天很满意的完成了设计和开发，并交付报表开发人员重画报表。可是真正用了一段时间之后，基本的需求满足了，基本的可扩展性也具备，但是缺少可视化设计器、更灵活的公式、更丰富的报表元素，基本上就定型了，没有人有时间和精力再去维护它。</li>
</ol>
</p>
<p>在很多开发团队，大家经常碰在一起讨论具体的技术和设计，这很有必要，有时也不可避免。但是也许Joel Spolsky说的对，软件设计很难，但是比设计软件更难的，是同整个team一起设计软件。做技术的，对于自己了解、掌握、做过、尝试过的东西，对于自己熟悉和信任的东西，多多少少有些偏袒，而对于新的、自己不了解、不熟悉的东西，则难免心存疑虑。这就难怪很多设计讨论会最终很难达成一致。这个时候，要么由技术上的最高权威直接拍板，定下来是什么就是什么，要么就分歧双方或多方各自陈述，然后由项目外部的实体进行独立仲裁。</p>
<p>我看好开源框架，尤其是那些经过考验广泛被采用的框架，因为相比自制框架，它们有着更大的优势。</p>
<br/>
<img src ="http://www.blogjava.net/sean/aggbug/96071.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sean/" target="_blank">大胃</a> 2007-01-26 00:32 <a href="http://www.blogjava.net/sean/archive/2007/01/26/96071.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[闲侃DRY] 开篇</title><link>http://www.blogjava.net/sean/archive/2007/01/22/95424.html</link><dc:creator>大胃</dc:creator><author>大胃</author><pubDate>Mon, 22 Jan 2007 15:22:00 GMT</pubDate><guid>http://www.blogjava.net/sean/archive/2007/01/22/95424.html</guid><wfw:comment>http://www.blogjava.net/sean/comments/95424.html</wfw:comment><comments>http://www.blogjava.net/sean/archive/2007/01/22/95424.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/sean/comments/commentRss/95424.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sean/services/trackbacks/95424.html</trackback:ping><description><![CDATA[<br/>
DRY为何物？DRY是Don't Repeat Yourself的缩写，不要重复自己，这是一项软件开发中的重要原则，或者至少是一个很好的习惯。同样的数据、逻辑，我们应该尽量避免在代码、配置文件、数据库中重复，如果实在没有其他更好的办法，也应该尽可能不要手写这些重复的内容。<br/>
<br/>
既然是闲侃，我想就没必要那么一本正经，索性天马行空一把，想到哪儿写到哪儿吧。<br/>
<br/>
一直不习惯用桌面版RSS阅读器，最近又从Newsgator回到了熟悉的Bloglines，由于工作忙，经过几周的积累，Keep New的条目数超过500。唉，又欠下一堆的阅读债。几经删减，订阅的RSS Feed源还是有80个之多。<br/>
<br/>
一直在犹豫要不要取消BlogJava的综合区RSS订阅，一方面舍不得，毕竟自己在BlogJava安家，怎么说也得捧一下场，而我也需要持续了解这个圈子的人眼下都在做些什么想些什么；另一方面，实在有些难以忍受无数不做删减，原封不动照搬照抄其他网站内容的blog文章，其中不少我早已从其他渠道看到过，或者没什么特别的内容，整段整段的代码，这样的文章看了就是一句话，头痛。<br/>
<br/>
当然了，别人怎么写blog，我无权干涉，但是我是不是可以在这里呼吁一下，引用其他网站内容，能不能不要整篇照贴，要么给个链接，让大家自己去看，要么适当的引用你认为最有价值的段落或句子，或者适当给出自己的见解和评论？否则很难让别人相信你的诚意和动机，这是对原文作者、你的读者、以及你自己起码的尊重。<br/>
<br/>
换个角度来看问题，如果我们把软件开发社区看作一个整体，而我们就是这个整体中的一员，那么原封不动的拷贝粘贴这个整体中另外一个个体的文章内容，又何尝不是在广义上与DRY背道而驰？既然互联网给我们大家提供了分享信息的便利，为什么我们自己不懂得去维护这个本该服务于我们自己的环境呢？<br/>
<br/>
<br/>


<img src ="http://www.blogjava.net/sean/aggbug/95424.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sean/" target="_blank">大胃</a> 2007-01-22 23:22 <a href="http://www.blogjava.net/sean/archive/2007/01/22/95424.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>好奇心、求知欲、追求完美、解决实际问题 - IT人必要的职业素养</title><link>http://www.blogjava.net/sean/archive/2006/12/26/90186.html</link><dc:creator>大胃</dc:creator><author>大胃</author><pubDate>Tue, 26 Dec 2006 15:39:00 GMT</pubDate><guid>http://www.blogjava.net/sean/archive/2006/12/26/90186.html</guid><wfw:comment>http://www.blogjava.net/sean/comments/90186.html</wfw:comment><comments>http://www.blogjava.net/sean/archive/2006/12/26/90186.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sean/comments/commentRss/90186.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sean/services/trackbacks/90186.html</trackback:ping><description><![CDATA[
		<br />让我提醒一下各位准备进入IT行业，或者在IT行业但是还没有真正融入的朋友，IT这个领域，不管你做什么，都很有挑战，需要你的热情和勇气，这里没有金饭碗、铁饭碗，如果你入这行纯粹为了更轻松的工作或者更高的收入，我只能说我个人极其不看好你的这个动机。没有合适的心态和必要的职业素养，你很难成功或者满足。<br /><br />首先需要好奇心，从计算机如何工作，到某个软件系统或框架是如何实现的，到具体业务领域为什么会有某项特定的需求，都需要我们的好奇心，没有好奇心，就没有兴趣，没有兴趣，做出来的东西就必然缺少灵魂。如果你连基本的好奇心都没有了，我劝你还是早点关注一下其他更能够引起你好奇和感兴趣的行业，否则要么你很失败，要么会做得很辛苦。<br /><br />有了好奇心，接下来一定要有强烈的求知欲望，要有知甚解的精神。IT业是一个瞬息万变的行业，当下如日中天的技术，到了明天、下周、下个月、明年，可能就回无人问津，对于和你的知识面，和你的公司所涉猎的行业相关的技术知识、领域知识需要我们不断学习，不断充实自己，这个环节很难有什么捷径，如果有，也是通过一定的广度和深度来逐步达到举一反三的目的。曾经接触过不少“不求甚解”的朋友，表面上他们能够应付相当的工作和压力，但是很难让他们理解和掌握更深层次的东西。如果你观察他们足够长的时间，你会发现他们为了掌握不断变化或者不断发展的技术、框架、平台，或者适应某些看似极度不稳定的用户需求，由于没找到谱，其实也很累。<br /><br />有了必要的好奇心，也有足够的动力去学习新事物之后，我们需要有追求完美的工作态度。拿软件开发来说，我们产出的是软件，从某种意义上讲，是我们的孩子，应该给予足够的关爱和呵护，谁不希望自己的孩子是天下最棒的？说到底软件这个东西从无到有，灵活性相当大，能够做到怎样优秀的程度，很多时候取决于我们自己。<br /><br />最后是解决实际问题。追求完美没有错，但是需要有个度，需要有的放矢，需要有一个更加全局的指导方针，那就是解决实际问题。不论你做的东西采用多么先进的技术，你用了多么业界认可的管理方法，假如最后一些基本的客户需求无法达成，也是白搭。这是典型的“学院派”作风，我们在不断追求完美的同时，时刻都不能忘记我们存在的目的：解决实际问题。<br /><br /><br /><br /><img src ="http://www.blogjava.net/sean/aggbug/90186.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sean/" target="_blank">大胃</a> 2006-12-26 23:39 <a href="http://www.blogjava.net/sean/archive/2006/12/26/90186.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[阅读] Agile Methods as a Replacement for Fossil Fuels</title><link>http://www.blogjava.net/sean/archive/2006/12/23/89645.html</link><dc:creator>大胃</dc:creator><author>大胃</author><pubDate>Sat, 23 Dec 2006 03:33:00 GMT</pubDate><guid>http://www.blogjava.net/sean/archive/2006/12/23/89645.html</guid><wfw:comment>http://www.blogjava.net/sean/comments/89645.html</wfw:comment><comments>http://www.blogjava.net/sean/archive/2006/12/23/89645.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sean/comments/commentRss/89645.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sean/services/trackbacks/89645.html</trackback:ping><description><![CDATA[
		<br />
		<a target="_blank" title="http://leadinganswers.typepad.com/leading_answers/2006/11/agile_methods_a.html" href="http://leadinganswers.typepad.com/leading_answers/2006/11/agile_methods_a.html">http://leadinganswers.typepad.com/leading_answers/2006/11/agile_methods_a.html</a>
		<br />
		<br />关于如何使用敏捷方法管理知识型员工和团队，推荐阅读。其中两幅插图很形象的表示出：<br /><br />Command-and-Control的管理模式如何压制团队和个人的创造力、贡献的热情和生产效率，而适当的敏捷方法和实践如何推动和提高团队及个人的创造力、贡献的热情和生产效率。<br /><br />一个典型的Command-and-Control模式的特征：<br />- One way communications<br />- Lack of local control<br />- Compliance activities<br />- Bureaucracy<br />- Lack of recognition<br /><br />一个典型的敏捷管理模式的特征：<br />- Self organizing team<br />- Empowered to make decisions<br />- Focus on business value<br />- No blame culture<br />- Team recognition + development<br /><br /><br /><img src ="http://www.blogjava.net/sean/aggbug/89645.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sean/" target="_blank">大胃</a> 2006-12-23 11:33 <a href="http://www.blogjava.net/sean/archive/2006/12/23/89645.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[阅读] Technical Debt: the Threshold of Acceptable Pain</title><link>http://www.blogjava.net/sean/archive/2006/12/23/89639.html</link><dc:creator>大胃</dc:creator><author>大胃</author><pubDate>Sat, 23 Dec 2006 02:40:00 GMT</pubDate><guid>http://www.blogjava.net/sean/archive/2006/12/23/89639.html</guid><wfw:comment>http://www.blogjava.net/sean/comments/89639.html</wfw:comment><comments>http://www.blogjava.net/sean/archive/2006/12/23/89639.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sean/comments/commentRss/89639.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sean/services/trackbacks/89639.html</trackback:ping><description><![CDATA[
		<br />看到一篇好文，和大家共享之：<br /><a target="_blank" title="http://blog.technoetic.com/2006/09/19/threshold-of-pain/" href="http://blog.technoetic.com/2006/09/19/threshold-of-pain/">http://blog.technoetic.com/2006/09/19/threshold-of-pain/</a><br /><br />大意是探讨为什么有些team的“技术债”（我们在IT项目进展中犯下的哪怕是小小的一点错误或者不作为，都会影响到整个项目产出的质量，影响到该目未来的发展、维护，甚至验收，使得成本和预算无法被有效管理）会慢慢堆积，而另一些team能够及时发现并纠正这些潜在的问题。是team的技能水平吗？并不完全是。我们可以从不同team对pain（项目进展和产出上出现的瑕疵）的敏感程度的不同来考量，而非简单的技能差异。<br /><br />对pain的容忍度过高，项目中的“技术债”就会日益堆积，到最后项目变得无法收拾；对pain的容忍度过低，会让项目组变得吹毛求疵，得不偿失。当然，这个容忍度不可能也没必要定死在一个固定值上。有时候，我们也不得不临时调高这个容忍度，比如为了赶进度（如果错过某个deadline整个项目都可能会变得一文不值或者失去意义那种进度），问题的关键是，当我们有意识的提高宽容度，达到我们某个目标之后，能不能及时回过头来弥补这部分缺失的产出，避免今后带来更大的问题。今天你看来需要2周时间，你觉得不值，2周之后，同样这些欠下的“技术债”可能会“吃掉”你2个月，这不是在危言耸听。<br /><br />如何找到一个平衡点？如何根据项目实际情况调整这个平衡点的位置？这是摆在每个项目管理者面前的现实问题，也是项目管理者的责任和义务。<br /><br /><br /><img src ="http://www.blogjava.net/sean/aggbug/89639.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sean/" target="_blank">大胃</a> 2006-12-23 10:40 <a href="http://www.blogjava.net/sean/archive/2006/12/23/89639.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[Tips] 在Ubuntu Linux 6.06 LTS (Dapper Drake)上安装CVS服务</title><link>http://www.blogjava.net/sean/archive/2006/09/17/70145.html</link><dc:creator>大胃</dc:creator><author>大胃</author><pubDate>Sun, 17 Sep 2006 09:10:00 GMT</pubDate><guid>http://www.blogjava.net/sean/archive/2006/09/17/70145.html</guid><wfw:comment>http://www.blogjava.net/sean/comments/70145.html</wfw:comment><comments>http://www.blogjava.net/sean/archive/2006/09/17/70145.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.blogjava.net/sean/comments/commentRss/70145.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sean/services/trackbacks/70145.html</trackback:ping><description><![CDATA[
		<br />之前项目一直使用Win32环境的CVSNT做源代码版本管理，终于有一天受不了Windows下面跑CVS的性能（一方面CVS很慢，另一方面做CVS服务器的机子也被拖累了），下定决心把CVS搬到Linux环境下。<br /><br />以下简单记录一下在Dapper Drake上安装和配置CVS的步骤，供大家参考（由于服务器在内网，无法使用Debian系统下方便而强大的apt-get，只能手动下载了）：<br /><br />1- 下载和Dapper Drake匹配的CVS版本cvs_1.12.9-17_i386.deb，建议从国内比较快的ubuntu.cn99.com的源上拿，路径是/pool/main/c/cvs/cvs_1.12.9-17_i386.deb；<br /><br />2- 下载xinetd包，同上/pool/main/x/xinetd/xinetd_2.3.14-0ubuntu1_i386.deb；<br /><br />3- sudo -s转成root；<br /><br />4- dpkg -i cvs_1.12.9-17_i386.deb；<br /><br />5- dpkg -i xinetd_2.3.14-0ubuntu1_i386.deb；<br /><br />6- 为你的CVS资源库选择一个目录，比如mkdir /MyCVS；<br /><br />7- cvs -d /MyCVS init 初始化该CVS资源库；<br /><br />8- vi /etc/xinetd.d/cvspserver，添加<br />service cvspserver<br />{<br />     port = 2401<br />     socket_type = stream<br />     protocol = tcp<br />     user = root<br />     wait = no<br />     type = UNLISTED<br />     server = /usr/bin/cvs<br />     server_args = -f --allow-root /MyCVS pserver<br />     disable = no<br />}<br /><br />9- /etc/init.d/xinetd start；<br /><br />10- 开始配置CVS用户，最简单的方式就是采用Linux自己的用户/文件系统权限管理机制，我的做法是添加一个专门的用户组dev，然后往里面加用户，最后修改CVS资源目录的权限：<br /># addgroup dev<br /># adduser username<br /># adduser username dev<br /># chown -R username:dev /MyCVS<br /># chmod -R 775 /MyCVS<br />暂时用775，今后可以根据需要再细化每个文件/文件夹的细节权限；<br /><br />11- exit 退出sudo -s模式；<br /><br />12- 打开你熟悉的CVS客户端开始享用新的CVS服务器吧，相信它的性能相比较Win32下的CVSNT，一定会给你带来惊喜:D。<br /><br /><br /><img src ="http://www.blogjava.net/sean/aggbug/70145.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sean/" target="_blank">大胃</a> 2006-09-17 17:10 <a href="http://www.blogjava.net/sean/archive/2006/09/17/70145.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[阅读] 2010年IT职场趋势预测 - 业务领域知识比专业技术知识更重要</title><link>http://www.blogjava.net/sean/archive/2006/07/15/58304.html</link><dc:creator>大胃</dc:creator><author>大胃</author><pubDate>Sat, 15 Jul 2006 04:20:00 GMT</pubDate><guid>http://www.blogjava.net/sean/archive/2006/07/15/58304.html</guid><wfw:comment>http://www.blogjava.net/sean/comments/58304.html</wfw:comment><comments>http://www.blogjava.net/sean/archive/2006/07/15/58304.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/sean/comments/commentRss/58304.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sean/services/trackbacks/58304.html</trackback:ping><description><![CDATA[
		<br />For your leisure reading.<br /><br /><a title="http://www.computerworld.com/action/article.do?command=viewArticleTOC&amp;specialReportId=9000100&amp;articleId=112360" href="http://www.computerworld.com/action/article.do?command=viewArticleTOC&amp;specialReportId=9000100&amp;articleId=112360">http://www.computerworld.com/action/article.do?command=viewArticleTOC&amp;specialReportId=9000100&amp;articleId=112360</a><br /><a title="http://www.computerworld.com/action/article.do?command=viewArticleTOC&amp;specialReportId=9000100&amp;articleId=112368" href="http://www.computerworld.com/action/article.do?command=viewArticleTOC&amp;specialReportId=9000100&amp;articleId=112368">http://www.computerworld.com/action/article.do?command=viewArticleTOC&amp;specialReportId=9000100&amp;articleId=112368</a><br /><br /><br /><br /><img src ="http://www.blogjava.net/sean/aggbug/58304.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sean/" target="_blank">大胃</a> 2006-07-15 12:20 <a href="http://www.blogjava.net/sean/archive/2006/07/15/58304.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[Tips] Eclipse下CVS同步时"Add to .cvsignore..."弹出菜单项灰掉的真正原因</title><link>http://www.blogjava.net/sean/archive/2006/06/27/55292.html</link><dc:creator>大胃</dc:creator><author>大胃</author><pubDate>Tue, 27 Jun 2006 03:36:00 GMT</pubDate><guid>http://www.blogjava.net/sean/archive/2006/06/27/55292.html</guid><wfw:comment>http://www.blogjava.net/sean/comments/55292.html</wfw:comment><comments>http://www.blogjava.net/sean/archive/2006/06/27/55292.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/sean/comments/commentRss/55292.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sean/services/trackbacks/55292.html</trackback:ping><description><![CDATA[
		<br />开发过程中把Eclipse当作CVS客户端来用的时候，可能会遇到这样的情况：发现某些文件其实不需要CVS来管理，比如很多中间文件和可以通过其他源代码自动生成的东东，时间长了，一方面影响CVS性能，另一方面也是增加了同步时的额外工作，和真正需要上传的源代码混在一起，看上去很是不爽。这个时候你想起来可以把这些文件加入.cvsignore，但是这个时候无论你怎么弄，"Add to .cvsignore"菜单项总是灰掉的。<br /><br />为什么会这样呢？答案是这个"Add to .cvsignore"只能对还没有加入版本控制的文件起作用，所以对于那些已经加入的文件，这个菜单就被disable掉了。<br /><br />一个彻底但是相对野蛮的的解决办法是把项目从CVS断开，删掉所有的CVS目录，删掉CVS服务器上的这个项目的目录，在本地所有需要的地方新建.cvsignore文件（Windows用户注意，在Explorer中无法创建这样的文件，只能走命令行或者用编程的方式创建），和CVS目录一样，每个目录一个，打开.cvsignore文件以文本方式加入希望被CVS忽略的条目，如："*.exe"、"bin"等等。然后再和CVS同步，这个时候被忽略的条目（文件或者整个子目录）就不再出现在同步的文件列表中了。<br /><br /><br /><img src ="http://www.blogjava.net/sean/aggbug/55292.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sean/" target="_blank">大胃</a> 2006-06-27 11:36 <a href="http://www.blogjava.net/sean/archive/2006/06/27/55292.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[阅读] Are You Following the Instructions on the Paint Can?</title><link>http://www.blogjava.net/sean/archive/2006/04/23/42723.html</link><dc:creator>大胃</dc:creator><author>大胃</author><pubDate>Sun, 23 Apr 2006 13:53:00 GMT</pubDate><guid>http://www.blogjava.net/sean/archive/2006/04/23/42723.html</guid><wfw:comment>http://www.blogjava.net/sean/comments/42723.html</wfw:comment><comments>http://www.blogjava.net/sean/archive/2006/04/23/42723.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sean/comments/commentRss/42723.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sean/services/trackbacks/42723.html</trackback:ping><description><![CDATA[
		<br />
		<a href="http://www.codinghorror.com/blog/archives/000568.html">http://www.codinghorror.com/blog/archives/000568.html</a>
		<br />
		<a href="http://www.codinghorror.com/blog/archives/000283.html">http://www.codinghorror.com/blog/archives/000283.html</a>
		<br />
		<br />你会遵照油漆桶上的说明来涂漆吗？油漆桶上的说明，如果你仔细去看，会发现很多条目都是你觉得理所应当的，没什么了不起，甚至没有什么技术含量，但正是这些看似简单甚至"弱智"的使用说明保证了最终油漆涂出来的质量。转念想想现如今做软件何尝不是如此，管你技术再先进，个人的水平再高，如果忽略了好的习惯和基本的纪律，最终的结果未必好看。<br /><br /><img src ="http://www.blogjava.net/sean/aggbug/42723.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sean/" target="_blank">大胃</a> 2006-04-23 21:53 <a href="http://www.blogjava.net/sean/archive/2006/04/23/42723.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[VS2005起步]一些实用的工具和配置指南</title><link>http://www.blogjava.net/sean/archive/2006/04/01/38624.html</link><dc:creator>大胃</dc:creator><author>大胃</author><pubDate>Sat, 01 Apr 2006 09:04:00 GMT</pubDate><guid>http://www.blogjava.net/sean/archive/2006/04/01/38624.html</guid><wfw:comment>http://www.blogjava.net/sean/comments/38624.html</wfw:comment><comments>http://www.blogjava.net/sean/archive/2006/04/01/38624.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/sean/comments/commentRss/38624.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sean/services/trackbacks/38624.html</trackback:ping><description><![CDATA[
		<br />新的项目要求使用C#，对于习惯了Java开发模式和环境的朋友来说，一开始总会有些不适应。<br /><br />拿我自己的体验来说，VS2005跟Eclipse SDK相比，当然画GUI和调试的直观性方面给我留下的印象很深，不过也有些我认为缺少了的东西：增量编译（很多时候只有F6以后，编译错误提示才会消失，有些引用和IntelliSense才生效，不像Eclipse，保存后自动增量编译）、代码排版（很怀念Ctrl-Shift-F）、引用整理（很怀念Ctrl-Shift-O）、很多有用的重构（可以说VS里面代码级的重构相比很多Java IDE差远了）、单元测试的集成（NUnit理论上应该可以很好的集成到VS2005，不过还是花了我一些功夫）、CVS客户端（很怀念Eclipse SDK）。当然，一些IDE当中相对小的差异一开始也很难适应，不过这些也可以理解，属于正常范畴。<br /><br />最近为了把项目的一些基调和开发模式定下来，做了一些尝试，我想也许对大家还有些用，整理一下放在这里。<br /><br />一个好的.NET项目，我相信有些东西事先定义好，对项目整个过程是有很大好处的，这些东西至少应该包括：开发工具选择和配置、代码模板、单元测试、代码自动化review工具、自动编译和测试、缺陷跟踪、文档管理等。当然如果不计成本，那么有很多重量级的SDLC框架可以用，如VSTS(MSF)、Rational(RUP)和Borland的集成工具，以上这些环节的问题相应的框架也大都给出了很好的解决方案，但是毕竟不是所有的项目都会购买和采用那么"重"的方法和过程，很多时候就算有那个预算，对于特定的项目，实施起来也不见得就会收到好的效果。于是我们接触到的很多项目，其实都还是需要自己去寻找适合的工具来把整个周期串起来。以下是我在尝试找到一套合适方案时遇到的一些特定问题以及解决办法：<br /><br />首先是单元测试工具以及和IDE的集成。在Eclipse SDK中，我们不必太过关心这个问题，因为Eclipse已经很好的集成了JUnit。但是在.NET的世界，人们是怎么做的呢？答案是NUnit，一个跟JUnit非常类似的东西。和JUnit一样，NUnit也提供了命令行版本和GUI版本，但是VS里面并没有直接提供集成，你更多的时候需要从外部运行NUnit，当然这样很不爽啦。VS号称是自己也提供了单元测试工具，但是那仅仅在高端VSTS中才有。如何解决这个集成的问题呢？可以到<a href="http://www.testdriven.net/">http://www.testdriven.net/</a> 上下载一个TestDriven.NET的VS add-in。安装以后，就可以在VS中调用我们可能经常需要调用的NUnit来跑自己的单元测试了。<br /><br />其次是代码模板。一个项目，不管大小，总会涉及到相当数量的源代码文件，我们希望这些源代码都包括一些共有的东西和特定的注释，怎么办？在Eclipse里面有code template的概念，那么在VS里呢？答案是Project Template和Item Template。一开始我根本摸不着头脑，只看到MSDN上正在说Code Snippet，于是我实现的1.0版代码模板就是基于Code Snippet的，用起来很不方便，有关Code Snippet，我等下还会提到，这里先看Templates。我Google了一下相关的Project Template和Item Template的说明，基本都是VS 2003的，不过它们给了我很好的提示，至少可以知道VS在生成默认的代码时是怎样一个思路。所有的VS 2005代码模板都可以在%VS_2005_INSTALL_PATH%\Common7\IDE\ProjectTemplates和%VS_2005_INSTALL_PATH%\Common7\IDE\ItemTemplates目录下面找到，Project Template和Item Template不同的是Project Templates是在你新建一个项目时使用的模板，而Item Templates是在你往一个现有项目中添加item，如Form、Class等的时候使用。这里需要注意两点：一是VS 2005跟VS 2003不同，templates不再是直接的.cs文件等，而是打包在了.zip中，需要修改的话，需要把新的文件重新压到.zip中；二是除了template目录，还有一个TemplateCache目录，为了立即看到模板的效果，这里面的相应.cs文件等也需要修改。模板改起来相当直接，一看便知，比如新建Form的模板：<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: #0000ff">using</span><span style="COLOR: #000000"> System;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000"> System.Collections.Generic;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000"> System.ComponentModel;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000"> System.Data;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000"> System.Drawing;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000"> System.Text;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000"> System.Windows.Forms;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">namespace</span><span style="COLOR: #000000"> $rootnamespace$<br /><img id="Codehighlighter1_192_311_Open_Image" onclick="this.style.display='none'; Codehighlighter1_192_311_Open_Text.style.display='none'; Codehighlighter1_192_311_Closed_Image.style.display='inline'; Codehighlighter1_192_311_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_192_311_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_192_311_Closed_Text.style.display='none'; Codehighlighter1_192_311_Open_Image.style.display='inline'; Codehighlighter1_192_311_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_192_311_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_192_311_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> partial </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> $safeitemrootname$: Form<br /><img id="Codehighlighter1_242_309_Open_Image" onclick="this.style.display='none'; Codehighlighter1_242_309_Open_Text.style.display='none'; Codehighlighter1_242_309_Closed_Image.style.display='inline'; Codehighlighter1_242_309_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_242_309_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_242_309_Closed_Text.style.display='none'; Codehighlighter1_242_309_Open_Image.style.display='inline'; Codehighlighter1_242_309_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span><span id="Codehighlighter1_242_309_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_242_309_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> $safeitemrootname$()<br /><img id="Codehighlighter1_276_306_Open_Image" onclick="this.style.display='none'; Codehighlighter1_276_306_Open_Text.style.display='none'; Codehighlighter1_276_306_Closed_Image.style.display='inline'; Codehighlighter1_276_306_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_276_306_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_276_306_Closed_Text.style.display='none'; Codehighlighter1_276_306_Open_Image.style.display='inline'; Codehighlighter1_276_306_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />        </span><span id="Codehighlighter1_276_306_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_276_306_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />            InitializeComponent();<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />        }</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span></div><br /><br />接下来说说Code Snippet，这个东东被MSDN吹得有点大，不过用起来实在有些不顺手，你虽然可以定义一大块代码片断，然后填一些参数，就能得到一个定制的代码段，但是毕竟你还是需要自己写很多东西，然后使用的话需要在代码编辑器里面点很多下才出来，又没有很好的快捷方式。不客气地说我觉得用Code Snippet来模拟Eclipse的很多现成的重构功能实在不能够体现出优势。退一万步讲，有总比没有强，至少你还是可以做一些东西的。使用现成的Code Snippet很简单，只要把VS指向你存放Code Snippets的目录即可，新的Code Snippets会被自动扫描到。方法是：Tools -&gt; Code Snippets Manager或者Ctrl-K Ctrl-B然后添加目录名。所有的Code Snippets文件都以.snippet后缀结尾，其实内部是个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: 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: #0000ff">&lt;?</span><span style="COLOR: #ff00ff">xml version="1.0" encoding="utf-8" </span><span style="COLOR: #0000ff">?&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">CodeSnippets </span><span style="COLOR: #ff0000">xmlns</span><span style="COLOR: #0000ff">="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">CodeSnippet </span><span style="COLOR: #ff0000">Format</span><span style="COLOR: #0000ff">="1.0.0"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">Header</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />      </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">Title</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">Insert a simple set of getter and setter pair</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">Title</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />      </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">Author</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">Sean GAO</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">Author</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />      </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">Description</span><span style="COLOR: #0000ff">&gt;&lt;/</span><span style="COLOR: #800000">Description</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />      </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">Shortcut</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">simplisticGetterSetter</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">Shortcut</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />      </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">SnippetTypes</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">SnippetType</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">Expansion</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">SnippetType</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />      </span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">SnippetTypes</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">Header</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">Snippet</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />      </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">Declarations</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">Literal</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />          </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">ID</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">AccessLevel</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">ID</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />          </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">ToolTip</span><span style="COLOR: #0000ff">&gt;&lt;/</span><span style="COLOR: #800000">ToolTip</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />          </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">Default</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">public</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">Default</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">Literal</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">Literal</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />          </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">ID</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">PropertyType</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">ID</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />          </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">ToolTip</span><span style="COLOR: #0000ff">&gt;&lt;/</span><span style="COLOR: #800000">ToolTip</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />          </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">Default</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">string</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">Default</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">Literal</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">Literal</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />          </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">ID</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">PropertyName</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">ID</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />          </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">ToolTip</span><span style="COLOR: #0000ff">&gt;&lt;/</span><span style="COLOR: #800000">ToolTip</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />          </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">Default</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">name</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">Default</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">Literal</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">Literal</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />          </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">ID</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">LocalVarName</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">ID</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />          </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">ToolTip</span><span style="COLOR: #0000ff">&gt;&lt;/</span><span style="COLOR: #800000">ToolTip</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />          </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">Default</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">localVar</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">Default</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">Literal</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />      </span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">Declarations</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />      </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">Code </span><span style="COLOR: #ff0000">Language</span><span style="COLOR: #0000ff">="csharp"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">&lt;![CDATA[</span><span style="COLOR: #808080">        $AccessLevel$ $PropertyType$ $PropertyName$<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        {<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            get { return $LocalVarName$; }<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            set { $LocalVarName$ = value; }<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        }<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">]]&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />      </span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">Code</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">Snippet</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">CodeSnippet</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">CodeSnippets</span><span style="COLOR: #0000ff">&gt;</span></div><br />我们可以看到，首先在.snippet中我定义了一些变量，然后在&lt;Code/&gt;段加入了&lt;![CDATA[...]]&gt;，就这么简单。<br /><br />最后，还剩一些具体的工具，选择面比较广，我只列举一下我都选了哪些：<br />- 代码review和分析工具：FxCop，可以在GotDotNet网站上下载：<a href="http://www.gotdotnet.com/team/fxcop/">http://www.gotdotnet.com/team/fxcop/</a> 。<br />- 自动编译管理：NANT和CruiseControl.NET：<a href="http://nant.sourceforge.net/">http://nant.sourceforge.net/</a> 和 <a href="http://ccnet.thoughtworks.com/">http://ccnet.thoughtworks.com/</a> 。<br />- 缺陷跟踪：mantis：<a href="http://www.mantisbt.org/">http://www.mantisbt.org/</a> 。<br />- 文档管理： jLibrary：<a href="http://jlibrary.sourceforge.net/">http://jlibrary.sourceforge.net/</a> 。<br />- 版本控制：CVSNT和Eclipse SDK：<a href="http://www.cvsnt.org/">http://www.cvsnt.org/</a> 和 <a href="http://eclipse.org/">http://eclipse.org/</a> 。<br /><br />暂时就是这么多，如果你和我一样从Java转向.NET，然后正在犯愁如何做一个.NET项目的前期准备，希望能给你一些参考。<br /><br /><img src ="http://www.blogjava.net/sean/aggbug/38624.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sean/" target="_blank">大胃</a> 2006-04-01 17:04 <a href="http://www.blogjava.net/sean/archive/2006/04/01/38624.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[阅读]关于Offshore - 离岸外包的两篇好文</title><link>http://www.blogjava.net/sean/archive/2006/02/08/29960.html</link><dc:creator>大胃</dc:creator><author>大胃</author><pubDate>Wed, 08 Feb 2006 10:35:00 GMT</pubDate><guid>http://www.blogjava.net/sean/archive/2006/02/08/29960.html</guid><wfw:comment>http://www.blogjava.net/sean/comments/29960.html</wfw:comment><comments>http://www.blogjava.net/sean/archive/2006/02/08/29960.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sean/comments/commentRss/29960.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sean/services/trackbacks/29960.html</trackback:ping><description><![CDATA[<br>
"Why offshoring fails":<br>
<a href="http://management.itmanagersjournal.com/article.pl?sid=06/02/02/2135206">
http://management.itmanagersjournal.com/article.pl?sid=06/02/02/2135206</a><br>
<br>
"Five reasons why offshore deals go bust":<br>
<a href="" http://www.computerworld.com/managementtopics/outsourcing/story/0,10801,102677,00.html="">
http://www.computerworld.com/managementtopics/outsourcing/story/0,10801,102677,00.html</a><br>
<br>
<br><img src ="http://www.blogjava.net/sean/aggbug/29960.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sean/" target="_blank">大胃</a> 2006-02-08 18:35 <a href="http://www.blogjava.net/sean/archive/2006/02/08/29960.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java开发者～Java架构师：包办婚姻？</title><link>http://www.blogjava.net/sean/archive/2005/11/18/20391.html</link><dc:creator>大胃</dc:creator><author>大胃</author><pubDate>Fri, 18 Nov 2005 02:54:00 GMT</pubDate><guid>http://www.blogjava.net/sean/archive/2005/11/18/20391.html</guid><wfw:comment>http://www.blogjava.net/sean/comments/20391.html</wfw:comment><comments>http://www.blogjava.net/sean/archive/2005/11/18/20391.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/sean/comments/commentRss/20391.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sean/services/trackbacks/20391.html</trackback:ping><description><![CDATA[<br>
今天在JDJ上看到这个很有意思的文章：<br>
<a href="http://java.sys-con.com/read/152251.htm" target="_blank">http://java.sys-con.com/read/152251.htm</a><br>
<br>
大意是讲，在很多大的IT企业内部，经常能够看见一组独立的Java架构师，和另外很多个Java开发团队。架构师们往往忙于奔波在不同的项目，他们也有
自己的进度和任务要完成，有很多公用的模块要维护，很多新的框架或者模块要开发，他们开始怀疑自己作为架构师，到底应该做些什么；而开发者们往往被硬性规
定只能使用架构师组指定的方案和类库、框架，随着时间推移，这些原本的金科玉律开始不再光鲜，开发人员开始抱怨架构师组做的东西很不合理，而修改建议和请
求迟迟不能得到响应，时间长了很可能自己寻求其他途径，如开源的框架。但最终，这些都是团队内部矛盾，该怎么办还得怎么办，想撇开架构师组单干？没这个选
项。为什么会这样？这种情形是如何形成的？Java架构师和普通开发人员之间的工作关系经常是由他人指派，各自的工作内容和指标也都是来自不同的部门，而
不是出于双方自身的意愿。如果把上面这句话的“工作”换成“生活”，这不正像是包办婚姻么？<br>
<br>
我想，有很多Java的项目，当它做到一定规模的时候，自然而然就会产生出自定义框架和类库的想法，一开始，这种方法很有效，无论做框架的还是用框架的，
都很happy。但是时间长了，这样的模式就会带来各式各样的问题。这个时候，架构师和开发人员就需要坐下来，开诚布公的好好谈一谈，架构师要多多理解开
发人员的苦恼，因为毕竟他们的薪水来自项目预算，开发人员也需要多多理解架构师，也许是你没有把握好框架的正确使用，那个框架并非一无是处。还是把自己分
内该做的事情，做做好，毕竟，作为夫妻，作为一个家庭单元，有它的责任和义务，那就是养育出“孩子”，即产品或项目。就像夫妻吵架，吵归吵，但是第二天，
过去的不愉快，应该抛在脑后了。<br>
<br>
不知道各位所在的公司和项目有没有类似的情况出现，大家有有些什么好的办法去解决它所带来的麻烦呢？可以分享一下你的经验么？<br>
<br>
<br><img src ="http://www.blogjava.net/sean/aggbug/20391.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sean/" target="_blank">大胃</a> 2005-11-18 10:54 <a href="http://www.blogjava.net/sean/archive/2005/11/18/20391.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[PMO]简介</title><link>http://www.blogjava.net/sean/archive/2005/08/28/11346.html</link><dc:creator>大胃</dc:creator><author>大胃</author><pubDate>Sat, 27 Aug 2005 16:15:00 GMT</pubDate><guid>http://www.blogjava.net/sean/archive/2005/08/28/11346.html</guid><wfw:comment>http://www.blogjava.net/sean/comments/11346.html</wfw:comment><comments>http://www.blogjava.net/sean/archive/2005/08/28/11346.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/sean/comments/commentRss/11346.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sean/services/trackbacks/11346.html</trackback:ping><description><![CDATA[<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'"><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'">PMO</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Trebuchet MS'; mso-ascii-font-family: 'Trebuchet MS'">是什么？它可以是很多不同单词的组合，在这里，我要说的是</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'">Project Management Office</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Trebuchet MS'; mso-ascii-font-family: 'Trebuchet MS'">。请原谅我的孤陋寡闻，</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'">PMO</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Trebuchet MS'; mso-ascii-font-family: 'Trebuchet MS'">的概念其实在两年以前就已经是业界的</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'">buzzword</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Trebuchet MS'; mso-ascii-font-family: 'Trebuchet MS'">了，而我直到最近才因为工作的原因接触到这个概念。</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Trebuchet MS'; mso-ascii-font-family: 'Trebuchet MS'">在这篇随笔里面，让我们初步的探讨一下，为什么我们需要</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'">PMO</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Trebuchet MS'; mso-ascii-font-family: 'Trebuchet MS'">，或者说，</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'">PMO</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Trebuchet MS'; mso-ascii-font-family: 'Trebuchet MS'">应该具备怎样的职能呢？</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'">PMO</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Trebuchet MS'; mso-ascii-font-family: 'Trebuchet MS'">可以说是随着</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'">IT</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Trebuchet MS'; mso-ascii-font-family: 'Trebuchet MS'">产业的潮流应运而生的产物，最初的目的是节约成本，提高项目成功率，以及实施标准流程，以应对越来越多的项目管理任务。虽然它在节约成本和提升项目管理质量上目前还很难有一个可量化的指标，但是越来越多的公司和企事业单位在它们的</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'">IT</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Trebuchet MS'; mso-ascii-font-family: 'Trebuchet MS'">部门设立集中的</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'">PMO</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Trebuchet MS'; mso-ascii-font-family: 'Trebuchet MS'">，统管所有</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'">IT</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Trebuchet MS'; mso-ascii-font-family: 'Trebuchet MS'">项目。</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Trebuchet MS'; mso-ascii-font-family: 'Trebuchet MS'">按照比较公认的说法，</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'">PMO</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Trebuchet MS'; mso-ascii-font-family: 'Trebuchet MS'">的核心职能包括：</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'">1- </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Trebuchet MS'; mso-ascii-font-family: 'Trebuchet MS'">定义并推行可重用的项目管理流程；</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'">2- </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Trebuchet MS'; mso-ascii-font-family: 'Trebuchet MS'">集中控制项目进展和资源调配。</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Trebuchet MS'; mso-ascii-font-family: 'Trebuchet MS'">仔细想一想，也许我们有两种不同侧重点的</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'">PMO</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Trebuchet MS'; mso-ascii-font-family: 'Trebuchet MS'">：一种是顾问型的，为项目经理提供培训、指导和最佳实践；另一种是集中式管理型，将项目经理集中到</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'">PMO</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Trebuchet MS'; mso-ascii-font-family: 'Trebuchet MS'">，然后派往不同的项目，最终由</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'">PMO</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Trebuchet MS'; mso-ascii-font-family: 'Trebuchet MS'">统一控制所有项目和资源。</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Trebuchet MS'; mso-ascii-font-family: 'Trebuchet MS'">我相信国内很多公司应该是更倾向于后者，一方面，项目管理或者说软件工程本来就是一门艺术，很难有一个定式，就算有再多的“最佳实践”，根据项目具体情况的不同，也很难保证它们就一定适用，现实中要找到真正管理经验丰富，可以向别人提供理论指导的人才，并非那么容易；另一方面，后者能够更加直接的体现出</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'">PMO</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Trebuchet MS'; mso-ascii-font-family: 'Trebuchet MS'">存在的价值，不光是直接的具体的项目管理，也有利于确定不同项目的类型和轻重缓急，合理分配资源。</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Trebuchet MS'; mso-ascii-font-family: 'Trebuchet MS'">当然，如果一个</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'">PMO</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Trebuchet MS'; mso-ascii-font-family: 'Trebuchet MS'">最终做成一个完全意义上的行政部门的话，它也不应该同公司的企业文化相冲突，它起到的作用也应该更多的体现在如何去将项目的失败和公司的亏损减到最低限度，如何提高公司的项目管理水平，而不是一味的、机械的通过所谓的“标准流程”处理项目的实际问题，或者仅仅是一个跟踪项目进度，通常以一种管理者的姿态去命令各个项目组的部门。它应该同公司的各个相关部门：如</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'">CIO</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Trebuchet MS'; mso-ascii-font-family: 'Trebuchet MS'">、</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'">CAO</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Trebuchet MS'; mso-ascii-font-family: 'Trebuchet MS'">和</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'">QAO</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Trebuchet MS'; mso-ascii-font-family: 'Trebuchet MS'">，以及具体的项目组、公司财务和高层管理部门共同协作，促进公司各个项目的顺利实施。</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Trebuchet MS'; mso-ascii-font-family: 'Trebuchet MS'">一个比较常见的、直观的说法是，</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'">PMO</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Trebuchet MS'; mso-ascii-font-family: 'Trebuchet MS'">需要保证所有其属下的</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'">PM</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Trebuchet MS'; mso-ascii-font-family: 'Trebuchet MS'">具备管理当前项目的能力。而从长远来看，最理想的</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'">PMO</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Trebuchet MS'; mso-ascii-font-family: 'Trebuchet MS'">能够给公司的</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'">IT</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Trebuchet MS'; mso-ascii-font-family: 'Trebuchet MS'">部门带来持续不断的业绩提升。</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Trebuchet MS'; mso-ascii-font-family: 'Trebuchet MS'">先说到这，关于本话题，今后也许会有更多后续文章。同时欢迎大家参与讨论！</SPAN><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US style="FONT-FAMILY: 'Trebuchet MS'"><o:p>&nbsp;</o:p></SPAN></P><img src ="http://www.blogjava.net/sean/aggbug/11346.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sean/" target="_blank">大胃</a> 2005-08-28 00:15 <a href="http://www.blogjava.net/sean/archive/2005/08/28/11346.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>你真的认真考虑过周期性的构建工作的对于项目成功重要性吗？</title><link>http://www.blogjava.net/sean/archive/2005/03/30/2610.html</link><dc:creator>大胃</dc:creator><author>大胃</author><pubDate>Wed, 30 Mar 2005 07:16:00 GMT</pubDate><guid>http://www.blogjava.net/sean/archive/2005/03/30/2610.html</guid><wfw:comment>http://www.blogjava.net/sean/comments/2610.html</wfw:comment><comments>http://www.blogjava.net/sean/archive/2005/03/30/2610.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sean/comments/commentRss/2610.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sean/services/trackbacks/2610.html</trackback:ping><description><![CDATA[

<p class="MsoNormal" style="margin: 6pt 0cm;"><span style="font-family: &quot;Trebuchet MS&quot;;" lang="EN-US"><o:p>&nbsp;</o:p></span></p>


<p class="MsoNormal" style="margin: 6pt 0cm;"><span style="font-family: 宋体;">今天偶然在</span><span style="font-family: &quot;Trebuchet MS&quot;;" lang="EN-US">TheServerSide.com</span><span style="font-family: 宋体;">上发现一篇挺有意思的文章，大意是讲在软件开发项目中类似日构建这样的工作为什么重要，通过它我们要达到的目的是什么。虽然文章的背景是讲一个叫做</span><span style="font-family: &quot;Trebuchet MS&quot;;" lang="EN-US">BuildMonkey</span><span style="font-family: 宋体;">的东东，但是很大的篇幅实在是我们日常很容易忽略的问题。如果你在公司做项目经理或者负责配置管理，建议你看一看这篇文章，说不定会有启发。</span><span style="font-family: &quot;Trebuchet MS&quot;;" lang="EN-US"><o:p></o:p></span></p>


<p class="MsoNormal" style="margin: 6pt 0cm;"><span style="font-family: &quot;Trebuchet MS&quot;;" lang="EN-US"><o:p>&nbsp;</o:p></span></p>


<p class="MsoNormal" style="margin: 6pt 0cm;"><span style="font-family: 宋体;">原文见：</span><span style="font-family: &quot;Trebuchet MS&quot;;" lang="EN-US"><o:p></o:p></span></p>


<p class="MsoNormal" style="margin: 6pt 0cm;"><span style="font-family: &quot;Trebuchet MS&quot;;" lang="EN-US"><a href="http://www.theserverside.com/articles/article.tss?l=BuildManagement">http://www.theserverside.com/articles/article.tss?l=BuildManagement</a>
<o:p></o:p></span></p>


<p class="MsoNormal" style="margin: 6pt 0cm;"><span style="font-family: &quot;Trebuchet MS&quot;;" lang="EN-US"><o:p>&nbsp;</o:p></span></p>

<img src ="http://www.blogjava.net/sean/aggbug/2610.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sean/" target="_blank">大胃</a> 2005-03-30 15:16 <a href="http://www.blogjava.net/sean/archive/2005/03/30/2610.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>不同的J2EE项目开发流程</title><link>http://www.blogjava.net/sean/archive/2005/01/16/365.html</link><dc:creator>大胃</dc:creator><author>大胃</author><pubDate>Sun, 16 Jan 2005 15:18:00 GMT</pubDate><guid>http://www.blogjava.net/sean/archive/2005/01/16/365.html</guid><wfw:comment>http://www.blogjava.net/sean/comments/365.html</wfw:comment><comments>http://www.blogjava.net/sean/archive/2005/01/16/365.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sean/comments/commentRss/365.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sean/services/trackbacks/365.html</trackback:ping><description><![CDATA[<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Palatino Linotype'; mso-hansi-font-family: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt"></span>&nbsp;</p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Palatino Linotype'; mso-hansi-font-family: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">一个典型的</span><span lang="EN" style="FONT-FAMILY: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">J2EE</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Palatino Linotype'; mso-hansi-font-family: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">项目通常应该使用哪一种开发流程呢？流行开发流程有很多种，应用比较广泛的有：瀑布式、迭代式、以及</span><span lang="EN" style="FONT-FAMILY: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">RUP (Rational Unified Process)</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Palatino Linotype'; mso-hansi-font-family: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">。每一种都有其优点和不足，所以通常我们应该把它们结合起来而不是认定其中一个然后</span><span lang="EN" style="FONT-FAMILY: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">100%</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Palatino Linotype'; mso-hansi-font-family: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">按着它的规范走。</span><span lang="EN" style="FONT-FAMILY: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt"><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN" style="FONT-FAMILY: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Palatino Linotype'; mso-hansi-font-family: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">首先来看看每一种大致是什么意思：</span><span lang="EN" style="FONT-FAMILY: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt"><o:p></o:p></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN" style="FONT-FAMILY: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><b style="mso-bidi-font-weight: normal"><span lang="EN" style="FONT-FAMILY: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">[</span></b><b style="mso-bidi-font-weight: normal"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Palatino Linotype'; mso-hansi-font-family: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">瀑布式</span></b><b style="mso-bidi-font-weight: normal"><span lang="EN" style="FONT-FAMILY: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">]<o:p></o:p></span></b></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Palatino Linotype'; mso-hansi-font-family: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">这种模式的流程强调在开始编码和测试之前完成所有的需求分析和设计，这种模式历史相当久远，也很成熟，甚至到了今天，这种模式还是被广泛的采用到绝大多数公司和项目中。采用这种模式开发的项目通常很大，并且需要较长时间交付。正因为如此，这些项目通常会有更多的风险：在业务需求不断变化的今天，如果待开发的系统不能及时反应出这些需求的变化，最终开发出来的产品可能已经不是客户真正需要的了。</span><span lang="EN" style="FONT-FAMILY: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt"><o:p></o:p></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN" style="FONT-FAMILY: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><b style="mso-bidi-font-weight: normal"><span lang="EN" style="FONT-FAMILY: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">[</span></b><b style="mso-bidi-font-weight: normal"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Palatino Linotype'; mso-hansi-font-family: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">迭代式</span></b><b style="mso-bidi-font-weight: normal"><span lang="EN" style="FONT-FAMILY: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">]<o:p></o:p></span></b></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Palatino Linotype'; mso-hansi-font-family: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">为了应对传统瀑布式的开发在处理需求变更上的不足，近些年出现了一种全新的极限编程的概念。极限编程（</span><span lang="EN" style="FONT-FAMILY: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">XP</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Palatino Linotype'; mso-hansi-font-family: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">）的核心思想在于：从长远看，早期发现错误以及降低复杂度可以节约成本。极限编程强调我们将任务</span><span lang="EN" style="FONT-FAMILY: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">/</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Palatino Linotype'; mso-hansi-font-family: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">系统细分为可以在较短周期解决的一个个子任务</span><span lang="EN" style="FONT-FAMILY: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">/</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Palatino Linotype'; mso-hansi-font-family: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">模块，并且强调测试、代码质量和及早发现问题。通常，通过一个个短小的迭代周期，我们就可以获得一个个阶段性的进展，并且可以及时形成一个版本供用户参考，以便及时对用户可能的需求变更作出响应。</span><span lang="EN" style="FONT-FAMILY: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt"><o:p></o:p></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN" style="FONT-FAMILY: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><b style="mso-bidi-font-weight: normal"><span lang="EN" style="FONT-FAMILY: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">[RUP]<o:p></o:p></span></b></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN" style="FONT-FAMILY: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">RUP</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Palatino Linotype'; mso-hansi-font-family: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">的全称是</span><span lang="EN" style="FONT-FAMILY: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">Rational Unified Process</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Palatino Linotype'; mso-hansi-font-family: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">，是一套定义得很完整的软件工程模型。它强调编码前的需求分析和设计，以及短迭代周期的开发和发布。它鼓励团队首先开发项目中风险最高的模块，用更多的时间发现和应对问题，当设计需要变化时，它也能够在一定程度上减轻一些重复工作。不过，因为</span><span lang="EN" style="FONT-FAMILY: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">RUP</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Palatino Linotype'; mso-hansi-font-family: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">十分严谨，也比较具体，通常要完全跟着这个流程走也不是</span><span lang="EN" style="FONT-FAMILY: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">100%</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Palatino Linotype'; mso-hansi-font-family: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">必要。</span><span lang="EN" style="FONT-FAMILY: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt"><o:p></o:p></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN" style="FONT-FAMILY: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Palatino Linotype'; mso-hansi-font-family: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">下面我们来看看实际上我们应该采取什么样的流程或者策略：</span><span lang="EN" style="FONT-FAMILY: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt"><o:p></o:p></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN" style="FONT-FAMILY: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Palatino Linotype'; mso-hansi-font-family: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">实际的</span><span lang="EN" style="FONT-FAMILY: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">J2EE</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Palatino Linotype'; mso-hansi-font-family: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">项目中，</span><span lang="EN" style="FONT-FAMILY: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">RUP</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Palatino Linotype'; mso-hansi-font-family: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">的应用呈逐年上升的趋势，不过也并非所有这些采用了</span><span lang="EN" style="FONT-FAMILY: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">RUP</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Palatino Linotype'; mso-hansi-font-family: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">的项目也是完完全全</span><span lang="EN" style="FONT-FAMILY: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">RUP</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Palatino Linotype'; mso-hansi-font-family: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">式的。我们可以考虑一种综合上面三种流程的优点的方式，根据具体的项目量体裁衣。需要对这几种的优点来一个总结：瀑布式由于比较成熟，通常很好的强调了先需求后设计再编码的重要性，也比较适合大公司先预算后执行的方式；极限编程强调测试先行和简单是美，这样有利于及早发现问题以及更好的应对变化；</span><span lang="EN" style="FONT-FAMILY: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">RUP</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Palatino Linotype'; mso-hansi-font-family: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">强调的集中化的分析和设计也有其不可替代的优越性。</span><span lang="EN" style="FONT-FAMILY: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt"><o:p></o:p></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN" style="FONT-FAMILY: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Palatino Linotype'; mso-hansi-font-family: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">要做出一个结论性的答案并不容易，如果贵公司相对较大并且愿意支付一定的管理成本来推一套成熟且完整的开发流程并在公司内部所有项目或者是大多数项目严格执行，我想</span><span lang="EN" style="FONT-FAMILY: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">RUP</span><span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Palatino Linotype'; mso-hansi-font-family: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt">应该是首选；如果贵公司希望有更大的灵活性，可以考虑一些折衷的方案，根据具体的项目，从上面三种流程提取有价值的部分，来确定具体的流程。</span><span lang="EN" style="FONT-FAMILY: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt"><o:p></o:p></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN" style="FONT-FAMILY: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt"><o:p>&nbsp;</o:p></span></p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN" style="FONT-FAMILY: 'Palatino Linotype'; mso-bidi-font-size: 10.5pt"><o:p>&nbsp;</o:p></span></p><img src ="http://www.blogjava.net/sean/aggbug/365.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sean/" target="_blank">大胃</a> 2005-01-16 23:18 <a href="http://www.blogjava.net/sean/archive/2005/01/16/365.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>简单说说对J2EE项目组的人员结构的看法</title><link>http://www.blogjava.net/sean/archive/2005/01/16/363.html</link><dc:creator>大胃</dc:creator><author>大胃</author><pubDate>Sun, 16 Jan 2005 14:11:00 GMT</pubDate><guid>http://www.blogjava.net/sean/archive/2005/01/16/363.html</guid><wfw:comment>http://www.blogjava.net/sean/comments/363.html</wfw:comment><comments>http://www.blogjava.net/sean/archive/2005/01/16/363.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sean/comments/commentRss/363.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sean/services/trackbacks/363.html</trackback:ping><description><![CDATA[<p>&nbsp;</p> <p>有人做了一个总结：一个J2EE项目组通常会有怎样的人员结构，或者说，一个J2EE项目通常需要怎样一组代表不同的工作性质及内容的角色。实际情况中，一个人可能同时承担多个不同的角色，一个角色也可以有很多不同的人来分担。这些角色包括：</p> <ul> <li>项目经理</li> <li>架构师</li> <li>领域专家</li> <li>美工</li> <li>前端开发人员</li> <li>后端开发人员</li> <li>数据库设计师</li> <li>数据库管理员</li> <li>数据移植专员</li> <li>系统管理员</li> <li>测试人员</li></ul> <p>其中，项目经理负责安排和协调整个开发小组的任务和进度，向决策层和用户代表反馈项目进展和状态，以及负责保证项目组或者其成员所需的所有资源足够完成项目开发并及时到位；架构师负责项目的总体技术选择、系统设计和指定具体的技术标准和细节，通常也需要跟整个小组紧密协调；领域专家负责采集和分析用户需求，在整个项目开发过程中了解和确保产品能够符合最终用户的要求；美工设计用户界面；前端开发人员按照美工的蓝图增加具体的前端处理逻辑；后端开发人员实现具体的业务逻辑，通常包括持久层的操作；数据库设计师负责通过领域专家提供的需求设计数据库的表结构和表关系，如ER图；数据库管理员根据ER图生成实际的数据表，并对数据库进行维护，以及协助优化数据库和SQL查询语句性能等；数据移植专员负责编写移植脚本，帮助客户将原有系统数据导入新的系统；系统管理员负责维护开发工作中需要的所有开发、测试、产品环境，以及进行产品发布；测试人员负责测试，保证开发出来的产品满足需求文档并没有bug，测试人员应该具备一定的领域知识。</p> <p>拿一个具体的项目组来说：</p> <p>这是一个J2EE外包项目的开发组，共有人员30名，1个项目经理、2个领域专家、22个开发人员开发人员、1个数据库管理员、以及4个测试人员。由于设计部分是由甲方做好，项目组没有专职的架构师和数据库设计师。项目采用EJB+Struts的总体结构。</p> <p>项目经理负责同甲方的项目经理确认任务安排和进度，以及协调项目组内部各成员的工作进展，并提供必要的行政和软硬件支持，同时执行项目经理的其他日常工作，如配置管理等。2个领域专家参与同甲方领域专家的沟通，确保拿到的需求文档和设计文档充足且合理，并参与SIT，确保最终的产品符合文档的需求。数据库管理员负责维护并同步甲方提供的数据库，同时协助开发人员优化SQL。测试人员负责在不同模块完成后进行功能测试以及最后的SIT。开发人员按照不同的模块分成5个组，每个组又进一步细分为1个后端开发人员和多个前端开发人员，后端开发人员同时是该组组长。所有组长统一向项目经理汇报。</p> <p>由此可见，上面总结出的那个J2EE项目组成员角色清单还是相当有说服力。总体上，在这个项目组中，项目经理是其协调和沟通作用的单点，项目组的主体由开发人员构成（这不奇怪，本身就是要开发产品嘛），领域专家和数据库管理员主要还是配合开发人员的工作，而测试人员则除了一般意义上的测试和配合之外，因为相对独立于开发，也起到一定的对项目开发流程的监督作用。</p> <p>J2EE这个东东（可以理解为一组规范）本身就强调角色分工，当这些分工不同的角色都尽心尽力做好自己的工作，文档齐备，并且各个不同的角色之间保持足够的沟通，加上确定的流程，面向企业的Java项目就会更倾向于朝着健康可控的方向发展。</p> <p>&nbsp;</p><img src ="http://www.blogjava.net/sean/aggbug/363.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sean/" target="_blank">大胃</a> 2005-01-16 22:11 <a href="http://www.blogjava.net/sean/archive/2005/01/16/363.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>