# MySQL dump 8.16 # # Host: localhost Database: webpm #-------------------------------------------------------- # Server version 3.23.47-nt # # Table structure for table 't_webpm_project' # DROP TABLE IF EXISTS t_webpm_project; CREATE TABLE t_webpm_project ( fid int(11) NOT NULL auto_increment, fprojectname varchar(60) NOT NULL default '', fkeywords varchar(80) default NULL, fdescription varchar(250) default NULL, fauthor varchar(20) default NULL, fcreatedate datetime default '0000-00-00 00:00:00', fupdatedate datetime default '0000-00-00 00:00:00', fflag tinyint(4) NOT NULL default '0', PRIMARY KEY (fid), UNIQUE KEY fprojectname (fprojectname) ) TYPE=MyISAM; # # Dumping data for table 't_webpm_project' # LOCK TABLES t_webpm_project WRITE; INSERT INTO t_webpm_project VALUES (1,'test','test','Test Project','brokendoor','2002-07-12 02:53:19','2002-10-12 11:53:19',0); UNLOCK TABLES; # # Table structure for table 't_webpm_project_member' # DROP TABLE IF EXISTS t_webpm_project_member; CREATE TABLE t_webpm_project_member ( fid int(11) NOT NULL auto_increment, fprojectid int(11) NOT NULL default '0', fmembername varchar(20) default NULL, fcreatedate datetime default '0000-00-00 00:00:00', fupdatedate datetime default '0000-00-00 00:00:00', fflag tinyint(4) NOT NULL default '0', PRIMARY KEY (fid) ) TYPE=MyISAM; # # Dumping data for table 't_webpm_project_member' # LOCK TABLES t_webpm_project_member WRITE; INSERT INTO t_webpm_project_member VALUES (1,-1,'brokendoor','2002-07-12 02:53:19','2002-07-12 02:53:19',0),(2,1,'brokendoor','2002-07-12 02:53:39','2002-10-12 11:53:19',-1); UNLOCK TABLES; # # Table structure for table 't_webpm_user' # DROP TABLE IF EXISTS t_webpm_user; CREATE TABLE t_webpm_user ( fid int(11) NOT NULL auto_increment, fusername varchar(20) NOT NULL default '', fpassword varchar(20) default NULL, fquestion varchar(50) default NULL, fanswer varchar(50) default NULL, femail varchar(60) default NULL, faddress varchar(120) default NULL, fphone varchar(20) default NULL, fsex char(1) default NULL, fbirthday varchar(20) default NULL, fmemo varchar(250) default NULL, fcreatedate datetime default '0000-00-00 00:00:00', fupdatedate datetime default '0000-00-00 00:00:00', fflag tinyint(4) NOT NULL default '0', PRIMARY KEY (fid), UNIQUE KEY fusername (fusername) ) TYPE=MyISAM; # # Dumping data for table 't_webpm_user' # LOCK TABLES t_webpm_user WRITE; INSERT INTO t_webpm_user VALUES (1,'tester','testpass',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'2002-07-12 02:27:42','2002-07-12 02:27:42',0),(2,'brokendoor','qadyz5i1','who am i?','me','brokendoor@sina.com','深圳','','M','1973-10-5','测试','2002-07-12 02:49:38','2002-08-20 12:01:59',0),(3,'破门','qadyz5i1','who am i?','me','brokendoor@sina.com','','','M','1973-10-5','','2002-08-26 22:23:50','2002-08-26 22:23:50',0),(4,'test','test','test','test','test@test.com','','','M','1980-1-1','','2002-09-02 14:17:20','2002-09-02 14:17:20',0),(5,'a','a','a','a','aa@a','','','M','1980-1-1','','2002-09-02 14:18:00','2002-09-02 14:21:46',0),(6,'test1','test','test','test','test@test.com','','','W','1980-1-1','','2002-09-23 09:22:24','2002-09-23 09:22:24',0); UNLOCK TABLES; # # Table structure for table 't_wiki_article' # DROP TABLE IF EXISTS t_wiki_article; CREATE TABLE t_wiki_article ( ftopic varchar(200) binary NOT NULL default '', fbody text NOT NULL, fauthor varchar(20) default NULL, fcreatedate datetime NOT NULL default '0000-00-00 00:00:00', fupdatedate datetime NOT NULL default '0000-00-00 00:00:00', fflag tinyint(4) NOT NULL default '0', fmender varchar(20) default NULL, fid int(11) NOT NULL auto_increment, PRIMARY KEY (fid) ) TYPE=MyISAM; # # Dumping data for table 't_wiki_article' # LOCK TABLES t_wiki_article WRITE; INSERT INTO t_wiki_article VALUES ('JWIKI 自由讨论区','\'\'\'欢迎来到 WebPM 项目的 JWIKI 自由讨论区!\'\'\'\r\n----\r\n* \'\'\'关于 [WebPM] \'\'\'\r\n- WebPM 的英文全称是 (Project Management On Web),是由Softme Studio发起的自由软件平台。其主要目标是为中文自由软件的开发者、使用者和推广者提供基于互联网的开放式管理平台环境。\r\n\r\n* \'\'\'关于 WikiWikiWeb\'\'\',看看它到底好在哪里?它应该如何使用呢?\r\n下面的描述来自第一个WikiWikiWeb : http://c2.com/cgi/wiki\r\n首先,“Wiki”的想法可能会让人觉得奇怪,不过可以来深入一点并浏览这里的连接。\r\n“Wiki”是一个写作系统;是一个讨论媒介;是一个知识库;是一个邮件系统;也是一个合作的工具。事实上,我们也并不能明确的定义它是什么,但是它是在网络上进行异步通讯的很有趣的方式。\r\n\r\n它的名字“Wiki”本身也很奇怪 - 是什么意思呢? \r\n您可以访问 WikiWikiWeb 来获得答案,并且还可以看到其他的一些问题,但是一个简短的答案是:Wiki Wiki 是夏威夷语,意思是“很快”。如果你对夏威夷语有点兴趣,这里有一篇我在网上查到的文章-[基础夏威夷语],看看还有那些奇怪的词语。(也许下一个神奇的系统命名的会用得到,呵呵。)\r\n\r\n* \'\'\'[JWIKI最新公告]\'\'\'--- 关于JWIKI的一些最新公告\r\n* \'\'\'[起点]\'\'\'--- 这里是jwiki的导航,让我们从这里开始吧!支持自由!支持自由软件!\r\n* \'\'\'[文件格式化规则]\'\'\'--- 看一下应该如何输入和编辑文章。\r\n* \'\'\'[我要加入]\'\'\' --- 你有兴趣加入到WebPM项目中来的话,请在这里编辑,我们需要更多[自由开发者]!\r\n----\r\n现在正处于测试阶段,有什么错误请在[错误报告]中指出。\r\n由 Softme Studio WebPM 项目小组[浆糊]负责开发和维护。\r\n访问 Softme Studio 主页 [softme.org|http://softme.org]','N/A','2002-02-22 00:34:54','2002-08-29 12:59:04',0,'brokendoor',1),('浆糊','\r\n\r\n\r\n\r\n[user=浆糊]\r\n[big] 千秋万载,一统江湖![/big] \r\n----\r\n我都晕菜,蓝星\r\n\r\n浆糊而已,仅此\r\n----\r\n浆糊浆糊我爱你,就想老鼠爱大米!!! 这东西还挺好用的。呵。《踏冰》:P\r\n\r\n非常好!我要源码!!!一定要!![要]\r\n----\r\n<> come here ! jianghu where are u ???\r\n----\r\n浆糊一个人累得不行了阿,谁帮忙阿\r\n----\r\n也许一开始靠一种冲动和激情,等这点唯一的力量失去以后还能靠什么,浆糊现在才感到寂寞与孤单。也许就像破门说的那样:要准备好没有人自己一个人也要作到底的决心。也许对我来说,只能说一个人把代码写到底的决心。现在才感慨一句:做点事情真不容易啊。现在都是金钱的社会,没有点好处,谁又会来支持和加入我们,看来也只能靠运气,看看是否能遇到像我们这样的人。不知道国外的那些组织是如何运作的,不看apache,就是jive也很让我感觉羡慕,虽然只是一个论坛而已。为什么国内就没有这种团体或者一群狂热者,也许是没有发现,也许根本没有。论坛上见的帖子很多,很多讨论这个问题,充满很多的激情,但是从来就没有看到过结尾。从javaunion到smiling到dev-club,更多的是空谈,也许做做设计的还是有的,雄心壮志尽在宏伟蓝图上,但是到真真的累活来了,却一个一个不见踪影。就浆糊参加的网上很作也不少,每次都是尽力而为,写了不少的东西,到头来都是白忙一场,颇让浆糊感到伤心。其实自己也知道,能坚持下去的几率很小,也许是虚荣心,也许是不甘心,每次还是义无返顾。咳~,发发牢骚,仅此\r\n----\r\n浆糊,你还是不是男人,切,累就累吧,还说出来,受不了。。。要不我送你几个 PLMM 安慰你一下吧。切,不是男人的东西 《踏冰》\r\n----\r\nSoftme Studio WebPM\r\n\r\n-------------------\r\n\r\n老兄别灰心啊!你这个wiki不是做得挺好的吗?\r\n--------------------------------------\r\n现在快年底了,大家都好忙好累,所以要学会放松,罗马不是一天建成的,webpm也不是一个月能做好的。所以别灰心,先放自己几天假,心情就会不一样的。\r\n另:国内目前还没有存在开源软件的沃土,大部分programmer还在为生计奔波,象国外那工作轻松又有钱的程序员团体在中国可能要若干年后才会出现(也许更长时间),谁让我们是初级阶段呢。所以我们要现实一些,少空谈理想,多做实事,从点滴做起,反正我是会坚持到最后的。\r\n\r\n对了,这个[wiki]我好象还不太会用,有时间再研究了。\r\n\r\n[takaka]\r\n2002.01.30\r\n----\r\n如果累的话,可以歇歇啊。WebPM 决不会白忙一场的! 我自从2001年3月份提出这个项目,经历了这么久的折磨,如果我们不坚持,就不会有今天的Wiki,更不会有明天的WebPM。就更不会有以后能够在WebPM的基础上发展的各种自由软件。兄弟们啊,还有更多的兄弟们在看着等着我们呢。(他们暂时精神支持我们!呵呵.)鸽子不是也来加入了么?很多东西你可以告诉别人怎么做,要不然他们也不知道该如何加入!我现在就是这样做的,你说我偷懒也行,呵呵...这不久累着你了么?你得想法让其他人能够提供有效的帮助。唯一的方法就是你帮助他们学习,理解系统的要求,掌握如何才能提供帮助。\r\n浆糊,我们并不孤单啊!不过对于Java开发,你是高手的寂寞而已,:)。我们都还在拼命的找时间学呢。 BrokenDoor 2002/1/31\r\n----\r\n浆糊,你还是不是男人,切,累就累吧,还说出来,受不了。。。要不我送你几个 PLMM 安慰你一下吧。切,不是男人的东西 《踏冰》\r\n----\r\n浆糊已经有一个人把代码写到底的决心。。。。\r\n----\r\n终于恢复了\r\n----\r\n10月的黄山之旅\r\n[img]http://www.16885.com/wader/image/han2.jpg[/img]\r\n----\r\nwiki是好东东,浆糊值得鼓励。\r\n----','N/A','2002-02-21 23:31:16','2002-03-17 12:30:40',0,'szwxh',2),('2001年12月5日 破门和浆糊的聊天纪录','----\r\n浆糊 (11:05:32): 我想知道,我是什么时候开始写wiki的,什么时候和你认识的?\r\n下面就是我们第一次谈到[webpm_wiki]的QQ纪录。 BrokenDoor 2002/2/10\r\n\r\n说明: java.net 就是 大家都崇拜的 [浆糊] 人士 !\r\n----\r\n2001-12-05 09:36:33 brokendoor\r\n你好\r\n\r\n2001-12-05 09:36:34 java.net\r\n:)\r\n你好 。\r\n\r\n2001-12-05 09:37:00 java.net\r\n我在smiling xp上经常看到你。\r\n\r\n2001-12-05 09:37:46 brokendoor\r\n是啊,我现在正在公司推行XP\r\n\r\n2001-12-05 09:38:16 java.net\r\n嗯,看到你发的文章了。\r\n我也是刚刚开始学习,主要受notyy的影响,呵呵。。\r\n以前和notyy一起作过xpbuilder\r\n\r\n2001-12-05 09:39:42 brokendoor\r\n我当时几乎是同时发起了WebPM,不过我是在武汉自由软件协会认识notyy的。\r\n\r\n2001-12-05 09:40:09 brokendoor\r\n我没有用过j2eeunit, 你认为可以测试ASP/JSP网页么?\r\n\r\n2001-12-05 09:39:53 java.net\r\n嗯。我知道的。\r\n你的项目我也看过的,和xpbuilder有很多的相似之处\r\n\r\n2001-12-05 09:40:36 java.net\r\n至少可以测试jsp的,我和notyy试过。\r\n不过现在不用了\r\n\r\n2001-12-05 09:41:20 brokendoor\r\n是啊,不过当时也不清楚XP是什么。\r\n\r\n2001-12-05 09:41:38 brokendoor\r\n我当时说和notyy合并,但是也没有下文了\r\n\r\n2001-12-05 09:41:34 java.net\r\n咳~~,现在倒好,两个都没有消息了 :)\r\n\r\n2001-12-05 09:42:58 brokendoor\r\n我倒是觉得只要坚持,会有结果的。只不过我现在确实很少自己写程序了。\r\n\r\n2001-12-05 09:43:02 java.net\r\n我还不清楚,到底网络合作的是不是可行。\r\n有没有这样的成功的例子,在国内\r\n\r\n2001-12-05 09:43:52 java.net\r\n我觉得如果做项目管理,平时也应该写点程序的,就像国外很多的高人\r\n\r\n2001-12-05 09:44:52 brokendoor\r\n呵呵,好像没有。XP对现场的要求太高了,尤其是没有实践的时候。\r\n不过我现在主要职务是部门经理,不是项目经理。\r\n\r\n2001-12-05 09:44:58 java.net\r\n我那个时候是对xpbuilder投入和很多的热情,写了不少的代码。\r\n\r\n2001-12-05 09:45:49 brokendoor\r\n可以继续啊,也不一定就重开webpm\r\n\r\n2001-12-05 09:45:38 java.net\r\n哦。那也许其它的事情也比较多。\r\n\r\n2001-12-05 09:46:35 java.net\r\n我很想继续。没有响应,也没有人组织 :(\r\n毕竟由我来组织的话,还是感觉力不从心\r\n\r\n2001-12-05 09:47:50 brokendoor\r\n目前,加上你至少还有3个人愿意重新启动。\r\n\r\n2001-12-05 09:47:36 java.net\r\n还有谁?\r\n\r\n2001-12-05 09:48:07 brokendoor\r\ntakaka\r\n\r\n2001-12-05 09:48:09 java.net\r\n好像看到过的。他是不是做页面很内行的那个?\r\n\r\n2001-12-05 09:48:41 brokendoor\r\n是\r\n\r\n2001-12-05 09:48:59 brokendoor\r\nxpbuilder的logo就是他做的\r\n\r\n2001-12-05 09:50:23 java.net\r\n嗯。知道的。\r\n如果三个人启动的话,如何分配?\r\n一开始的时候也不太可能有很多人参加\r\n\r\n2001-12-05 09:51:16 java.net\r\n其实我觉得xp中,每个人都是设计师,不知道我的想法是不是对\r\n\r\n2001-12-05 09:51:54 brokendoor\r\n我觉得第一步是客户,我们要确认究竟做什么。我想第一件事是将xpbuilder和webpm的故事整理一下。\r\n\r\n2001-12-05 09:52:04 java.net\r\n嗯。如果能找些customer就好了\r\n\r\n2001-12-05 09:52:43 brokendoor\r\n你的看法是对的,我觉得XP中的角色虽然有划分,但是都是互相学习的\r\n\r\n2001-12-05 09:53:17 brokendoor\r\nnotyy可以啊,管理没有空,做customer总行吧\r\n\r\n2001-12-05 09:53:35 brokendoor\r\n还有adamli\r\n\r\n2001-12-05 09:53:18 java.net\r\n嗯,是的。\r\n我对 desing a little,test a little,code a little很有兴趣,很想试试\r\n\r\n2001-12-05 09:54:13 brokendoor\r\n也就是sample这个关键词\r\n\r\n2001-12-05 09:53:48 java.net\r\n嗯。是啊 。\r\n\r\n2001-12-05 09:54:25 java.net\r\n你说的是 user story?\r\n\r\n2001-12-05 09:55:27 brokendoor\r\n是,如果故事整理完了,我决定去申请一个JSP虚拟主机。这样有个集成的环境。\r\n\r\n2001-12-05 09:56:12 brokendoor\r\n你看了我的启动问题分析的贴子么?\r\n\r\n2001-12-05 09:55:48 java.net\r\n嗯。可以。一开始人少的话,可以将就一下。。\r\n让我们先做起来\r\n\r\n2001-12-05 09:56:28 brokendoor\r\nhttp://xpchina.smiling.com/group/posts/view_forum.ecgi?group_id=9999&res_message_id=1100692\r\n\r\n2001-12-05 09:56:06 java.net\r\n??在哪里?\r\n\r\n2001-12-05 09:57:07 brokendoor\r\n2,3,4,5都不好解决\r\n\r\n2001-12-05 09:57:20 brokendoor\r\n反而人员不是问题了\r\n\r\n2001-12-05 09:57:52 java.net\r\n嗯。是的。\r\n\r\n2001-12-05 09:59:02 brokendoor\r\n第4个问题,只要出钱就可以了。我准备提供这笔经费。\r\n\r\n2001-12-05 09:59:27 brokendoor\r\n第3个问题,看来没有更好的办法。\r\n\r\n2001-12-05 09:59:42 brokendoor\r\n第2个问题你有什么好建议\r\n\r\n2001-12-05 10:00:08 brokendoor\r\n可能最好的办法是netmeeting.但是目前有些问题。\r\n\r\n2001-12-05 10:00:12 java.net\r\n第三个问题肯定是没有办法解决了。\r\n第二个问题的话,我想可以用QQ的聊天室,你看呢\r\n\r\n2001-12-05 10:01:38 brokendoor\r\n以前webpm就是用qq,但是根据我在公司的实践,看来是不够的\r\n\r\n2001-12-05 10:01:51 brokendoor\r\n我们需要一个whiteboard\r\n\r\n2001-12-05 10:01:29 java.net\r\n缺少什么?\r\n\r\n2001-12-05 10:01:53 java.net\r\n嗯。用BBS 的话,交流的速度太慢了。\r\n\r\n2001-12-05 10:02:37 brokendoor\r\n白板,主要是要直观\r\n\r\n2001-12-05 10:02:34 java.net\r\n你觉得用什么比较合适?\r\n\r\n2001-12-05 10:03:34 brokendoor\r\n我觉得IRC可能好一些\r\n\r\n2001-12-05 10:03:46 brokendoor\r\n不过,服务器不好解决\r\n\r\n2001-12-05 10:03:26 java.net\r\n我没有用过。是不是就是聊天服务器阿?\r\n\r\n2001-12-05 10:04:36 brokendoor\r\n对不起,错了。还是neetmeeting,才有白板的功能\r\n\r\n2001-12-05 10:04:54 java.net\r\n哦。\r\n我没有试过,那我们为什么不尝试一下\r\n\r\n2001-12-05 10:05:32 brokendoor\r\n好啊。\r\n\r\n2001-12-05 10:05:24 java.net\r\n现在能试试吗/\r\n\r\n2001-12-05 10:06:01 brokendoor\r\n你的ip多少?\r\n\r\n2001-12-05 10:06:05 java.net\r\n阿?完蛋,我这里是用代理的。\r\n要不我到服务器上去试试\r\n\r\n2001-12-05 10:07:41 brokendoor\r\n我也用代理的\r\n\r\n2001-12-05 10:07:47 java.net\r\n那怎么试啊?\r\n\r\n2001-12-05 10:09:39 brokendoor\r\n我也搞不清楚,其实我在想,利用java Applet可以实现一个白板的功能\r\n\r\n2001-12-05 10:09:36 java.net\r\n一个白板需要什么功能?\r\n\r\n2001-12-05 10:10:50 brokendoor\r\n就是一个paintbrush\r\n\r\n2001-12-05 10:10:59 java.net\r\n那也是难了点。\r\n\r\n2001-12-05 10:12:10 brokendoor\r\n我不清楚,反正也可以先用QQ克服一下的\r\n\r\n2001-12-05 10:12:13 java.net\r\n嗯。是的。\r\n慢慢地会有办法的。面包会有的\r\n\r\n2001-12-05 10:13:00 brokendoor\r\n要不然我们还是把讨论整理一下,贴出去。让大家看看。\r\n\r\n2001-12-05 10:13:00 java.net\r\n嗯。好的。\r\n\r\n2001-12-05 10:13:14 java.net\r\nhttp://www.javaren.com/cgi-bin/topic.cgi?forum=1&topic=7003\r\n\r\n2001-12-05 10:16:39 java.net\r\n那我们是不是现整理出来?\r\n\r\n2001-12-05 10:17:22 brokendoor\r\n好啊\r\n\r\n2001-12-05 10:25:34 brokendoor\r\n你在整理么?还是我来?\r\n\r\n2001-12-05 10:25:35 java.net\r\n我在找,没找着。要不你找吧\r\n\r\n2001-12-05 10:26:08 brokendoor\r\n我来吧\r\n\r\n----\r\n分类:[WebPM] | [WebPM 小组会议] \n----\n2002-10-3 20:27:24 [test1]\ndfgsdfgd','202.105.104.140','2002-02-10 22:02:11','2002-10-03 20:27:24',0,'test1',149),('WebPM','WebPM 项目主页\r\n----CopyLeft (l) 2001 Softme Studio\r\n(brokendoor) brokendoor@sina.com\r\n\'\'有关版权问题的讨论移至 CopyLeft 讨论区...\'\'\r\n----\r\n\'\'\'什么是 WebPM ?\'\'\'\r\nWebPM 的英文全称是 (Project Management On Web),是由Softme Studio发起的自由软件平台。其主要目标是为中文自由软件的开发者、使用者和推广者提供基于互联网的开放式管理平台环境。\r\n---- \r\n* \'\'\'[WebPM.成员章程]\'\'\'\r\n需要申请加入WebPM开发组的朋友们请仔细阅读。\r\n----\r\n* [licence] * [源码下载] * [安装说明] * [webpm源码分析]\r\n----\'\'\'子项目文档\'\'\'\r\n* [webpm_wiki] 子项目 --- WebPM 的wiki系统,目前主力开发成员为 - [浆糊]。\r\n\r\n* [webpm_info] 子项目 --- WebPM的主题项目,主要目标是实现webpm系统整合,以及项目信息管理。\r\n\r\n* [webpm_net] 子项目 --- WebPM的网络交流系统,目前的主要任务是开发 WebpmChat 和 WebpmWhiteBoard.\r\n----\r\n* \'\'\'规格定义\'\'\'\r\n - [webpm 规格说明书] - 1.0 版 - 草稿,希望大家多提意见,可以在讨论区讨论。\r\n - [webpm 开发手册] - 1.0 版 - 便于WebPM 开发人员参考 - 2001年12月27日\r\n - [webpm 编码规范] - 1.0 版 - 增加了页面和数据库命名约定。- 2002年1月3日\r\n - [webpm CVS 使用指南] - 1.0 版 - 便于WebPM 开发人员参考 - 2001年12月27日\r\n----\'\'\'讨论区:\'\'\'\r\n* [webpm_info 讨论区] --- 讨论webpm_info子项目的需求、开发和应用等主题。\r\n\r\n* [webpm_wiki 讨论区] --- 讨论webpm_wiki子项目的需求、开发和应用等主题。\r\n\r\n* [webpm_net 讨论区] --- 讨论webpm_net子项目的需求、开发和应用等主题。\r\n\r\n* [WebPMAndWiki] --- 讨论 WebPM 如何与 WiKiWiKiWeb 结合,发挥最有效的网络开发支持能力。\r\n----\r\n* \'\'\'小组会议 \'\'\'\r\n-- [WebPM 小组会议] - WebPM 开发人员会议的记录和纪要。\r\n----\r\n[我要加入]! - 看看目前WebPM的开发人员。','N/A','2002-02-22 00:45:48','2002-03-11 15:55:20',0,'61.141.205.107',3),('起点','这里是 WebPM 项目的WiKi自由讨论区,欢迎大家使用!\r\n\r\n如果你是第一次使用此类系统,你可以在这里[一试身手]!\r\n\r\n如果你想查看某一类的信息,你可以在这里看到[主题分类]。\r\n\r\n如果你想知道应该如何添加自己的文章,不妨先在[签名簿]签个到,建立自己的专题。\r\n\r\n如果你还想知道更多的信息,看看[WebPM]的项目计划。\r\n\r\n如果你发现了本系统的任何问题,可以寻求[帮助]或者提交一份[错误报告]。\r\n\r\n如果你不小心删除了一些有用的信息,请尽快通知[管理员寻呼]。','N/A','2002-01-23 01:32:01','2002-01-23 01:32:01',1,'N/A',4),('中文','伟大的[中国]的文字!发\r\n','N/A','2002-02-02 02:09:33','2002-02-02 02:09:33',0,'192.168.1.228',5),('BrokenDoor','[user=BrokenDoor]\r\n[WebPM] 的客户——破门。呵呵..\r\n\r\n我初8上班,这几天上网不方便,辛苦你了! --2002/02/14 浆糊\r\n---\r\n[linux 用户管理]\r\n我星期一晚回上海。这几天服务器好像当了。 --2002/03/09 [浆糊] \r\n我回来了 --2002/03/11 [浆糊]\r\n----\r\n破门最近的日子不好过了,有好几个项目同时开工!希望大家多努力,WebPM发展还是要大家一起投入的。 ---- 2002/03/12 BrokenDoor','N/A','2002-02-22 08:25:32','2002-03-12 12:54:07',0,'BrokenDoor',6),('中国','不可能不知道吧。','N/A','2002-02-02 20:41:41','2002-02-02 20:41:41',0,'61.141.204.2',8),('最近变化','Finish','N/A','2002-01-24 10:06:42','2002-01-24 10:06:42',0,'N/A',9),('踏冰','一块冰,0 度以上也不会融化啊。。记住了。。。\r\n\r\n你的PLMM呢?让大伙儿一睹芳容,如何?\r\n----\r\n谁问的啊,留下姓名 《踏冰》\r\n----\r\n:-)\r\n----\r\n一定是 takaka 这家伙!\r\n----\r\n酷哥\r\n[img]http://www.tabing.8u8.com/30005a.jpg[/img]\r\n----\r\n踏冰好酷啊。。。喜欢,可以爱你吗?\r\n----\r\n如果你是个富婆就来爱我吧,我欢迎骚扰·!· (恶心吗,没感觉啊。)\r\n----\r\n[webPM开发成员相册]','浆糊','2002-02-07 00:25:41','2002-02-07 00:25:41',0,'61.167.164.5',10),('文件格式化规则','\'\'\'* 我应该如何格式化我的文章?\'\'\'\r\n目前JWIKI支持的标签如下----[no]\r\n显示用户信息: [user=BrokenDoor]\r\n\r\n粗体: \'\'\'这里是粗体字\'\'\'\r\n\r\n斜体: \'\'这里是斜体字\'\' \r\n\r\n标题:\r\n[h1]标题1[/h1]\r\n[h2]标题2[/h2]\r\n[h2]标题2[/h2]\r\n[h3]标题3[/h3] \r\n[h4]标题4[/h4] \r\n[h5]标题5[/h5]\r\n[h6]标题6[/h6]\r\n\r\n\r\n邮件:[email=abc@263.net]My Email[/email]\r\n\r\n图片:[img]/webpm/images/webpm_wiki_logo.gif[/img]\r\n\r\n小字体:[small]这里是小字体[/small]\r\n\r\n大字体:[big]这里是大字体[/big]\r\n\r\n预设字体:[pre]这里是预设字体[/pre]\r\n\r\n代码段:\r\n[code]\r\npackage org.softme.webpm.pub;\r\n/**\r\n * Title: WebPM\r\n * Description:\r\n * Copyright: Copyright (c) 2001\r\n * Company: WebPM\r\n * @author 浆糊\r\n * @version 1.0\r\n */\r\n\r\npublic class Debug {\r\n\r\n public Debug() {\r\n }\r\n public static void println(String aMsg){\r\n System.out.println(aMsg);\r\n }\r\n}\r\n[/code]\r\n横线:\r\n----\r\n[/no]\r\n这里是实际效果:\r\n----\r\n显示用户信息: [user=BrokenDoor]\r\n\r\n粗体: \'\'\'这里是粗体字\'\'\'\r\n\r\n斜体: \'\'这里是斜体字\'\' \r\n\r\n标题:\r\n[h1]标题1[/h1]\r\n[h2]标题2[/h2]\r\n[h2]标题2[/h2]\r\n[h3]标题3[/h3] \r\n[h4]标题4[/h4] \r\n[h5]标题5[/h5]\r\n[h6]标题6[/h6]\r\n\r\n超连接:[softme.org|http://www.softme.org]\r\n\r\n邮件:[email=climber_cn@263.net]My Email[/email]\r\n\r\n图片:[img]/webpm/images/webpm_wiki_logo.gif[/img]\r\n\r\n小字体:[small]这里是小字体[/small]\r\n\r\n大字体:[big]这里是大字体[/big]\r\n\r\n预设字体:[pre]这里是预设字体[/pre]\r\n\r\n代码段:\r\n[code]\r\npackage org.softme.webpm.pub;\r\n/**\r\n * Title: WebPM\r\n * Description:\r\n * Copyright: Copyright (c) 2001\r\n * Company: WebPM\r\n * @author 浆糊\r\n * @version 1.0\r\n */\r\n\r\npublic class Debug {\r\n\r\n public Debug() {\r\n }\r\n public static void println(String aMsg){\r\n System.out.println(aMsg);\r\n }\r\n}\r\n[/code]\r\n横线:\r\n----\r\n\r\n----\r\n如果您觉得还有需要的有用标记,请点击下面的[错误报告]。\r\n','N/A','2002-02-21 23:28:32','2002-02-26 17:54:29',0,'61.152.125.82',11),('WebPM 小组会议','这里是WebPM 开发组会议的记录和纪要汇总:\r\n------\r\n---[2002年2月27日的会议纪要] \r\n---[2002年2月27日 会议记录] \'\'WebPM 小组的重要会议,主要讨论了WebPM发展和成员章程两个议题。\'\'\r\n\r\n---[2002年2月20日 聊天记录] \'\'关于webpm_wiki-1.2的发布计划\'\'\r\n---[2002年2月6日 会议纪要]\r\n---[2002年2月6日 会议记录]\r\n\r\n---[2002年1月31日 聊天记录]\r\n---[2002年1月30日 聊天记录]\r\n---[2002年1月28日 会议记录]\r\n---[2002年1月21日 会议记录]\r\n\r\n---[2001年12月5日 破门和浆糊的聊天纪录]\r\n\r\n----\r\n分类:[WebPM]','BrokenDoor','2002-02-20 18:52:20','2002-03-04 15:42:56',0,'BrokenDoor',81),('2001年1月21日 会议记录','----\r\n说明:一起去听海 就是大家都爱的 踏冰 (别吐,要吐去厕所)\r\n----\r\n★欢迎您来到『webpm』房间★ \r\n \r\n浆糊: 我想说,是不是brokendoor负责把wiki的内容建设起来, \r\n\r\n浆糊: 内容建设时间不用太多 \r\n \r\nbrokendoor: 没问题,查找都搞定了么? \r\n \r\n浆糊: 查找没有搞定 \r\n \r\n浆糊: 我的下个任务是开发 最近更新 查找 \r\n \r\n浆糊: 还有锁定 \r\n \r\n浆糊对一起去听海说: 我这里可以得。 \r\n \r\nbrokendoor: 嗯,我改过页面样式。能不能用ftp? \r\n\r\n浆糊对brokendoor说: 我对Linux不熟悉 \r\n \r\nbrokendoor对浆糊说: 反正你用一个方便的用户调试,建一个webpm用户作发布好了。 \r\n \r\n浆糊对brokendoor说: 好的。 \r\n \r\nbrokendoor对浆糊说: 数据库也建两个用户,一个用户发布,另外一个做调试。 \r\n \r\n浆糊对brokendoor说: 页面建设什么时候开始弄? \r\n \r\nbrokendoor对浆糊说: 你弄好用户,发给我,我就可以开始了。wiki作为webpm的下级目录吧。 \r\n \r\nbrokendoor: 下来就是project管理部分的整理了。把注册用户和项目登记连接上来。 \r\n \r\n浆糊对brokendoor说: 嗯? webpm/jwiki对不? \r\n\r\n一起去听海对brokendoor说: 好的。 \r\n \r\n浆糊对brokendoor说: 我估计jwiki的数据库结构还得变 \r\n \r\n一起去听海对brokendoor说: 用户注册那部分,用的是 SERVLET 可是编译不了,我的环境总是出错。 \r\n \r\n一起去听海对浆糊说: 能把库结构发给我一份吗? \r\n \r\n浆糊对一起去听海说: 我把我的代码给你。你试试我的数据库接口,怎么样? \r\n\r\n一起去听海对brokendoor说: 要不就先 简单的把功能实现了。用 JAVABEAN吧。 \r\n \r\n一起去听海对浆糊说: 好。 \r\n \r\nbrokendoor: 你们能够收到topica的邮件么? \r\n \r\n一起去听海对brokendoor说: 能。 \r\n \r\n一起去听海对brokendoor说: 你说,现在是不是只实现 注册功能就行。 \r\n \r\n一起去听海对brokendoor说: 不考虑用 SERVLET \r\n \r\n一起去听海对brokendoor说: 如果那样,我就用 BEAN 了。 \r\n \r\nbrokendoor对一起去听海说: 是的 \r\n \r\n一起去听海对brokendoor说: 我已经把程序发给 JAVANET了,不过他说,数据借口不一样。 \r\n \r\nbrokendoor对一起去听海说: 必须统一数据接口 \r\n\r\nbrokendoor对浆糊说: 我们要好好考虑如何结合wiki的功能,建立主页,用户注册页面和项目主页。 \r\n \r\n浆糊对一起去听海说: 代码有什么问题,和我说 \r\n \r\n一起去听海对浆糊说: 好。 \r\n \r\nbrokendoor对浆糊说: 可能要允许一些特殊的标记,比如 login, project \r\n \r\n一起去听海对brokendoor说: 新键 项目 要增加功能了? \r\n \r\n浆糊对brokendoor说: 嗯,是的。 \r\n \r\n浆糊对brokendoor说: 其实login作为一个关键字就可以了。 \r\n \r\nbrokendoor: 不是,主要是有一些webpm 内定的功能允许在wiki页面调用 \r\n \r\n浆糊对brokendoor说: 在线用户在哪里? \r\n \r\nbrokendoor: 很多东西,我们可以作为标准的页面,允许wiki页面嵌入或连接访问 \r\n \r\nbrokendoor: 可以先单独作了再说。用bean会不会比较好调用? \r\n \r\nbrokendoor: 大家想一下,怎么能结合的更好,更方便? \r\n \r\n一起去听海对brokendoor说: 如果保存 在线用户,就用 BEAN 吧。 \r\n \r\n浆糊对brokendoor说: brokendoor说的那个嵌入标准页面,没有问题。 \r\n \r\n一起去听海对brokendoor说: ANT 真的很好用吗? \r\n \r\n一起去听海对brokendoor说: 你做的??? \r\n\r\nbrokendoor: 哪有那么厉害,tomcat开发组的工具 \r\n \r\n一起去听海对浆糊说: 你的 数据接口,有没有说明? \r\n \r\nbrokendoor对一起去听海说: 好的,我希望项目信息部分可以快点出来。takaka 最近也不见了,所以靠你了 \r\n \r\nbrokendoor: ant 的最好的作用是可以自动完成build和发布工作 \r\n \r\n浆糊对brokendoor说: 暂时没有,不过很简单。 \r\n \r\nbrokendoor: 项目注册 \r\n \r\n浆糊对brokendoor说: 看看我的例子 \r\n \r\n一起去听海对浆糊说: 好的。 \r\n \r\n一起去听海对浆糊说: 我给你的接口,你改动多少??? \r\n \r\n浆糊: 几乎全部。 \r\n \r\n一起去听海对浆糊说: 呵。。。 \r\n \r\nbrokendoor: takaka写了一点代码,你收到么? \r\n \r\n一起去听海对brokendoor说: 没有。 \r\n \r\n浆糊: 收到了。但是也是接口不统一 \r\n \r\nbrokendoor: 可以简单点,就是id, name, status 就行了. \r\n \r\n浆糊: 数据库操作的部分 \r\n \r\nbrokendoor对浆糊说: 交给踏冰改吧,你负责wiki \r\n \r\n浆糊: 好的。wiki还有很多要做。公司的事情也是多的很,咳~~ \r\n \r\nbrokendoor对浆糊说: 我想踏冰负责项目部分,以后是任务管理(流转) \r\n \r\nbrokendoor对浆糊说: chat部分我另外找人做好了。 \r\n \r\n浆糊: 呵呵。。不是说你做阿 :) \r\n \r\n一起去听海对brokendoor说: 好的。。 \r\n \r\n浆糊: 好。 \r\n \r\n浆糊: 其实可以先分开做。然后整合。 \r\n \r\n一起去听海对brokendoor说: 数据库操作部分还需要什么? \r\n \r\n浆糊: 只是在开发的过程中多想一些结合的方式 \r\n \r\n一起去听海对浆糊说: : 数据库操作部分还需要什么? \r\n \r\n浆糊: 你看了我的接口了吗、? \r\n \r\n一起去听海对浆糊说: 没呢? \r\n \r\n一起去听海对浆糊说: 等看了再找你。 \r\n \r\n浆糊: 其实数据库操作没有什么太多要做的 \r\n \r\n一起去听海对浆糊说: 就是。1.login 2.logout 3.select 4.update 够吗? \r\n \r\n浆糊: 我没有作这些。 \r\n \r\n一起去听海对浆糊说: 那你做什么了。 \r\n \r\n浆糊: 我只有一个 newConnection \r\n \r\n一起去听海对浆糊说: 哦。 \r\n \r\n浆糊: 其实那些操作封装起来也可以,不过没有太多的用处。 \r\n \r\n一起去听海对浆糊说: 呵 。。封起来还是方便一些 \r\n \r\n浆糊: 你看了我的那些类,我们再商量,我们不怕修改 \r\n \r\n一起去听海对浆糊说: 好的。。。XP 厉害。 \r\n \r\n浆糊: 呵呵。。。 \r\n \r\n一起去听海对浆糊说: 问 破门还有什么事。 \r\n \r\n浆糊: 你的项目什么时候能做出来? \r\n \r\nbrokendoor对浆糊说: 我同意你的观点,除了连接池必须封装,其他的问题不大。jdbc已经不错了 \r\n \r\n一起去听海对浆糊说: 你是说我的 文件流传吗? \r\n \r\n浆糊: 不是,是webpm的项目管理。 \r\n \r\n一起去听海对brokendoor说: 呵。。JDBC 的 ResultSet 接口 有点不方便啊。 \r\n \r\n一起去听海对浆糊说: 不知道 \r\n \r\n一起去听海对浆糊说: 注册先弄好。。 \r\n \r\n一起去听海对浆糊说: 然后开始那部分。 \r\n \r\n浆糊: 我这个星期把最新更新做上去,还有锁定。 \r\n \r\n浆糊: 注册什么时候? \r\n \r\nbrokendoor对浆糊说: 我们先弄好wiki,我可不希望在erptao讨论webpm,没劲 \r\n \r\n浆糊: 呵呵。。。是啊!!现在可以用了阿 :) \r\n \r\n一起去听海对浆糊说: 我今天下午要给老师干活,明天和他去交项目,明天晚上开始 弄。 \r\n \r\n浆糊: wiki的内容还是由破门来做。 \r\n \r\nbrokendoor对浆糊说: 没问题的。 \r\n\r\n一起去听海对浆糊说: 后天应该差不多。 \r\n \r\nbrokendoor对浆糊说: 那你要把数据库备份做好啊,不然有人捣乱的话,呵呵。:( \r\n \r\n浆糊: 好。 \r\n \r\n浆糊: 呵呵。。好的。就在我的机器上。erptao也没也出现这种可能 \r\n \r\n一起去听海对浆糊说: 你在你自己的机器上发布的吗? \r\n \r\n浆糊: 不是,数据库在我自己的机器上。 \r\n\r\nbrokendoor对浆糊说: 他们有人整过了,不过有备份恢复的 \r\n \r\n浆糊: 大家访问速度如何? \r\n \r\nbrokendoor对浆糊说: 不错 \r\n \r\n浆糊: 哦。 \r\n \r\n一起去听海对浆糊说: 很快。 \r\n \r\n浆糊: ok! \r\n \r\n一起去听海对浆糊说: 你的机器可以做 长期主机吗? \r\n \r\n浆糊: 你们谁做过mysql的备份? \r\n \r\n一起去听海对浆糊说: 第一次用MYSQL。 \r\n \r\n浆糊: 应该在一段时间内没有问题。 \r\n \r\n一起去听海对浆糊说: 好呵。。。你怎么不用 IIS+TOMCAT \r\n\r\n浆糊: use linux \r\n \r\n一起去听海对浆糊说: 哦。。 \r\n \r\n一起去听海对brokendoor说: linux 应该弄一下了???? \r\n \r\nbrokendoor对一起去听海说: 这个没问题的,用用就知道了。资料很多 \r\n \r\n一起去听海对brokendoor说: 哦。在 LINUX上有什么 WEB SERVER \r\n\r\nbrokendoor对浆糊说: 你把 jwiki/index.jsp 重定向到 \"jwiki.jsp?主页\" 吧. \r\n \r\n浆糊: 好的。没有问题。 \r\n \r\nbrokendoor对浆糊说: 我们的jwiki呵 \r\n\r\n一起去听海对brokendoor说: 格式规则》???????? \r\n \r\n一起去听海对brokendoor说: 没弄出来吗???????? \r\n \r\nbrokendoor对浆糊说: 没有 \r\n\r\nbrokendoor对浆糊说: 我明天会开始建内容。:) 下午要出差。 \r\n\r\nbrokendoor: 有问题,e-mail 联系吧。用 webpm@topica.com. \r\n \r\n浆糊: 大家还有问题吗? \r\n\r\nbrokendoor对浆糊说: 吃饭去了 \r\n \r\n---------\r\n分类: [WebPM] | [WebPM 小组会议]','BrokenDoor','2002-01-31 15:46:54','2002-01-31 15:46:54',0,'N/A',82),('sdddd','Nothing','N/A','2002-00-21 17:15:36','2002-00-21 17:15:36',0,'N/A',13),('ssss','sdf sdf','N/A','2002-00-21 14:06:33','2002-00-21 14:06:33',0,'N/A',14),('WiKi','什么是WiKi?\r\n又称作WiKiWiKiWeb, 是一种基于互联网络的协作创作系统。\r\n----\r\n2002','N/A','2002-02-20 20:55:02','2002-02-20 20:55:02',0,'202.105.101.188',15),('一试身手','[color=red]test[/color]\r\n =*大赛非国大非国大----=\r\n 特色他\r\n---- \r\n*test\r\n**特色1\r\n*yery\r\nhttp://softme.org\r\n http://softme.org\r\n\n----\n2002-8-30 14:55:25 [brokendoor]\n特色他\n----\n2002-10-3 21:3:34 [test1]\nsdafsdfsadfadsfadsf',NULL,'2002-02-22 11:22:28','2002-10-03 21:03:34',0,'test1',16),('JWiki v1.2.2','这里是 JWiki v1.2.2 版本说明\r\n','brokendoor','2002-08-21 00:10:23','2002-08-21 00:10:23',0,'brokendoor',216),('test1','xdfsd','test1','2002-10-03 21:04:37','2002-10-03 21:04:37',0,'test1',217),('主题分类','* [WebPM]计划\r\n* [Delphi]\r\n\r\n* [JAVA 技术][no] [/no]* [SVG]\r\n\r\n* [自由软件][no] [/no]* [developer] \r\n\r\n* [工作流][no] [/no]* [AOP] \r\n\r\n* [设计模式][no] [/no]* WebService\r\n\r\n* [随便聊聊][no] [/no]* [JDO]\r\n\r\n* [软件工程][no] [/no]* [lua]\r\n\r\n* [连接池][no] [/no]* []\r\n','N/A','2002-02-07 01:12:53','2002-08-20 12:01:22',0,'brokendoor',17),('webpm_wiki 讨论区','在这里讨论 [webpm_wiki] 子项目的相关问题!\r\n----\r\n先把标记得使用说明写好吧,我把最近更新尽快做好。 -浆糊 2002-01-21\r\n----\r\n就这样随便更改吗? \r\n -- 这就是自由,不过还请你尊重别人的自由。看看[文件格式化规则]里的建议吧。- BrokenDoor 2002/1/22\r\n----\r\n代码段的设计不错,但我觉得其他的标记太复杂,类似html语法。如果能使用缺省,通用的wiki标记更好 --[kert]\r\n--[浆糊]已经增加了部分通用的wiki标记,其他标记会陆续实现。- BrokenDoor 2002/1/23\r\n----\r\n管理程序中可以增加一个删除帖子的功能,可以定期整理一些没有的文章。删除文章自动备份到备份库,然后删除主库的文章信息。 - BrokenDoor 2002/1/24\r\n----\r\n加个右对齐标记吧,应该比较方便的。 - BrokenDoor 2002/1/24\r\n----\r\n最紧要任务是加个Preview,免得搞不懂的时候改来改去,增加不必要的信息。\r\n另一个就是能不能加上个不改动超文本原样输出的标记,例如, 不要加太多的标记了,要不就不是wiki了 - bugn 2001/1/24\r\n\r\n试试了,[浆糊] [蓝星]\r\n这次我在试试!\r\n----\r\n网站构思很好:),但是还有一些问题,见[haha]\r\n----\r\n分类:[WebPM]\r\n参考:[WebPMAndWiki]','N/A','2002-02-22 10:47:26','2002-03-01 18:36:43',0,'haha12',18),('签名簿','*破门,BrokenDoor, 看来我还是第一个。 - 2002/1/21\r\n\r\n*[浆糊],哈哈~~,我是第二个. -2002/1/21\r\n\r\n*kangsh -2002/1/21\r\n\r\n*[hbworld] 本来是昨天就来了 --2002/1/22\r\n\r\n*[bugn] - 2002/1/23\r\n\r\nbugn有个问题,能否先把webpm的copyright和license明确写出来,不要就干写个copyleft,可能很多人搞不明白。另外就是webpm我觉得务必要支持多语言才好,一开始就做进去。\r\n--我也搞不懂啊?所以只好先CopyLeft了,反正开放源码是肯定了,最终选择合适的版权协议还要经过大家讨论。 - BrokenDoor - 2002/1/24\r\n\r\n*luodi --2002/1/23\r\n\r\n*踏冰,我来晚了,呵。。。555555555555 。。。\r\n\r\n*铁马踏着冰,也来了! -2002/1/23\r\n\r\n*yanfeng -2002/1/24\r\n来晚了。哈哈\r\n----\r\n*[蚂蚁]* 呵呵~~ 来了 -、2002-1-26\r\n*[qzhl(灌篮高手)]\r\n*[宗子昱]我下次会常常来看看,这个自由的地方\r\n*Wader -- 2002-01-30\r\n[notyy]我也来了\r\n[takaka]来了有几天了,现在才发现要签到。:-(\r\n\r\n*bluestar--[蓝星]* 真让我没有Face,找了半天的Door,竟然不能In,即使我再Clever,也被你[浆糊]搞Faint\r\n\r\n我登录了,看看效果怎么样,^_^\r\n\r\n\r\n[扫地的癞蛤蟆]呵呵,兄弟门,偶也来参加[email=ymruan@163.net]联系我[/email]\r\n\r\n我来了,[haha]\r\n* 蚂蚁改名[scaler]2002-3-1[错误报告][scaler]。 [为什么]我的名字没连接[email=scaler_w@sina.com]联系我[/email]','N/A','2002-02-22 11:39:21','2002-03-12 09:30:08',0,'scaler',19),('Topic','Body','Author','2002-00-22 00:18:52','2002-00-22 00:18:52',0,'N/A',20),('TestTopic','TestNewBody','TestAuthor','2002-01-23 09:33:11','2002-01-23 09:33:11',0,'N/A',21),('错误报告','请大家多提问题,意见和建议请到[webpm_wiki 讨论区]。\r\n----\r\n*需要提供列表标记 --[浆糊] 2002/03/06\r\n\'\'\'bug:关键字不能包含英文的“:”,比如[no][中文:标题dd][/no]。请大家注意!\'\'\' BrokenDoor 2002-3-4\r\n----\r\n*如果中文连接中间包含英文wiki名,会出现错误。\r\n这里是例子: [webpm 与 SourceForge 的异同] \r\n这个问题是这样,为了考虑在使用的时候不至于太混乱,在[]标记中不允许出现wiki代码-浆糊 2002-1-28\r\n现在地解决办法是这样:[]标记得优先级高于英文大写的自动连接。例如 [MyTestAnd]\r\n----\r\n*
标记转换请不要包含
。 \r\n这个问题已经解决 -浆糊 2002-1-22\r\n----\r\n*英文标记,自动连接不能区分大小写。\r\n请看:WikiWikiWeb\r\n这个问题已经解决 -浆糊 2002-1-23\r\n----\r\n*标记中的空格应该转换成html显示,以保持代码结构 -- BrokenDoor 2002/1/22\r\ncode标记我们将采用特殊的解决方式,力争支持彩色代码 --浆糊 2002/01/28\r\n----\r\n2002-00-21 22:03:33 \r\n月份忘了加1了 [hbworld] 2002/1/22\r\n这个问题已经解决 -浆糊 2002-1-22\r\n----\r\n中英文混合\'\'\'有空格\'\'\'的关键字找不到。- [webpm 规格说明书] - BrokenDoor 2002/1/22\r\n这个问题已经解决 -浆糊 2002-1-22\r\n----\r\n能否增加自动url转换? http://www.softme.org --BrokenDoor 2001/1/23\r\n这个我已经考虑过了,但是要有一些核心代码的变化,所以我想放一放 -浆糊 2002-1-23\r\n此功能用[|]标记代替 浆糊 2002-1-28\r\n\r\n----\r\n中文问题的确不是很好解决,就tomcat4 和tomcat3.2的处理又是不一样。看来要花挺多的时间来弄这个问题。\r\n-----\r\n系统时间好象不准 -takaka 2002.1.30\r\n----\r\n如果页面中一个链接内存在尖括号,比如[test<>],而且这个链接对应的那个文件在wiki内存在,这时系统将不能正确显示该标题。这是我昨天遇到过的问题,现在才解决,我也在做一个wiki,但功能不如你们的全。\r\n---\'\'回复:谢谢你指出这个问题,很快能解决的.你能留下联系方式吗? --浆糊 2002/02/08\'\'\r\n\r\n修改用户信息时出现目录列表\r\nDirectory Listing For /user/ \r\n---\'\'??不会的阿\'\' 浆糊 \'\'\'已修订\'\'\' BrokenDoor 2002/2/26\r\n\r\n----\r\n现在v1.1在我这里已经可以用了,但页头和页脚都是乱码[code]\r\n页头:English | ?ò?????? \r\n ×??á | ???? \r\n页脚:\r\n×??ó?ü???±??:2002-02-26 22:06:16 ×??ó??????:127.0.0.1 ???¨??:127.0.0.1 \r\n×??ó?????±??: [/code]A:你在什么平台上?添加文章和编辑文章有没有乱码? [浆糊]\r\n----\r\n关于最受欢迎页面,每次登陆都是JWikiWeb那个页面,当然是最受欢迎了!我觉得规则应该修改一下,起码有几个页面不在统计范围内.\r\nA: \'\'有道理,浆糊你考虑一下吧\'\' BrokenDoor\r\nA: \'\'我原先的考虑是可以顺便用来作为访问计数器,呵呵...如果那样的话,是不是别的页面也需要不进行统计?如果多的话,做个过滤器\'\' --[浆糊]\r\n\r\n\'\'\'用IE5.5和以上版本访问,出现乱码,request取得的参数乱了:)\'\'\'[扫地的癞蛤蟆]\r\n--原先考虑是进行URL编码的,但是后来看看没有问题也就没有做.而且编码的时候还要进行中文处理,这个放到下个版本的故事里吧. [浆糊]\r\n\'\'\'非常的对不起,刚才偶写的那个bug不是问题了!问题出在我们这里,主要其他几个同事用的机器设置了代理,而代理又是自己写的一个小程序,写的不好,导致了这个问题,我突然想到了这点,关掉了代理,搞定了,哎,刚才想了半天,还以为是resin的bug呢,把resin的辕马都down下来看了。呵呵,真是不好意思啊!\'\'\'\r\n\r\n----\r\n\'\'\'看了一下源码,好象是用Connection conn=DBConnection.newInstance()建立连接的,如果为个登录的用户都建立数据库连接,系统开销会很大的,建议重构时考虑使用[ConnectionPool]类。\'\'\'[takaka]\r\n--原先是考虑过的,但是为了进度,也没有去用.不过我们可以进行重构.先考虑JDO,Pool也肯定要加入的.就是看如何加了. 实在人员太少 :( 2002/02/28 --[浆糊]\r\n\r\n\'\'\'把jive里的ConnectionPool直接拿来用好了\'\'\'\r\n也可以,只要再包装一下,修改不会太大.\r\n\r\n----\r\n注册用户的页面中日期不能选择12月和31日 --[hdw1978] \'\'\'已修订\'\'\'\r\n----\r\n是不是还不能画表格? --[takaka]\r\n----\r\n两张一样的图,第一张不能显示\r\n\'\'\'A:img标签中间不能使用回车\'\'\'\r\n\'\'我知道不能用回车啊,只是想知道算不算BUG\'\'\r\n第一张[img]http://www-900.ibm.com/developerWorks/education/xml/transforming-xml/xmltosvg/piechart.jpg\r\n[/img]第二张[img]http://www-900.ibm.com/developerWorks/education/xml/transforming-xml/xmltosvg/piechart.jpg[/img]\r\n----\r\n----\r\n糨糊怎么搞的,我改写的 连接池 怎么没弄上,什么原因。[踏冰]\r\nA:踏冰,实在对不起阿,我最近一点时间也没有,实在人手太少了. [浆糊]\r\n----\r\n项目注册不好用 [踏冰]\r\n----\r\n','N/A','2002-02-09 00:56:29','2002-08-26 15:45:32',0,'brokendoor',22),('我要加入','\'\'\'目前WebPM 开发成员:\'\'\'\r\n BrokenDoor - \'\'\'QQ:16048561\'\'\' [破门的邮箱|mailto:brokendoor@sina.com]\r\n [浆糊] \'\'\'QQ :3413384\'\'\' [email=java_cn@21cn.com]浆糊的邮箱[/email]\r\n [踏冰]\r\n [takaka] [email=takaka@163.net]takaka的邮箱[/email]\r\n [扫地的癞蛤蟆] [email=ymruan@sina.com]ymruan的邮箱[/email] \r\n ----[加入邮件列表|http://brokendoor.myetang.com/] \r\n----\r\n\'\'申请加入者,请在此处输入您自己的介绍\'\'\r\n [qzhl(灌篮高手)]\r\n [hbworld]\r\n [zwhhoo]\r\n [冬儿哥哥]\r\n [铁马]\r\n [87ZD]\r\n [letdo]\r\n [有你可思] [email=apache1493@21cn.com]有你可思的邮箱[/email]\r\n ----\r\n分类: [WebPM]',NULL,'2002-02-20 22:28:05','2002-03-06 11:17:40',0,'浆糊',23),('软件工程','这里是软件工程专栏:\r\n\r\n* [极端编程] - eXtreme Programming\r\n\r\n* [敏捷软件开发联盟] - Agile Software Development Alliance\r\n\r\n----\r\n[业务分析指南]\r\n----\r\n分类:[主题分类]','N/A','2002-01-24 21:37:29','2002-02-26 23:33:25',0,'浆糊',24),('敏捷软件开发联盟','2001年2月的美国犹他州,在17个业界的知名人士努力下,敏捷软件开发联盟(Agile Software Development Alliance)成立了。在这之前,联盟的成员们做了很多的工作,知名的XP方法就是众多Agile方法论中的一种。最早,Alistair Cockburn是用“light”一词来区别新型方法和传统方法的不同,而在这一次的会议上,Agile一词最终被确定为新方法学的名称。\r\n\r\n请看:[url=http://www.agilechina.org]http://www.agilechina.org/[/url]\r\n\r\n----\r\n分类:[软件工程]','N/A','2002-01-23 14:19:15','2002-01-23 14:19:15',0,'N/A',25),('h1','dfsgdfdfgsdfgdfg','N/A','2002-00-22 10:49:41','2002-00-22 10:49:41',0,'N/A',26),('自由软件开发','这里是自由软件开发如何利用软件工程成果的讨论:\r\n\r\n\'\'\'经典文章\'\'\'\r\n* [大教堂与市集]\r\n\r\n\'\'\'推荐好文\'\'\'\r\n* [自由软件开发讨论] - 转自[url=http://cosoft.org.cn]共创软件联盟[/url]自由软件工程讨论论坛\r\n\r\n* [自由软件及其在我国的发展]\r\n--- 转自 [url=http://aka.org.cn]AKA[/url]的杂志第二期[url=http://aka.org.cn/Magazine/Aka2/cover.html]软件工程[/url]\r\n\r\n*[Open Source 的开发模式探讨] - 转自[共创软件联盟|http://cosoft.org.cn]\r\n----\r\n分类:[自由软件]\r\n','N/A','2002-02-20 15:03:30','2002-02-20 15:03:30',0,'192.168.1.228',27),('大教堂与市集',' 自由软件工程讨论 \r\n\r\n主题: 大教堂与市集 \r\n\r\n说明: \r\n本文的作者Eric Raymond是Open Source Software领域的领袖,这方面许多 \r\n新的思想正是从他那儿产生的,同时他也是UNIX上最流行的Email软件Fetchmail \r\n的作者。 \r\n下面这篇文章有点儿长,然而它是值得你去耐心把它读完的。文章以Fetchmail \r\n为例,讨论了Internet上集市风格的开发方式。 \r\n我们应该感谢HansB,是他把这篇长文章翻译成了中文。 \r\nEric的主页地址在:http://www.tuxedo.org/~esr/ \r\n\r\n------------------------------------------------------------------------- \r\n\r\n一. 大教堂和市集 \r\n\r\n  Linux的影响是非常巨大的。甚至在5年以前,有谁能够想象一个世界级的操 \r\n作系统能够仅仅用细细的Internet连接起来的散布在全球的几千个开发人员有以业 \r\n余时间来创造呢? \r\n我当然不会这么想。在1993年早期我开始注意Linux时,我已经参与Unix \r\n和自由软件开发达十年之久了。我是八十年代中期GNU最早的几个参与者之一。我 \r\n已经在网上发布了大量的自由软件,开发和协助开发了几个至今仍在广泛使用的 \r\n程序(Nethack,Emacs VC和GND模式,xlife等等)。我想我知道该怎样做。 \r\n\r\n  Linux推翻了许多我认为自己明白的事情。我已经宣扬小工具、快速原型和演 \r\n进式开发的Unix福音多年了。但是我也相信某些重要的复杂的事情需要更集中化的, \r\n严密的方法。我相信多数重要的软件(操作系统和象Emacs一样的真正大型的工具) \r\n需要向建造大教堂一样来开发,需要一群于世隔绝的奇才的细心工作,在成功之前 \r\n没有beta版的发布。 \r\nLinus Torvalds的开发风格(尽早尽多的发布,委托所有可以委托的事,对所 \r\n有的改动和融合开放)令人惊奇的降临了。这里没有安静的、虔诚的大教堂的建造 \r\n工作——相反,Linux团体看起来像一个巨大的有各种不同议程和方法的乱哄哄的 \r\n集市(Linux归档站点接受任何人的建议和作品,并聪明的加以管理),一个一致 \r\n而稳定的系统就象奇迹一般从这个集市中产生了。 \r\n\r\n  这种设计风格确实能工作,并且工作得很好,这个事实确实是一个冲击。在我 \r\n的研究过程中,我不仅在单个工程中努力工作,而且试图理解为什么Linux世界不 \r\n仅没有在一片混乱中分崩离析,反而以大教堂建造者们不可想象的速度变得越来越 \r\n强大。 \r\n\r\n  到了1996年中,我想我开始理解了。我有一个极好的测试我的理论的机会, \r\n以一个自由软件计划的形式,我有意识的是用了市集风格。我这样做了,并取得了 \r\n很大的成功。 \r\n\r\n在本文的余下部分,我将讲述这个计划的故事,我用它来明确一些自由软件高 \r\n效开发的格言。并不是所有这些都是从Linux世界中学到的,但我们将看到Linux世 \r\n界给予了它们一个什么样的位置。如果我是正确的,它们将使你理解是什么使Linux \r\n团体成为好软件的源泉,帮助你变得更加高效。 \r\n\r\n二. 邮件必须得通过 \r\n\r\n  1993年以前我在一个小的免费访问的名为Chester County InterLink的ISP \r\n的做技术工作,它位于Pennsylvania的West Chester。(我协助建立了CCIL,并写了 \r\n我们独特的多用户BBS系统——你可以telnet到locke.ccil.org来检测一下。今天它 \r\n在十九条线上支持三千的用户)。这个工作使我可以一天二十四小时通过CCIL的56K \r\n专线连在网上,实际上,它要求我这么做! \r\n\r\n  所以,我对Internet email很熟悉。因为复杂的原因,很难在我家里的机器 \r\n(snark.thyrsus.com)和CCIL之间用SLIP工作。最后我终于成功了,但我发现不 \r\n得不时常telnet到locke来检查我的邮件,这真是太烦了。我所需要的是我的邮件 \r\n发送到snark,这样biff(1)会在它到达时通知我。 \r\n\r\n  简单地sendmail的转送功能是不够的,因为snark并不是总在网上而且没有一 \r\n个静态地址。我需要一个程序通过我的SLIP连接把我的本地发送的邮件拉过来。 \r\n我知道这种东西是存在的,它们大多使用一个简单的协议POP(Post Office \r\nProtocol)。而且,locke的BSD/OS操作系统已经自带了一个POP3服务器。 \r\n\r\n  我需要一个POP3客户。所以我到网上去找到了一个。实际上,我发现了三、 \r\n四个。我用了一会pop-perl,但它却少一个明显的特征:抽取收到的邮件的地址 \r\n以便正确回复。 \r\n\r\n  问题是这样的:假设locke上一个叫“joe”的人向我发了一封邮件。如果我 \r\n把它取到snark上准备回复时,我的邮件程序会很高兴地把它发送给一个不存在的 \r\nsnark上的“joe”。手工的在地址上加上“@ccil.org”变成了一个严酷的痛苦。 \r\n\r\n  这显然应是计算机替我做的事。(实际上,依据RFC1123的5.2.18节, \r\nsendmail应该做这件事)。但是没有一个现存的POP客户知道怎样做!于是这就给 \r\n我们上了第一课: \r\n  1.每个好的软件工作都开始于搔到了开发者本人的痒处。 \r\n也许这应该是显而易见的(“需要是发明之母”长久以来就被证明是正确的), \r\n但是软件开发人员常常把他们的精力放在它们既不需要也不喜欢的程序,但在 \r\nLinux世界中却不是这样——这解释了为什么从Linux团体中产生的软件质量都如 \r\n此之高。 \r\n\r\n  那么,我是否立即投入疯狂的工作中,要编出一个新的POP3客户与现存的那 \r\n些竞争呢?才不是哪!我仔细考察了手头上的POP工具,问自己“那一个最接近我 \r\n的需要?”因为: \r\n  2.好程序员知道该写什么,伟大的程序员知道该重写(和重用)什么。 \r\n\r\n  我并没有声称自己是一个伟大的程序员,可是我试着效仿他们。伟大程序员 \r\n的一个重要特点是建设性的懒惰。他们知道你是因为成绩而不是努力得到奖赏, \r\n而且从一个好的实际的解决方案开始总是要比从头干起容易。 \r\n\r\n  例如,Linux并不是从头开始写Linux的。相反的它从重用Minix(一个386机 \r\n型上的类似Unix的微型操作系统)的代码和思想入手。最后所有的Minix代码都消 \r\n失或被彻底的重写了,但是当它们在的时候它为最终成为Linux的雏形做了铺垫。 \r\n\r\n  秉承同样的精神,我去寻找良好编码的现成的POP工具,用来作为基础。 \r\n\r\n  Unix世界中的代码共享传统一直对代码重用很友好(这正是为什么GNU计划不 \r\n管Unix本身有多么保守而选取它作为基础操作系统的原因)。Linux世界把这个传 \r\n统推向技术极限:它有几个T字节的源代码可以用。所以在Linux世界中花时间寻 \r\n找其他几乎足够好的东西,会比在别处带来更好的结果。 \r\n\r\n  这也适合我。加上我先前发现的,第二次寻找找到了9个候选者——fetchPOP \r\n,PopTart,get-mail,gwpop,pimp,pop-perl,popc,popmail 和 upop)。我 \r\n首先选定的是“fetchpop”。我加入了头标重写功能,并且做了一些被作者加入 \r\n他的1.9版中的改进。 \r\n\r\n  但是几个星期之后,我偶然发现了Carl Harris写的“popclient”的代码, \r\n然后发现有个问题,虽然fetchpop有一些好的原始思想(比如它的守护进程模式), \r\n它只能处理pop3,而且编码的水平相当业余(Seung-Hong是个很聪明但是经验不足 \r\n的程序员),Carl的代码更好一些,相当专业和稳固,但他的程序缺少几个重要的 \r\n相当容易实现的fetchpop的特征(包括我自己写的那些)。 \r\n\r\n  继续呢还是换一个? 如果换一个的话,作为得到一个更好开发基础的代价, \r\n我就要扔掉我已经有的那些代码。 \r\n\r\n  换一个的一个实际的动机是支持多协议,pop3是用的最广的邮局协议,但并 \r\n非唯一一个,Fetchpop和其余几个没有实现POP2.RPOP,或者APOP,而且我还有一 \r\n个为了兴趣加入IMAP(Internet Message Access Protocol,最近设计的最强大的 \r\n邮局协议)的模糊想法。 \r\n\r\n  但是我有一个更加理论化的原因认为换一下会是一个好主意,这是我在Linux \r\n很久以前学到的: \r\n 3.“计划好抛弃,无论如何,你会的”(Fred Brooks,《神秘的人月》第11章) \r\n\r\n  或者换句话说,你常常在第一次实现一个解决方案之后才能理解问题所在, \r\n第二次你也许才足够清楚怎样做好它,因此如果你想做好,准备好推翻重来至少 \r\n一次。 \r\n\r\n  好吧(我告诉自己),对fetchpop的尝试是我第一次的尝试,因此我换了一下。 \r\n\r\n  当我在1996年6月25日把我第一套popclient的补丁程序寄给Carl Harris之 \r\n后,我发现一段时间以前他已经对popclient基本上失去了兴趣,这些代码有些陈 \r\n旧,有一些次要的错误,我有许多修改要做,我们很快达成一致,我来接手这个 \r\n程序。不知不觉的,这个计划扩大了,再也不是我原先打算的在已有的pop客户上 \r\n加几个次要的补丁而已了,我得维护整个的工程,而且我脑袋里涌动着一些念头 \r\n要引起一个大的变化。 \r\n\r\n  在一个鼓励代码共享的软件文化里,这是一个工程进化的自然道路,我要指 \r\n出: \r\n 4. 如果你有正确的态度,有趣的问题会找上你的,但是Carl Harris的态度甚 \r\n至更加重要,他理解: \r\n 5.当你对一个程序失去兴趣时,你最后的责任就是把它传给一个能干的后继者。 \r\n\r\n  甚至没有商量,Carl和我知道我们有一个共同目标就是找到最好的解决方 \r\n案,对我们来说唯一的问题是我能否证明我有一双坚强的手,他优雅而快速的写 \r\n出了程序,我希望轮到我时我也能做到。 \r\n\r\n三. 拥有用户的重要性 \r\n\r\n  于是我继承了popclient,同样重要的是,我继承了popclient的用户基础, \r\n用户是你所拥有的极好的东西,不仅仅是因为他们显示了你正在满足需要,你做 \r\n了正确的事情,如果加以适当的培养,他们可以成为合作开发者。 \r\n\r\n  Unix传统另一有力之处是许多用户都是黑客,因为源优码是公开的,他们可 \r\n以成为高效的黑客,这一点在Linux世界中也被推向了令人高兴的极致,这对缩短 \r\n调试时间是极端重要的,在一点鼓励之下,你的用户会诊断问题,提出修订建 \r\n议,帮你以远比你期望快得多的速度的改进代码。 \r\n\r\n 6. 把用户当做协作开发者是快速改进代码和高效调试的无可争辩的方式。 \r\n\r\n  这种效果的力量很容易被低估,实际上,几乎所有我们自由软件世界中的人 \r\n都强烈低估了用户可以多么有效地对付系统复杂性,直到Linus让我们看到了这一 \r\n点。 \r\n\r\n  实际上,我认为Linus最聪明最了不起的工作不是创建了Linux内核本身,而 \r\n是发明了Linux开发模式,当我有一次当着他的面表达这种观点时,他微笑了一 \r\n下,重复了一句他经常说的话:“我基本上是一个懒惰的人,依靠他人的工作来 \r\n获取成绩。”象狐狸一样懒惰,或者如Robert Heinlein所说,太懒了而不会失 \r\n败。 \r\n\r\n  回顾起来,在GNU Emacs Lisp库和Lisp代码集中可以看到Linux方法的成功, \r\n与Emacs的C内核和许多其他FSF的工具相比,Lisp代码库的演化是流动性的和用户 \r\n驱动的,思想和原型在达到最终的稳定形式之前往往要重写三或四次,而且经常 \r\n利用Internet的松散合作。 \r\n\r\n  实际上,我自己在fetchmail之前最成功的作品要算Emacs VC模式,它是三个 \r\n其他的人通过电子邮件进行的类似Linux的合作,至今我只见过其中一个人 \r\n(Richard Stallman),它是SCCS、RCS和后来的CVS的前端,为Emacs提供“one- \r\ntouch”版本控制操作,它是从一个微型的、粗糙的别人写好的sccs.el模式开始 \r\n演化的,VC开发的成功不像Emacs本身,而是因为Emacs Lisp代码可以很快的通过 \r\n发布/测试/改进的过程。 \r\n\r\n  (FSF的试图把代码放入GPL之下的策略有一个未曾预料到的副作用,它让FSF \r\n难以采取市集模式,因为他们认为每个想贡献二十行以上代码的人都必须得到一 \r\n个授权,以使受到GPL的代码免受版权法的侵扰,具有BSD和MITX协会的授权的用 \r\n户不会有这个问题,因为他们并不试图保留那些会使人可能受到质询的权力)。 \r\n\r\n 四. 早发布、常发布 \r\n\r\n  尽量早尽量频繁的发布是Linux开发模式的一个重要部分,多数开发人员(包 \r\n括我)过去都相信这对大型工程来说是个不好的策略,因为早期版本都是些充满错 \r\n误的版本,而你不想耗光用户的耐心。 \r\n这种信仰强化了建造大教堂开发方式的必要性,如果目标是让用户尽可能少 \r\n的见到错误,那你怎能不会仅仅每六个月发布一次(或更不经常),而且在发布之 \r\n间象一只狗一样辛勤“捉虫”呢? Emacs C内核就是以这种方式开发的,Lisp库, \r\n实际上却相反,因为有一些有FSF控制之外的Lisp库,在那里你可以独立于Emacs \r\n发布周期地找寻新的和开发代码版本。 \r\n\r\n  这其中最重要的是Ohio州的elisp库,预示了今天的巨大的Linux库的许多特 \r\n征的精神,但是我们很少真正仔细考虑我们在做什么,或者这个库的存在指出了 \r\nFSF建造教堂式开发模式的什么问题,1992年我曾经做了一次严肃的尝试,想把 \r\nOhio的大量代码正式合并到Emacs的官方Lisp库中,结果我陷入了政治斗争中,彻 \r\n底失败了。 \r\n\r\n  但是一年之后,在Linux广泛应用之后,很清楚,一些不同的更加健康的东西 \r\n诞生了,Linus的开发模式正好与建造教堂方式相反,Sunsite和tsx-11的库开始 \r\n成长,推动了许多发布。所有这些都是闻所未闻的频繁的内核系统的发布所推动 \r\n的。 \r\n\r\n  Linus以所有实际可能的方式把它的用户作为协作开发人员。 \r\n\r\n 7. 早发布、常发布、听取客户的建议 \r\n  Linus的创新并不是这个(这在Unix世界中是一个长期传统),而是把它扩展到 \r\n和他所开发的东西的复杂程度相匹配的地步,在早期一天一次发布对他来说都不 \r\n是罕见的!而且因为他培育了他的协作开发者基础,比其他任何人更努力地充分利 \r\n用了Internet进行合作,所以这确实能行。 \r\n\r\n  但是它是怎样进行的呢?它是我能模仿的吗?还是这依赖于Linus的独特天才? \r\n\r\n  我不这样想,我承认Linus是一个极好的黑客(我们有多少人能够做出一个完 \r\n整的高质量的操作系统内核?),但是Linux并不是一个令人敬畏的概念上的飞跃, \r\nLinus不是(至少还不曾是)象Richard stallman或James Gosling一样的创新天 \r\n才,在我看来,Linus更象一个工程天才,具有避免错误和开发失败的第六感觉, \r\n掌握了发现从A点到B点代价最小的路径的决窍,确实,Linux的整个设计受益于这 \r\n个特质,并反映出Linus的本质上保守和简化设计的方法。 \r\n\r\n  如果快速的发布和充分利用Internet不是偶然而是Linus的对代价最小的路径 \r\n的洞察力的工程天才的内在部分,那么他极大增强了什么?他创建了什么样的方法? \r\n\r\n  问题回答了它自己,Linus保持他的黑客用户经常受到激励和奖赏:被行动的 \r\n自我满足的希望所激励,而奖赏则是经常(甚至每天)都看到工作在进步。 \r\n\r\n  Linus直接瞄准了争取最多的投入调试和开发的人时,甚至冒代码不稳定和一 \r\n旦有非常棘手的错误而失去用户基础的险,Linus似乎相信下面这个: \r\n 8. 如果有一个足够大的beta测试人员和协作开发人员的基础,几乎所有的问题 \r\n都可以被快速的找出并被一些人纠正。 \r\n\r\n  或者更不正式的讲:“如果有足够多的眼睛,所有的错误都是浅显的”(群众 \r\n的眼睛是雪亮的),我把这称为“Linus定律”。 \r\n\r\n  我最初的表述是每个问题“对某些人是透明的”,Linus反对说,理解和修订 \r\n问题的那个人不一定非是甚至往往不是首先发现它的人,“某个人发现了问题”, \r\n他说,“另一个理解它,我认为发现它是个更大的挑战”,但是要点是所有事都趋 \r\n向于迅速发生。 \r\n\r\n  我认为这是建造教堂和集市模式的核心区别,在建造教堂模式的编程模式看 \r\n来,错误和编程问题是狡猾的、阴险的、隐藏很深的现象,花费几个月的仔细检 \r\n查,也不能给你多大确保把它们都挑出来的信心,因此很长的发布周期,和在长 \r\n期等待之后并没有得到完美的版本发布所引起的失望都是不可避免的。 \r\n\r\n  以市集模式观点来看,在另一方面,我们认为错误是浅显的现象,或者至少 \r\n当暴露给上千个热切的协作开发人员,让他们来对每个新发布进行测试的时候, \r\n它们很快变得浅显了,所以我们经常发布来获得更多的更正,作为一个有益的副 \r\n作用,如果你偶尔做了一个笨拙的修改,也不会损失太多。也许我们本不应该这 \r\n样的惊奇,社会学家在几年前已经发现一群相同专业的(或相同无知的)观察者的 \r\n平均观点比在其中随机挑选一个来得更加可靠,他们称此为“Delhpi效应”, \r\nLinus所显示的证明在调试一个操作系统时它也适用——Delphi效应甚至可以战胜 \r\n操作系统内核一级的复杂度。 \r\n\r\n  我受Jeff Dutky (dutky @ wam.umd.edu)的启发指出Linus定律可以重新表述 \r\n为“调试可以并行”,Jeff观察到虽然调试工作需要调试人员和对应的开发人员 \r\n相交流,但它不需要在调试人员之间进行大量的协调,于是它就没有陷入开发时 \r\n遇到的平方复杂度和管理开销。 \r\n在实际中,由于重复劳动而导致的理论上的丧失效率的现象在Linux世界中并 \r\n不是一个大问题,“早发布、常发布策略”的一个效果就是利用快速的传播反馈 \r\n修订来使重复劳动达到最小。 \r\n\r\n  Brooks甚至做了一个与Jeff相关的更精确的观察:“维护一个广泛使用的程 \r\n序的成本一般是其开发成本的40%,奇怪的是这个成本受到用户个数的强烈影响, \r\n更多的用户发现更多的错误”(我的强调)。 \r\n更多的用户发现更多的错误是因为更多的用户提供了更多测试程序的方法, \r\n当用户是协作开发人员时这个效果被放大了,每个找寻错误的人都有自己稍微不 \r\n同的感觉和分析工具,从不同角度来看待问题。“Delphi效应”似乎因为这个变 \r\n体工作变得更加精确,在调试的情况下,这个变体同时减小了重复劳动。 \r\n\r\n  所以加入更多的beta测试人员虽不能从开发人员的P.O.V中减小“最深”的错 \r\n误的复杂度,但是它增加了这样一种可能性,即某个人的工具和问题正好匹配, \r\n而这个错误对这个人来说是浅显的。 \r\n\r\n  Linus也做了一些改进,如果有一些严重的错误,Linux内核的版本在编号上 \r\n做了些处理,让用户可以自己选择是运行上一个“稳定”的版本,还是冒遇到错 \r\n误的险而得到新特征,这个战略还没被大多数Linux黑客所仿效,但它应该被仿 \r\n效,存在两个选择的事实让二者都很吸引 人。 \r\n   \r\n五. 什么时候玫瑰不是玫瑰? \r\n\r\n  在研究了Linus的行为和形成了为什么它成功的理论之后,我决定在我的工程 \r\n(显然没有那么复杂和雄心勃勃)里有意识的测试这个理论。 \r\n但我首先做的事是熟悉和简化Popclient。 Carl Harris的实现非常好,但是 \r\n有一种对许多C程序来说没有必要的复杂性。他把代码当作核心而把数据结构当作 \r\n对代码的支持,结果是代码非常漂亮但是数据结构设计得很特别,相当丑陋(至少 \r\n对以这个老LISP黑客的标准来看),然而除了提高代码和数据结构设计之外,重写 \r\n它还有一个目的,就是要把它演化为我彻底理解的东西,对修改你不理解的程序 \r\n中的错误负责可不是一件有趣的事。 \r\n\r\n  第一个月我只是在领会Carl\'s的基本设计的含义,我所做的第一个重大修改 \r\n是加入了IMAP支持,我把协议机重新组织为一个通用驱动程序和三个方法表(对应 \r\nPOP2、POP3和IMAP),这个前面的修改指出一个需要程序员(特别是象C这种没有自 \r\n然的动态类型支持的语言)记在脑中的一般原理: \r\n\r\n 9. 聪明的数据结构和笨拙的代码要比相反的搭配工作的更好 \r\n\r\n  Fred Brooks也在他第11章中讲道:“让我看你的[代码],把你的[数据结 \r\n构]隐藏起来,我还是会迷惑;让我看看你的[数据结构],那我就不需要你的[代 \r\n码]了,它是显而易见的”。 \r\n\r\n  实际上,他说的是“流程图”和“表”,但是在三十年的术语/文化演进之 \r\n后,事情还是一样的。 \r\n\r\n  此时(1996年9月初,在从零开始六个月后),我开始想接下来修改名字——毕 \r\n竟,它已不仅仅是一个POP客户,但我犹豫了,因为还没有什么新的漂亮设计呢, \r\n我的popclient版本需要有自己的特色。 \r\n\r\n  当fetehmail学会怎样把取到的邮件转送到SMTP端口时,事情就完全改变了, \r\n但是首先:上面我说过我决定使用这个工程来测试我关于Linus Torualds所做的 \r\n行为的理论,(你可能会问)我怎样做到这点呢? 以下面的方式: \r\n\r\n 1. 我尽早尽量频繁的发布(几乎从未少于每十天发布一次;在密集开发的时候 \r\n是每天一次)。 \r\n\r\n 2. 我把每一个和我讨论fetchmail的人加入一个beta表中。 \r\n\r\n 3. 每当我发布我都向beta表中的人发出通告,鼓励人们参与。 \r\n\r\n 4. 我听取beta测试员的意见,向他们询问设计决策,对他们寄来的补丁和反馈 \r\n表示感谢。 \r\n\r\n  这些简单的手段立即收到的回报,在工程的开始,我收到了一些错误报告, \r\n其质量足以使开发者因此被杀掉,而且经常还附有补丁、我得到了理智的批评, \r\n有趣的邮件,和聪明的特征建议,这导致了: \r\n\r\n 10. 如果你象对待最宝贵的资源一样对待你的beta测试员,他们就会成为你最 \r\n宝贵的资源。 \r\n\r\n六. popclient变成了Fetchmail \r\n\r\n  这个工程的真正转折点是Harry Hochleiser寄给我他写的代码草稿,他把邮 \r\n件转发到客户端机器的SMTP端口,我立即意识到这个特征的可靠实现将淘汰所有 \r\n其他的递送模式。 \r\n\r\n  几个星期以来我一直在修改而不是改进fetchmail,因为我觉得界面设计虽然 \r\n有用但是太笨拙琐碎了,到处充满了太多的粗陋的细小选项。 \r\n\r\n  当我思考SMTP转发时我发现popclient试图做的事太多了,它被设计成既是一 \r\n个邮件传输代理(MTA)也是一个本地递送代理(MDA)。使用SMTP转发,它就可以从 \r\nMDA的事务中解脱出来而成为一个纯MTA,而象sendmail一样把邮件交给本地递送 \r\n程序来处理。 \r\n\r\n  既然端口25在所有支撑TCP/IP的平台上早已被预留,为什么还要为一个邮件 \r\n传输代理的配置或为一个邮箱设置加锁的附加功能而操心呢?尤其是当这意味着抽 \r\n取的邮件就象一个正常的发送者发出的SMTP邮件一样,而这就是我们需要的。 \r\n\r\n  这里有几个教益:第一,SMTP转发的想法是我有意识地模拟Linus的方法以来 \r\n的最大的单个回报,一个用户告诉我这个非同寻常的想法——我所需做的只是理 \r\n解它的含义。 \r\n\r\n 11. 想出好主意是好事,从你的用户那里发现好主意也是好事,有时候后者更 \r\n好。 \r\n\r\n  很有趣的是,你很快将发现,如果你完全承认你从其他人那里得到多少教益 \r\n的话,整个世界将会认为所有的发明都是你做出的,而你会对你的天才变得谦 \r\n虚。我们可以看到这在Linus身上体现得多明显!(当我在1997年8月的Perl会议上 \r\n发表这个论文时,Larry Wall坐在前排,当我讲到上面的观点时,他激动的叫了 \r\n出来:“对了!说对了!哥们!”所有的听众都哄堂大笑起来,因为他们知道同样的 \r\n事情也发生在Perl的发明者身上)。 \r\n\r\n  于是在同样精神指导下工程进行了几个星期,我开始不光从我的用户那儿也 \r\n从听说我的系统的人那儿得到类似的赞扬,我把一些这种邮件收藏起来,我将在 \r\n我开始怀疑自己的生命是否有价值时重新读读这些信。:) \r\n\r\n  但是有两个更基本的,非政治性的对所有设计都有普遍意义的教益。 \r\n\r\n 12. 最重要和最有创新的解决方案常常来自于你认识到你对问题的概念是错误 \r\n的。 \r\n\r\n  一个衡量fetchmail成功的有趣方式是工程的beta测试人员表(fegtchmail的 \r\n朋友们)的长度,在创立它的时候已经有249个成员了,而且每个星期增加两到三 \r\n个。 \r\n\r\n  实际上,当我在1997年5月校订它时,这张表开始因为一个有趣的原因而缩短 \r\n了,有几个人请求我把他们从表中去掉,因为fetchmail已经工作的如此之好,他 \r\n们不需要看到这些邮件了!也许这是一个成熟的市集风格工程的生命周期的一部分。 \r\n\r\n  我以前一直在解决错误的问题,把popclient当作MTA和具有许多本地递送模 \r\n式的MDA的结合物,Fetchmail的设计需要从头考虑为一个纯的MTA,做为一个普通 \r\nInternet邮件路径的一部分。 \r\n\r\n  当你在开发中碰了壁时(当你发现自己很难想通下一步时),那通常不是要问 \r\n自己是否找到正确答案,而是要问是否问了正确问题,也许需要重新构造问题。 \r\n\r\n  于是,我重新构造了我的问题,很清楚,要做的正确的事是(1)把SMTP转发支 \r\n持放在通用驱动程序中,(2)把它做为缺省模式,(3)最终分离所有其他的递送模 \r\n式,尤其是递送到文件和标准输出的选项。 \r\n\r\n  我在第三步上犹豫了一下,担心会让popdiant的长期用户对新的递送方法感 \r\n到烦心,在理论上,他们可以立即转而转发文件或者他们的非sendmail等价物来 \r\n得到同样的效果,在实际中这种转换可能会很麻烦。 \r\n但是当我这么做之后,证明好处是巨大的,驱动程序代码的冗余的部分消失 \r\n了,配置完全变得简单了——不用屈从于系统MDA和用户的邮箱,也不用为下层 \r\nOS是否支持文件锁定而担心了。 \r\n\r\n  而且,丢失邮件的唯一漏洞也被堵死了,如果你选择了递送到一个文件而磁 \r\n盘已满,你的邮件就会丢失,这在SMTP转发中不会发生,因为SMTP侦听器不会返 \r\n回OK的,除非邮件可以递送成功或至少被缓冲留待以后递送。 \r\n\r\n  还有,性能也改善了(虽然在单次执行中你不会注意到),这个修改的另一个 \r\n不可忽视的好处是手册变得大大简单了。 \r\n\r\n  后来,为了允许处理一些罕见的情况,包括动态SLIP,我必须回到让用户定 \r\n义本地MDA递送上来,但是我发现了一个更加简单的方法。 \r\n\r\n  所有这些给了我们什么启发呢?如果可以不损失效率,就要毫不犹豫抛弃陈旧 \r\n的特性,Antonine de Saint-Exupery(在他成为经典儿童书籍作家之前是一个飞 \r\n行员和飞机设计师)曾说过: \r\n\r\n 13. “最好的设计不是再也没有什么东西可以添加了,而是再也没有什么东西 \r\n可以去掉。” \r\n\r\n  当你的代码变得更好和更简单时,这就是你知道它是正确的时候了,而且在 \r\n这个过程中,fetehmail的设计具有了自己的特点,而区别于其前身popclient。 \r\n\r\n  现在是改名的时候了,这个新的设计看起来比老popclient更象一个sendmail \r\n的复制品,它们都是MTA,但是Senmail是推然后递送,而新的popclient是拉然后 \r\n递送。于是,在两个月之后,我把它重新命名为fetehmail。 \r\n\r\n 七. Fetchmail成长起来 \r\n\r\n  现在我有了一个简洁和富有创意的设计,工作得很好的代码,因为我每天都 \r\n用它,和一直在增长的beta表,它让我渐渐明白我已经不是在从事只能对少数其 \r\n他人有用的工作中,我写了一个所有有一个Unix邮箱和SLIP/PPP邮件连接的人都 \r\n真正需要的程序。 \r\n\r\n  通过SMTP转发功能,它成为一个潜在的“目录杀手”,远远领先于它的竞争 \r\n者,这个程序如此能干以至于其他的程序不但被放弃简直被忘记了。 \r\n\r\n  我知道你不可以真得瞄准或计划出这样的结果,你只能努力去设计这些强大 \r\n的思想,以后这些结果就好象是不可避免的、自然的、注定了的,得到这种思想 \r\n的唯一办法是获取许多思想,或者用工程化的思考其他人的好主意而超过原来想 \r\n到它的人的设想。 \r\n\r\n  Andrew Tanenbanm原来设想建造一个适合386的简单的Unix用做教学,Linus \r\nTorvalels把Andrew的可能想到的Minix可以做什么的概念推进了一步,成长为一 \r\n个极好的东西,同样的(虽然规模较小),我接受了Card Harris和Harry \r\nHochheiser的想法,把它们变得更强大,我们都不是人们所浪漫幻想的天才的创 \r\n始人,但是大多数科学和工程和软件开发不是被天才的创始人完成的,这和流传 \r\n的神话恰恰相反。 \r\n\r\n结果总是执着的原因——实际上,它是每个黑客为之生存的成功!而且它们意 \r\n味着我必须把自己的标准定高一点,为了把fetchmail变得和我所能设想的那样 \r\n好,我必须不仅为我自己的需要写代码,而且也要包括对在我生活围主页外的人 \r\n们的需求的支持,而且同时也要保证程序的简单和健壮。 \r\n\r\n  在实现它之后我首先写的最重要的特征是支持多投——从集中一组用户的邮 \r\n件的邮箱中取出邮件,然后把它路由到每个人手中。 \r\n\r\n  我之所以加上多投功能部分是因为有些用户一直在闹着要它,更是因为我想 \r\n它可以从单投的代码中揭露出错误来,让我完全一般地处理寻址,而且这被证明 \r\n了。正确解释RFC822花了我相当长的时间,不仅因为它的每个单独部分都很难, \r\n而且因为它有一大堆相互依赖的苛刻的细节。 \r\n\r\n  但是多投寻址也成为一个极好的设计决策,由此我知道: \r\n\r\n14. 任何工具都应该能以预想的方式使用,但是一个伟大的工具提供你没料到 \r\n的功能。 \r\n\r\n  Fetchmant多投功能的一个没有料到的用途是在SLIP/PPP的客户端提供邮件 \r\n列表、别名扩展。这意味着一个使用个人机器的人不必持续访问ISP的别名文件就 \r\n能通过一个ISP帐户管理一个邮件列表。我的beta测试员提出的另一个重要的改变 \r\n是支持8位MIME操作,这很容易做,因为我已经仔细的保证了8位代码的清晰,不 \r\n仅因为我预见到了这个特性的需求,而且因为我忠实于另一准则: \r\n\r\n 15. 当写任何种类的网关型程序时,多费点力,尽量少干扰数据流,永远不要 \r\n抛弃信息,除非接收方强迫这么作! \r\n\r\n  如果我不遵从这个准则,那么8位MIME支持将会变得困难和笨拙,现在我所需 \r\n要做的,是只读一下RFC 1652,在产生信头的逻辑加上一点而已。 \r\n\r\n  一些欧洲用户要求我加上一个选项来限制每次会话取得消息数(这样他们就可 \r\n以从昂贵的电话网中控制花费了),我很长一段时间拒绝这样做,而且我仍然对它 \r\n不很高兴,但是如果你是为了世界而写代码,你必须听取顾客的意见——这并不 \r\n随他们不付给你钱而改变。 \r\n\r\n八. 从Fetchmail得来的另一些教益 \r\n\r\n  在他们回到一般的软件工程问题以前,还有几个从fetchmail得到的教益需要 \r\n思考。 \r\n\r\n  rc文件语法包括可选的“noise”关键字,它被扫描器完全忽略了,当你把它 \r\n们全抽取出的时候,关键字/值对更具可读性。 \r\n\r\n  当我注意到rc文件的声明在多大程度上开始象一个微型命令语言时,这是一个 \r\nLate-night的体验(这也是我为什么把popclient原来的“server”关键字改成了 \r\n“poll”)。 \r\n\r\n  对我来说似乎把这个微型命令语言变得更象英语可能会使它更容易使用。现在, \r\n虽然我对经过Emacs和HTML及许多数据库引擎所证实的“把它做成一个语言”的设计 \r\n方式确信不疑,但是我并不是一个通常的“类英语”语法的狂热拥护者。 \r\n\r\n  传统程序员容易控制语法使它尽量精确和紧凑,完全没有冗余,这是计算机资 \r\n源还很昂贵时遗留下的一种文化传统,所以扫描策略需要尽可能的廉价和简单,而 \r\n具有50%冗余度的英语,看来好象是一个非常不合适的模型。 \r\n\r\n  这并不是我不用类英语语法的原因,我提到这一点是为了推翻它,在更廉价的 \r\n时钟周期与核心的时代,简洁并没有走到尽头,今天对一个语言来说,对人更方便 \r\n比对机器更廉价来的更加重要。 \r\n\r\n  然而,有几个原因提醒我们小心一点,一个是扫描策略的复杂度开销——你并 \r\n不想把它变成一个巨大的错误来源和让用户困惑,另一个是试图使语言表面上的类 \r\n似可以和传统语言一样令人困惑(你可以在许多4GL和商业数据库查询语言上看到这 \r\n一点)。 \r\n\r\n  Fetchmail的控制语法避免了这些问题,因为语言的领域是极其有限的。它一 \r\n点也不象一个一般性的语言,它很简单地描述的东西并不复杂,所以很少可能在英 \r\n语的一个小子集与实际的控制语言之间发生混淆,我想这有一个更广泛的教益: \r\n\r\n 16. 如果你的语言一点也不象是图灵完备的,严格的语法会有好处。 \r\n\r\n  另一个教益是关于安全的,一些fetchmail用户要求我修改软件把口令加密存 \r\n贮在rc文件里,这样觑探者就不能看到它们了。 \r\n\r\n  我没有这样做,因为这实际上起不到任何保护作用,任何有权读取你的rc文件 \r\n的人都可以以你的名义运行fetchmail——如果他们要破你的口令,它们可以从 \r\nfetchmail的代码中找到制作解码器的方法。 \r\n\r\n  所以fetchmail口令的加密都会给那些不慎重思考的人一种安全的错觉,这里 \r\n一般性的准则是: \r\n\r\n 17. 一个安全系统只能和它的秘密一样安全,当心伪安全。 \r\n\r\n九. 集市风格的必要的先决条件 \r\n\r\n  本文的早期评审人员和测试人员坚持提出成功的市集模式开发的先决条件, \r\n包括工程领导人的资格问题和在把项目公开和开始建造一个协作开发人员的社团 \r\n的时候代码的状态。 \r\n\r\n  相当清楚,不能以一个市集模式从头开发一个软件,我们可以以市集模式、 \r\n测试、调试和改进,但是以市集模式从头开始一个项目将是非常困难的,Linus \r\n没有这样做,我也没有,初期的开发人员的社团应该有一此可以运行和测试的 \r\n东西来玩。 \r\n\r\n  当你开始创建社团时,你需要演示的是一个诺言,你的程序不需要工作的 \r\n很好,它可以很粗糙、很笨拙、不完整和缺少文档、它不能忽略的东西是要吸 \r\n引哪些人卷入一个整洁的项目。 \r\n\r\n  Linux和fetchmail都是以一个吸引人的基本设计进入公共领域的,许多和 \r\n我一样在思考市集模式的人已经正确的认为这是非常关键的,然后得出了一个 \r\n结论,工程领导者的高度的设计直觉和聪颖是必不可少的。 \r\n\r\n  但是Linus是从Unix得到他的设计的,我最初是从先前的popmail得到启发的 \r\n(虽然相对Linux而言,它最后改变巨大),所以市集风格的领导人/协调人需要有 \r\n出众的设计才能,或者他可以利用别人的设计才能? \r\n\r\n  我认为能够提出卓越的原始设计思想对协调人来说不是最关键的,但是对 \r\n他/她来说绝对关键的是要能把从他人那里得到的好的设计重新组织起来。 \r\n\r\n  Linux和fetchmail项目都显示了这些证据,Linus(如同前面所说)并不是惊人 \r\n的原始设计者,但他显示了发现好的设计并把它集成到Linux内核中的强大决窍。 \r\n还有我也描述了怎样从别人那里得到了fetchmail中最强大的设计思想(SMTP转发)。 \r\n\r\n  本文的早期读者称赞我,说因为我做了许多关于原始设计的事,所以倾向于 \r\n低估原始设计在市集项目中的价值,也许有些是对的吧,但是设计(而不是编码或 \r\n调试)本来就是我最强的能力。 \r\n\r\n  变得聪明和软件设计的原始创作的问题是它会变成一个习惯,当需要保持事 \r\n物健壮和简洁的时候,你却开始把事情变得漂亮但却复杂。我曾经犯过错误,使 \r\n得一些项目因我而崩溃了,但我努力不让它发生在fetchmail身上。 \r\n\r\n  所以我相信fetchmail项目的成功部分是因为我抑制自己不要变得太聪明,这 \r\n说明(至少)对市集模式而言原始设计并不是本质的,请考察一下Linux假设Linus \r\nTorvalds在开发时试图彻底革新操作系统设计,它还会象今天我们所拥有的内核 \r\n那样稳定和成功吗? \r\n\r\n  当然基本的设计和编码技巧还是必需的,但我希望每个严肃考虑发起一个市 \r\n集计划的人都已至少具备这些能力,自由软件社团的内部市场对人们有某些微妙 \r\n的压力,让他们不要发起自由不能搞定的开发,目前为止,这工作得仍然相当好。 \r\n\r\n  对市集项目来说,我认为还有另一种通常与软件开发无关的技能和设计能力 \r\n同样重要——或者更加重要,市集项目的协调人或领导人必须有良好的人际和交 \r\n流能力。 \r\n\r\n  这是很显然的,为了建造一个开发社团,你需要吸引人,你所做的东西要让 \r\n他们感到有趣,而且要保持他们对他们正在做的工作感到有趣,而且要保持他们 \r\n对他们正在做的工作感到高兴,技术方面对达成这些目标有一定帮助,但这远远 \r\n不是全部,你的个人素质也有关系。 \r\n\r\n  并不是说Linus是一个好小伙子,让人们喜爱并乐于帮助他,也并不是说我是 \r\n个积极外向的,喜欢扎堆儿工作,有出众的幽默感的人,对市集模式的工作而 \r\n言,至少有一点吸引人的技巧是非常有帮助的。 \r\n\r\n十. 自由软件的社会学语境 \r\n\r\n 下述如实:最好的开发是从作者解决每天工作中的个人问题开始的,因为它 \r\n对一大类用户来说是一个典型问题,所以它就推广开来了,这把我们带回到准则1, \r\n也许是用一个更有用的方式来描述: \r\n\r\n 18. 要解决一个有趣的问题,请从发现让你感兴趣的问题开始。 \r\n\r\n  这是Carl Harris和原先的popclient的情形,也是我和fetchmail的情形,但 \r\n这已在很长一段时间被大家知晓了,Linux和fetchmail的历史要求我们注意的有 \r\n趣之处是下一个阶段——软件在一个庞大的活跃的用户和协作开发人员的社团中 \r\n的进化。 \r\n\r\n  在《神秘的人月》一书中,Fred Brooks观察到程序员的工作时间是不可替代 \r\n的:在一个误了工期的软件项目中增加开发人员只会让它拖得更久,他声称项目 \r\n的复杂度和通讯开销以开发人员的平方增长,而工作成绩只是以线性增长,这个 \r\n说法被称为“Brooks定律”,被普遍当作真理,但如果Brooks定律就是全部,那 \r\nLinux就不可能成功。 \r\n\r\n  几年之后,Gerald Weinbeng的经典之作“The Psychology Of Computer \r\nProgromming”为我们更正了Brooks的看法,在他的“忘我(egoless)的编程”中, \r\nWeinberg观察到在开发人员不顽固保守自己的代码,鼓励其他人寻找错误和发展 \r\n潜力的地方,软件的改进的速度会比其他地方有戏剧性的提高。 \r\n\r\n  Weinberg的用词可阻止了他的分析得到应有的接受,人们对把Internet黑客 \r\n称为“忘我”的想法微笑,但是我想今天他的想法比以往任何时候都要引人注目。 \r\n\r\n  Unix的历史已经为我们准备好了我们正在从Linux学到的(和我在更小规模上 \r\n模仿Linus的方法所验证的)东西,这就是,虽然编码仍是一个人干的活,真正伟 \r\n大的工作来自于利用整个社团的注意和脑力,在一个封闭的项目中只利用他自己 \r\n的脑力的人会落在知道怎样创建一个开放的、进化的,成百上千的人在其中查找 \r\n错误和进行修改的环境的开发人员之后。 \r\n\r\n  但是Unix的传统中有几个因素阻止把这种方法推到极致。一个是各种授权的 \r\n法律约束、商业机密和商业利益,另一个(事后来看)是Internet还不够好。\r\n----\r\n分类:[自由软件开发]','N/A','2002-01-24 16:06:07','2002-01-24 16:06:07',0,'N/A',28),('WiKiWiKiWeb','请参看: WikiWikiWeb\r\n\r\n----\r\n参加讨论: [WebPMAndWiki]','BrokenDoor','2002-01-30 17:21:41','2002-02-26 15:33:52',0,'N/A',29),('WebPMAndWiki','这里是 [WebPM] 如何结合 WiKiWiKiWeb 的讨论区:\r\n--------------------------------------------------------------------------------\r\n我希望有一种为特定工作服务的wiki比如说程序开发。结合ant,junit和CVS。项目的成员可以对同一份代码做到真正的合作开发或是pairprogramming。因此可以 \r\n-合作开发 \r\n-结合ant的功能 \r\n-结合junit的功能 \r\n-版本控制 \r\n-代码、文档发行 \r\n-- kert \r\n--------------------------------------------------------------------------------\r\n没错,其实我们只是参照了vqw和erpTao 的功能。而用wiki支持程序开发,似乎难度很大。所以,我们目前只考虑利用wiki实现,项目信息的发布和管理。毕竟,wiki的功能在某种程度上可以看作一种网站的在线编辑系统。目前我的想法是先完成一个基本的框架,重点解决在线项目信息发布(像SourceForge,不过我们准备用wiki完成)。以及互联网上的交流平台,不仅仅是论坛(其实有wiki,就不需要论坛了),而且要提供在线会议的管理。例如: \r\n-在线的白板和聊天功能 \r\n-自动的会议记录(所有会议内容自动纪录到项目数据库) \r\n-白板的自动展示。 \r\nant 和 junit 的功能(尤其是junit)目前仅限于java开发,因此暂时不考虑集成。而版本控制,还需要进一步的探讨。 - brokendoor\r\n--------------------------------------------------------------------------------\r\nwiki最早的目的是CSCW,是GroupWare的一种。因此我觉得是一个非常好的合作开发的平台。我得目的是希望在这个平台的基础上实施XP,尝试分布式的合作开发。如果要讨论,我希望在这里。以wiki为基础,大家可以共同写作写作。 - kert \r\n--------------------------------------------------------------------------------\r\nwiki 可以支持项目交流,信息发布,讨论和项目文档。但是如何进行代码和版本控制?以及工程管理? - brokendoor 2002/1/8 \r\n--------------------------------------------------------------------------------\r\n原始的wiki不能完成这些功能,可是你可以将其扩展呀!你可以假设这是一个具有超强功能的IDE在Web应用的扩展。设想一下在wiki基础上的进行的pair programming,就像我们这里的讨论一样。再加上一些扩充的功能(结合编译工具和xUnit工具,加上CVS和在线的文档管理),你能想象一下这是一个什么样的怪物么? -- kert 2002./1/8 \r\n--------------------------------------------------------------------------------\r\n不就是WebPM希望成为的怪物么?:) 目前,WebPMWiki的基本框架已经形成,核心开发者是我们的浆糊同志。如果kert你觉得还可以,让我们大家一起努力吧!我这个人还是喜欢多点力量支持!- brokendoor 2002/1/9 \r\n--------------------------------------------------------------------------------\r\n破门,你有没有听说过jakarta的Alexandria? 也许可以作为一个你项目的参考。 --kert \r\n--------------------------------------------------------------------------------\r\n没有,我上去看了一下,感觉一般。不过把javadoc, cvsweb 架在了一起,作用并不十分明显。 --brokendoor 2002/1/14 \r\n--------------------------------------------------------------------------------\r\n其实还是有很多的借鉴的地方,例如cvsweb也是webpm所需要的 --浆糊 \r\n--------------------------------------------------------------------------------\r\nWebPM 关于网络开发(ant, junit, cvs集成)的支持可能要等到下一阶段。目前考虑的是要实现一个好的网站架构和交流平台。也就是如何利用wiki实现项目信息发布,以及文章管理。说到网站架构,我倒是觉得[url=http://www.zope.org]zope[/url]的思路比较好. - brokendoor 2002/1/16 \r\n--------------------------------------------------------------------------------\r\n我正想说这个,的确可以一试。顺便你可以去看一下[url=http://java.isavvix.com/index.jsp]这里[/url]作为参考 -- kert \r\n----\r\n 以上讨论摘自[url=http://www.erptao.org/wiki]ERP之道[/url],既然[webpm_wiki]已经初见成效,这类讨论自然应该在此继续。同时十分感谢erptao potian 的辛勤工作! - BrokenDoor 2002/1/22\r\n\r\n----\r\n分类: [WebPM] | [webpm_wiki]\r\n\r\n参考: [webpm_wiki 讨论区]','N/A','2002-01-30 17:22:33','2002-01-30 17:22:33',0,'N/A',30),('TestTest','Nothing','N/A','2002-00-22 12:31:03','2002-00-22 12:31:03',0,'N/A',31),('TestTestTest','Nothing','N/A','2002-00-22 12:31:39','2002-00-22 12:31:39',0,'N/A',32),('webpm_wiki','\'\'\'1.2版本发布计划\'\'\'\r\n*见:[2002年2月20日 聊天记录]\r\n----\r\n\'\'\'版本1.2 用户故事\'\'\'\r\n* [webpm_wiki.用户故事.v1.2]\r\n----\r\n\'\'\'第二次发布计划会议\'\'\'\r\n* [2002年2月6日 会议纪要]\r\n* [webpm_wiki.用户故事.第二阶段]\r\n----\r\n\'\'\'第二版本用户故事提要\'\'\'--<详细故事内容编写中>\r\n\r\n\'\'一定完成的功能:\'\'\r\n\r\n-1.code标记不处理wiki 代码,此功能优先考虑(提供不进行wiki代码处理标签)\r\n-2.申请项目的时候自动创建项目的wiki首页; <第一版本未实现>\r\n-3.提供preview功能;\r\n-4.编辑冲突保护;\r\n-5.最近浏览页面统计;\r\n-6.页面浏览数统计;\r\n-7.webpm的安装程序;\r\n\r\n\'\'争取实现的功能:\'\'\r\n\r\n-1.code标记支持彩色代码显示;\r\n-2.不同平台的中文处理;\r\n-3.版本内容间的详细比较 java diff;\r\n-4.多语言支持;\r\n----\r\n\'\'\'定义\'\'\'\r\nWebPM 的核心子项目,当前的用户故事如下:\r\n\r\n1、用jsp/mysql实现wiki的功能; \r\n2、每日自动备份数据,可以由管理员恢复数据; \r\n3、申请项目的时候自动创建项目的wiki首页; \r\n4、中文标签采用类似[?]或者[url]&[/url]等成对的方式,可以方便的对标签扩展; \r\n5、支持[code][/code]标签,用于显示程序源代码; \r\n6、尽量支持原来英文的Wiki标签转换规则; \r\n7、暂时不考虑权限控制,不支持任何脚本。 \r\n\r\n\'\'\'JWIKI 待办事项 \'\'\'\r\n\'\'2002-1-30\'\'\r\n*为第一次代码发布编写相关文档\r\n\r\n\'\'2002-1-29\'\'\r\n*除接口以外的所有类实行动态加载 Finish \r\n*简化标签\r\n\r\n\'\'2002-1-24\'\'\r\n* 自动URL连接 \r\n* 版本比较 Finsh\r\n* 编辑冲突的保护\r\n* code 标记的扩展接口处理\r\n* 中文问题的接口化处理\r\n* 增加Preview功能\r\n\r\n\'\'2002-1-23\'\'\r\n* 最近更新 Finish\r\n* 数据备份 Finish\r\n* 修改 Bug\r\n* 完善现有的页面: 查询,版本 页面\r\n\r\n----\r\n分类:[WebPM]\r\n-----\r\n\'\'这里的讨论转移到[webpm_wiki 讨论区]\'\'\r\n','N/A','2002-02-22 00:36:38','2002-02-22 00:36:38',0,'浆糊',33),('webpm 规格说明书','----WebPM - v1.0 - 规格定义 版本 0.1 - 2001-07-21 0:12:15 \r\n----CopyLeft (l) 2001 Softme Studio \r\nBrokenDoor brokendoor@sina.com \r\n----\r\n1. 简介 \r\n---- \r\n什么是 [WebPM] ? WebPM 的英文全称是 (Project Management On Web),是由Softme Studio发起的自由软件平台。其主要目标是为中文自由软件的开发者、使用者和推广者提供基于互联网的开放式管理平台环境。\r\n\r\n2. WebPM 的阶段计划 \r\n----\r\nWebPM 的开发计划分为三个阶段,每个阶段有着相对独立的目标和内容。 \r\n\r\n2.1 第一阶段: \r\n\r\n WebPM 的第一阶段目标是提供全中文的自由软件项目信息集散地。\r\n 主要的功能包括以下的内容。\r\n - 自由软件开发者、使用者及推广者的注册信息管理。\r\n - 自由软件项目开发、需求信息的发布和管理。\r\n - 自由软件项目人员的组织和管理。\r\n - 自由软件项目公开文件的发布和管理。\r\n\r\n2.2 第二阶段: \r\n\r\n WebPM 的第二阶段的目标是提供全球化中文网上项目开发过程沟通平台。\r\n 主要的功能包括以下的内容。\r\n - 自由软件项目的任务需求发布和管理。\r\n - 自由软件项目的人力需求发布和管理。\r\n - 自由软件项目的专用技术论坛。\r\n - 自由软件项目的专用既时通讯系统。\r\n - 自由软件项目的专用网上会议系统。\r\n\r\n2.3 第三阶段: \r\n\r\n WebPM 的第三阶段的目标是提供全球化中文网上项目开发过程管理平台。\r\n 主要的功能包括以下的内容。\r\n - 自由软件项目的需求分析和跟踪管理。\r\n - 自由软件项目的人力资源组织。\r\n - 自由软件项目的任务计划跟踪管理。\r\n - 自由软件项目的源代码跟踪管理。\r\n - 自由软件项目的开发文档跟踪管理。\r\n - 自由软件项目的错误跟踪管理。\r\n\r\n3. 开发平台 \r\n---- a) 全WEB界面管理,多语种界面信息支持。\r\n b) 使用 JSP/Apache+tomcat/MySQL 作为开发平台。\r\n c) 支持 XML/ HTML 4.0 / XHTML 等相关规范。\r\n\r\n4. 人员组织 \r\n----项目管理: BrokenDoor (Softme Studio) \r\n项目顾问: [notyy] (xpchina.org) \r\n固定成员: \r\n[takaka] (焦点网电子小组 xpchina) \r\n[踏冰](Softme Studio)&(NeedRecharge Studio)\r\n[浆糊](Softme Studio) \r\n\r\n5. 相关资源 \r\n----武汉自由软件协会 http://www.clinux.org \r\n湖北省软件协会开源分会 \r\n\r\nxpchina.org http://xpchina.org \r\n\r\nSoftme Studio(WebPM) http://softme.org \r\n\r\n----\r\n分类: [WebPM]','N/A','2002-01-29 09:48:44','2002-01-29 09:48:44',0,'N/A',34),('冬儿哥哥','小人物一个,初涉IT界不久,请各位前辈提携\r\n\r\ncaodz@oliveinfo.com','N/A','2002-01-23 09:05:07','2002-01-23 09:05:07',0,'N/A',35),('JWIKI','请参看 [webpm_wiki] ...','N/A','2002-00-22 18:05:22','2002-00-22 18:05:22',0,'N/A',37),('hbworld','我是hbworld\r\n黄波','N/A','2002-00-22 18:37:35','2002-00-22 18:37:35',0,'N/A',38),('kertwww','kert is K E R T','N/A','2002-00-22 22:17:54','2002-00-22 22:17:54',0,'N/A',39),('极端编程','\'\'\'这里是关于极端编程 (eXtreme Programming) 的介绍:\'\'\'\r\n --- 可以去[url=http://www.xpchina.org]\'\'\'XPChian\'\'\'[/url]看到很多好的讨论。\r\n --- 这里是[极端编程讨论区]\r\n----\r\n* [什么是XP?] - XP简介中我认为是最经典、最清楚的一篇文章。\r\n\r\n* [成对编程] - 来自Rational 公司的白皮书\r\n\r\n* [XP的实践规则] - 更详细一点的关于XP的12条实践规则的介绍,主要参考 XP Distilled 一文。\r\n\r\n----\r\n* [解析“极端”] - xpchina 中关于kent beck 的“极端句式”的讨论,从一个侧面说明了“极端编程”这个名字的来源。\r\n\r\n* [完成的感觉] - 也许你对前两篇文章中的“可接受的步伐”和“程序员控制节奏”不够了解,那么看看这篇译文吧。愿所有的程序员都能够体验像文章所描述的美好的一天!\r\n\r\n* [CRC的使用简介] - CRC 是XP团队用来进行快速设计的一种有效手段,但是没有找到很好的介绍,这里是破门整理的一小段介绍,真正简陋的介绍,:(\r\n\r\n* [设计模式与XP]\r\n----\r\n任何一个学说都需要从各个角度分析,看看反对派的经典论文:\r\n\r\n* [XP-抄近路的诡计] - Doug Rosenberg及Kendall Scott对于XP的质疑\r\n----\r\n分类:[软件工程]\r\n','N/A','2002-02-20 19:05:22','2002-03-04 09:59:48',0,'BrokenDoor',40),('kert','kert is K E R T','N/A','2002-00-22 22:23:29','2002-00-22 22:23:29',0,'N/A',41),('Delphi','一种不错的语言\r\nDelphiWork','N/A','2002-00-22 22:47:23','2002-00-22 22:47:23',0,'N/A',42),('HHHHH','shuo ming ','N/A','2002-00-22 23:07:41','2002-00-22 23:07:41',0,'N/A',43),('zwhhoo','做的好,加油,加油。^O^[email=zwhhoo@163.net]我的邮箱[/email]','N/A','2002-00-22 23:18:42','2002-00-22 23:18:42',0,'N/A',44),('安装问题','\'\'\'有什么问题请在此提出:\'\'\'\r\n----\r\n\'\'\'Q:老大!我这里有中文乱码啊,55555\'\'\'\r\nA:需要设置config.xml中的中文编码,具体的要看你的平台了.请留下联系方式 2002/02/22--[浆糊] \r\n\r\n\'\'\'Q:稍微修改了下代码,用了Sqlserver,但是还是有不少问题,比方说topic还是乱码,不知道你的1.0是不是最新的?我现在最新更新要出nullpointer错误,搜索则是什么都搜不出。代码我大体上看了下。如果是最新的版本,我就要开始修改一些地方拉:)恩,对了,我的环境是tomcat+sqlserver。\'\'\'\r\nA:最新版本是v1.1,修订了不少中文问题。中文的处理不需要修改代码,只要修改conf/config.xml就可以解决中文问题。请到[源码下载]获取最新的稳定代码。最新的开发代码可以到[CVS|http://cosoft.org.cn/cvs/?group_id=17]中获取。\r\n\r\n\'\'\'Q:我下载了1.1看了一下代码,好象存在这样的问题。是不是你们将[no]org.softme.webpm.utility.StringUtility的方法进行过refactory?而没有及时的将jsp中的方法修改过来?给个例子把。你去看jsp/jviki/acticle_version_manager.jsp中有StringUtility.URLParamEncode()的方法。我用cvs不能checkout你们的东西,(公司关了很多端口)。不过通过web方式上去,发现你们的StringUtility又把方法全修改了。[/no]你看看是不是有这个问题?给个好点的版本把,可能你们发布的和自己用的是不是有点不一样?\'\'\'\r\nA: acticle_version_manager.jsp 已经不再使用了。最新的 [no]StringUtility [/no]提供了六个字符串处理函数,分别处理 response/request <=> memory <=> db 之间的字符串编码转换,1.1的代码已经是最新的,CVS里面的是目前正在开发的v1.2,详情请看[webpm_wiki]中v1.2用户故事。很抱歉目前由于力量的不足没有能提供好一点的文档,感谢你的大力支持!如果还有问题,请与我们联系!\r\nQ:\'\'\'破门兄,我就是下载你们提供的1.1beta的啊,里面就是有这样那样的问题的,你下载一个看看就知道拉。我想在自己公司架一个wiki,因为我们正在用xp的方式开发。\'\'\'\r\nA:请下载1.1版本,不要下beta版本.如果有什么问题最好描述一下,我们会尽力帮你解决的.\r\n\r\n\'\'\'[no]呵呵,下载了1.1的版本以后,稍微修改了部分代码就可以了,主要问题就出在:我用的是jdbc,odbc的桥,所以,只能用jdbc1.0拉,所以原来的部分代码就要修改(否则....呵呵......),所以建议你们的代码需要做一些修改,使得代码在什么情况都可以用。比方说pstmt.setString(1,\"%\"+StringUtility.encodeMemory2DB(gKey)+\"%\") ;在jdbc1.0是不支持的。而且有些查询因为依赖了MySQL的函数,切换到其他数据库的时候也要做一些修改。我建议用ORMapping来做这部分的工作,这样就可以解决数据库的无关性 :)[/no]\'\'\'\r\nA:谢谢你的意见,我们会尽量完善现有的程序,能否提供你修改过的代码?\r\n\r\n\'\'\'可以啊!不过不知道怎么给你??ORMapping的工作我当然没做了,我只是修改了部分的和数据库操作的代码。还有想到了一点,就是对从数据库里面拿出来的String和request拿来的String最好加上trim()的操作:)否则取出来的String都是用空格补成等长的,在MySql里面可能不是问题,但是加上trim()是一个良好的编程习惯:)所以偶帮你全加上了:)\'\'\'\r\nA:呵呵..谢谢了.你可以发给我.我的邮箱java_cn@21cn.com.不知道有没有兴趣加入到我们的开发队伍中来?看看最新公告里的会议通知. 2002/02/26 --[浆糊]\r\n\r\n\'\'\'好的啊!不过我不知道我有没有时间参加编码了,不过大家在一起可以一起探讨一些问题,比方说系统的架构什么的.不能否认,目前的架构对于调试什么的,并不是很方便,大家探讨探讨,呵呵.我以前写过写东西,猿马网上一放,就说这是opensource的,真的在网络上协同开发到没尝试过,协调是个问题啊.这个wiki应该算是一个[cscw]的应用了把?hoho\'\'\'[扫地的癞蛤蟆]\r\nA:好的,不知道你有没有QQ?大家交流方便一点,我的:3413384 . [浆糊]\r\n\'\'\'我的QQ是4304954 ,不过上班的时候不能用的。用一次扣500银子:(MSN是 :ymruan@hotmail.com\r\n哈哈。对了!发现一个小bug~~~你用IE5.5以及以上版本浏览,用问号传的中文参数是乱码。赫赫5。0是没有问题di!\'\'\'[扫地的癞蛤蟆]\r\n----\r\n分类:[WebPM] | [webpm_wiki]','浆糊','2002-02-22 11:42:18','2002-02-27 09:45:40',0,'ymruan',158),('webpm 开发手册','=======================================================================\r\nWebPM - v1.0 - 开发手册 - 2001年12月18日\r\n=======================================================================\r\n\r\n版本 1.0\r\nCopyLeft (l) 2001 Softme Studio\r\n=======================================================================\r\n\r\nBrokenDoor (Softme Studio) 2001-12-18\r\n\r\nWishipping 2001-7-30\r\n=======================================================================\r\n\r\n说明\r\n=======================================================================\r\n开发手册提供WebPM开发过程中使用的相关技术简介和资料,开发工具使用,开发\r\n平台配置,编码规范等,是WebPM开发者开发和参考手册。相关技术的介绍和开发\r\n环境的配置内容均为提纲挈领及综合描述式,详细学习和参考可以通过所提供的\r\n相关资料或资源,(有的资料可能不是最新,如果有更新的资料请通知我更新)。\r\n重点在于开发规范约定。本手册在开发过程中不断增补。\r\n\r\n目录\r\n=======================================================================\r\n1. 开发平台和使用技术概诉\r\n2. JSP\r\n 2.1 JSP简介\r\n 2.2 JSP与ASP的比较\r\n 2.3 JSP+Servlets+JavaBean的开发模式\r\n 2.4 资料:JSP规范和开发者指南\r\n3. JavaBeans\r\n 3.1 JavaBeans 及其准则\r\n 3.2 用JavaBean 连接数据库\r\n 3.3 JSP中调用JavaBeans\r\n 3.4 资料:JavaBeans规范\r\n4. OOAD\r\n 4.1 使用CRC进行OOAD\r\n 4.2 设计模式和框架\r\n 4.3 资料:Design Java Apps with UML\r\n 4.4 资料:design pattern\r\n5. XP\r\n 5.1 为什么是XP\r\n 5.2 XP简介\r\n 5.3 相关资源\r\n6. 开发环境的配置\r\n 6.1 JDK的安装和使用\r\n 6.2 Apache\r\n 6.3 Tomcat的安装和使用\r\n 6.4 Mysql的安装和使用\r\n 6.5 加载JDBC驱动程序\r\n7. 编码规范\r\n 7.1 遵循编码规范的好处\r\n 7.2 源文件\r\n 7.3 命名约定\r\n 7.4 间隔的用法\r\n 7.5 注释和javadoc的使用\r\n 7.6 相关资料\r\n\r\n1.开发平台和相关技术概诉\r\n=======================================================================\r\n开发平台:JDK + Tomcat + mysql\r\n相关技术:Java2, JSP, servlet, JavaBeans\r\n\r\n\r\n2.JSP\r\n=======================================================================\r\n2.1 JSP简介\r\n-------------------------------------------------------------\r\nJava Server Pages (JSP)技术为创建显示动态生成内容的Web页面提供了一个简捷而\r\n快速的方法。JSP规范是Web服务器、应用服务器、交易系统、以及开发工具供应商间\r\n广泛合作的结果。Sun开发出这个规范来整合和平衡已经存在的对Java编程环境(例如,\r\nJava Servlet和JavaBeansTM)进行支持的技术和工具。其结果是产生了一种新的、\r\n开发基于Web应用程序的方法,给予使用基于组件应用逻辑的页面设计者以强大的功能。\r\n\r\n常用的jsp应用服务器:\r\n - Allaire的Jrun: http://www.allaire.com/Products/Jrun/\r\n - Oracle的oas: http://www.oracle.com/\r\n - Weblogic Server: http://www.bea.com/priducts/weblogic/server/index.html\r\n - IBM WebSphere:http://www-4.ibm.com/software/webservers/appserv/\r\n - apache.org Jakarta项目组的Tomcat:http://jakarta.apache.org/\r\n\r\n2.2 JSP与ASP的比较\r\n-------------------------------------------------------------\r\nJSP 与 Microsoft 的 ASP 技术非常相似。两者都提供在 HTML 代码中混合某种程序\r\n代码、由语言引擎解释执行程序代码的能力。在 ASP 或 JSP 环境下, HTML 代码主\r\n要负责描述信息的显示样式,而程序代码则用来描述处理逻辑。普通的 HTML 页面只\r\n依赖于 Web 服务器,而 ASP 和 JSP 页面需要附加的语言引擎分析和执行程序代码。\r\n程序代码的执行结果被重新嵌入到 HTML 代码中,然后一起发送给浏览器。 ASP 和 \r\nJSP 都是面向 Web 服务器的技术,客户端浏览器不需要任何附加的软件支持。 \r\n\r\nASP 的编程语言是 VBScript 之类的脚本语言, JSP 使用的是 Java ,这是两者最明\r\n显的区别。此外, ASP 与 JSP 还有一个更为本质的区别:两种语言引擎用完全不同的\r\n方式处理页面中嵌入的程序代码。在 ASP 下, VBScript 代码被 ASP 引擎解释执行;\r\n在 JSP 下,代码被编译成 Servlet 并由 Java 虚拟机执行,这种编译操作仅在对 JSP\r\n页面的第一次请求时发生。 \r\n\r\n2.3 JSP+Servlets+JavaBean的开发模式\r\n-------------------------------------------------------------\r\n四种JSP的开发模式:\r\n1) 直接使用JSP\r\n对于最小型的Web站点,可以直接使用JSP来构建动态网页,比如简单的留言板、动态日期\r\n等基本的功能。对于这种开发模式,一般可以将所有的动态处理部分都放置在JSP的\r\nScriptlet 中,就像一般使用PHP或ASP 开发动态网页一样。\r\n\r\n2) JSP+JavaBeans\r\n中型站点面对的是数据库查询、用户管理和小量的商业业务逻辑。对于这种站点,不能将\r\n所有的东西全部交给JSP页面来处理。在单纯的JSP中加入JavaBeans技术将有助于这种中型\r\n网站的开发。利用JavaBeans,将很容易完成如数据库连接、用户登录与注销、商业逻辑\r\n封装的任务。如:将常用的数据库连接写为一个JavaBeans,既方便了使用,又可以使JSP\r\n文件简单而清晰,通过封装,还可以防止一般的开发人员直接获得数据库的控制权。\r\n\r\n3) JSP+JavaBeans+Servlet\r\n无论用ASP还是PHP开发动态网站,长期以来都有一个比较重要的问题,就是网站的逻辑关系\r\n和网站的显示页面不容易分开。常常可以看见一些夹杂着if......then......、case select\r\n或是if{......}和大量显示用的HTML代码的ASP、PHP页面,即使是有着良好的程序写作习惯\r\n的程序员,其作品也几乎无法阅读。另一方面,动态Web的开发人员也在抱怨,将网站美工\r\n设计的静态页面和动态程序和并的过程是一个异常痛苦的过程。如何解决这个问题呢?事实\r\n是Servlet在不再担负动态页面生成的任务以后,开始担负起决定整个网站逻辑流程的任务。\r\n在逻辑关系异常复杂的网站中,借助于Servlet和JSP良好的交互关系和JavaBeans的协助,完\r\n全可以将网站的整个逻辑结构放在Servlet中,而将动态页面的输出放在JSP页面中来完成。\r\n在这种开发方式中,一个网站可以有一个或几个核心的Servlet来处理网站的逻辑,通过调用\r\nJSP页面来完成客户端(通常是Web 浏览器)的请求。在J2EE模型中,Servlet的这项功能\r\n可以被EJB取代。\r\n\r\n4) J2EE 开发模型\r\n在实际运作中,JSP中只应该有对Bean的消息操作(调用方法,设置和获得属性)和涉及显示\r\n逻辑的控制语句,不应该有直接涉及业务逻辑的操作也不应该有对其他类的实例化和调用\r\n(一些基本的API除外);在 Servlet 中可以有对类实例化和调用。\r\n\r\n2.4 相关资料\r\n-------------------------------------------------------------\r\n - JSP 规范\r\n - JSP developer guid\r\n\r\n3.JavaBeans\r\n=======================================================================\r\n3.1 JavaBeans 及其准则\r\n-------------------------------------------------------------\r\n详细规范请参考 Sun Microsystems的JavaBeans规范。以下是基本准则:\r\n - 构造器:\r\n必须有一个不带参数的公有构造器。此构造器也应该通过调用各个属性的访问器方法来设置\r\n属性的缺省值,例如:\r\npublic Fireworks()\r\n{\r\nsetAutoStart(true);\r\nsetBackground(Color.black);\r\nsetSpeed(10);\r\nsetRadius(40);\r\n\r\n}\r\n如果bean 是一个从 java.awt.Component 类继承而来的可视 bean,您就应该为 bean 定义一个缺省的首选大小,例如:\r\npublic Dimension getPreferredSize()\r\n{\r\nreturn (new Dimension(radius*3, radius*3));\r\n}\r\n\r\npublic Dimension getMinimumSize()\r\n{\r\nreturn getPreferredSize();\r\n}\r\n\r\n - 属性:\r\n所有属性都应该设置为私有,对于需要公用的属性,应该匹配公用访问器(getter 、setter) 方法,例如:\r\nprivate int speed;.\r\n\r\npublic int getSpeed()\r\n{\r\nreturn speed;\r\n}\r\n\r\npublic void setSpeed(int s)\r\n{\r\nspeed = s;\r\n}\r\n\r\n访问器方法必须有与实例变量相同的名称,但是第一个字母要大写并以 get 和 set 开头。\r\n\r\n - 操作:\r\n对于每个需要公用的操作,应该有一个公用方法,例如:\r\npublic void start()\r\n{\r\nif(thread==null)\r\n{\r\nthread=new Thread(this);\r\nthread.start();\r\n}\r\n}\r\n为操作写的方法应该在无须期待用户创建连接或设置很多特性的情况下独立操作。 \r\n例如,如果您写了一个音频 Bean,您希望通过播放操作处理打开声音的所有步骤、完成\r\n您需要的所有设置并播放声音。同样,即使声音未播放,停止操作也应起作用。\r\n\r\n - 事件:\r\n对于您需要的每个事件或事件设置,您应该定义事件和侦听器类。对于此例,查看 \r\nFireworksEvent.java 源文件以及 Fireworks.java 文件。此事件类的源应该如同这样:\r\nimport java.awt.*;\r\nimport java.util.*;\r\n\r\npublic class FireworksEvent extends EventObject\r\n{\r\npublic static final int EXPLODED = 1;\r\nint id = 0;\r\n\r\npublic FireworksEvent(Component source, int id)\r\n{\r\nsuper(source);\r\nthis.id = id;\r\n}\r\n\r\npublic int getID()\r\n{\r\nreturn id;\r\n}\r\n}\r\n您应该为此事件设置中的每个事件定义一个公用静态结束事件标识符,例如在此例子\r\n中的 EXPLODED。对于侦听器类的源,查看 FireworksListener.java 源文件:\r\nimport java.util.*;\r\n\r\npublic interface FireworksListener extends EventListener\r\n{\r\npublic abstract void exploded(FireworksEvent e);\r\n}\r\n\r\n您应该为此事件设置中的每个事件定义一个公用抽象方法,例如在此例子中的\r\nexploded。 而且,侦听器类必须扩展 EventListener。 \r\n然后,如果由 bean 类播送事件,它必须跟踪侦听事件的对象。要这样做,您需要\r\n定义侦听器实例变量以及 addListener 和 removeListener 方法。返回 \r\nFireworks.java 源,例如,您将查看到:\r\nprivate Vector listeners = new Vector();\r\npublic void addFireworksListener(FireworksListener f)\r\n{\r\nlisteners.addElement(f);\r\n}\r\npublic void removeFireworksListener(FireworksListener f)\r\n{\r\nlisteners.removeElement(f);\r\n}\r\n最后,bean 类需要以正确的次数将事件实际播送到所有的侦听器。要这样做,您需要\r\n定义 processEvent 方法并以适当的次数调用它,例如:\r\npublic void processFireworksEvent(FireworksEvent e)\r\n{\r\nfor (Enumeration enum = listeners.elements(); enum.hasMoreElements(); )\r\n((FireworksListener)enum.nextElement()).exploded(e);\r\n}\r\npublic void run()\r\n{\r\nprocessFireworksEvent(new FireworksEvent(this, FireworksEvent.EXPLODED));\r\n}\r\n\r\n3.2 用 JavaBean 连接数据库\r\n-------------------------------------------------------------\r\n使用JavaBean 封装数据库连接, JSP中不应该有与数据库有关的操作, 应该将与\r\n数据库连接的所有操作封装到一个底层Bean中:\r\n - javabean通过 jdbc driver来连接和操作数据库。\r\n 一般市场上的数据库服务器的jdbc驱动都可以在\r\nhttp://industry.java.sun.com/products/jdbc/drivers 找到。\r\n - Java代码连接数据库需要2个参数:\r\n 一个是driverName(jdbc驱动名称),一个是urlString(数据库连接串),\r\n 程序通过Class.forName(driverName)从当前classpath中搜寻并加载driverName\r\n 指定的数据库驱动。如果找不到合适的驱动,会抛出:java.lang.ClassNotFoundException\r\n 如果这一步通过的话,程序就正确的加载了指定的驱动,但在执行任何数据库操作前\r\n 还需要通过urlString连接数据库服务器,conn = DriverManager.getConnection(urlString);\r\n 其中conn是一个Connection类型的变量,建立连接后,就可以通过conn来生成一个\r\n Statement:stmt = conn.createStatement();这个statement就可以用来执行sql语句\r\n - sql语句又分为2种:\r\n 1) 查询语句:\r\n 就是\"select\"语句,执行方法为stmt.execQuery(sqlText)//sqlText为查询sql语句。\r\n 返回结果为ResultSet类型。与asp中差不多。\r\n 2) 更新语句:\r\n 包括\"insert,delete,update\"语句。执行方法为stmt.execUpdate(sqlText).无返回值。\r\n 操作过程中如果发生错误会抛出java.sql.SQLException\r\n\r\n3.3 JSP 中调用JavaBeans\r\n-------------------------------------------------------------\r\n为简化jsp开发人员的工作,sun提供了一些jsp命令\r\n - 标准方法: \r\n \r\n 就可以生成User bean的一个实例,其生存周期为session, id相当于实例名。\r\n 通过 得到username属性,\r\n 通过设置username属性。\r\n 还可以通过直接从表单中\r\n 得到属性并设置进Bean中,要求表单中的名字和bean中的属性名相同。\r\n\r\n - 将javabean作为类来调用,直接在jsp里实例化。(降低了Bean的可用性,不应该使用)\r\n\r\n3.4 相关资料\r\n-------------------------------------------------------------\r\n - JavaBeans 1.01规范\r\n - Sun JavaBeans站点:http://java.sun.com/beans\r\n\r\n4.OOAD\r\n=======================================================================\r\n4.1 使用CRC进行OOAD\r\n-------------------------------------------------------------\r\n 第一步:从已知的开始\r\n 第二步:推测支持者\r\n 第三步:进行情景测试\r\n 第四步:尝试进行分组\r\n 第五步:重新分配责任\r\n 第六步:为了清晰化而重写卡片\r\n\r\n4.2 设计模式和框架\r\n-------------------------------------------------------------\r\n 待定\r\n\r\n4.3 资料\r\n-------------------------------------------------------------\r\n - Design Java Apps with UML\r\n - design pattern\r\n\r\n5.XP\r\n=======================================================================\r\n5.1 为什么是XP\r\n-------------------------------------------------------------\r\n让我们来考虑一个传统的途径:用户组和开发组协商让一个分析员设计一个项目。\r\n在几周和几个月中,分析员和用户每天会面几个小时。分析员生产出一套文档,\r\n可能还包括象一个可视描述和用例之类。用户和项目经理(也可能是编程团队)\r\n回顾这些文档并且协商出一个发行版。程序员使用规范在几个月之后成长出一个\r\n系统,或多或少的实现了原来的想法。在结束的时候这通常是一个闭呼叫系统,\r\n当人们发现他们所遗漏的并意识到自从文档被写好以来什么都已经改变了。最后,\r\n用户加入进来作一个用户接受测试然后系统被发布。 \r\n\r\n通常整个过程所花费的时间比任何人所期望的都长,会遗漏一些特征,并且质量\r\n并不是用户想要的。更有甚着,文档也不再随日期更新。 \r\n\r\n问题总结:\r\n - 不能完全理解用户需求(用户自己也经常不清楚自己需要什么)\r\n - 用户的要求不断变化\r\n - 技术更新速度很快\r\n - 开发人员缺乏成功经验\r\n - 开发小组不稳定\r\n - 没有完整的测试设计\r\n\r\n5.2 XP简介\r\n-------------------------------------------------------------\r\nXP全名Extreme Programming ,一种轻量级,灵活的方法。\r\nXP 规定了一组核心价值和方法,可以让软件开发人员发挥他们的专长:编写代码。\r\nXP 消除了大多数重量型过程的不必要产物,通过减慢开发速度、耗费开发人员的\r\n精力(例如干特图、状态报告,以及多卷需求文档)从目标偏离。\r\n\r\n在XP中,在用户和程序员的角色中有一个基本的分隔。用户拥有\"what you get\",\r\n而程序员拥有\"what it costs\"。这显示了谁能作出什么决定。 即用户做企业决策,\r\n程序员做技术决策。\r\n\r\n用户决定:\r\n· 范围:什么系统是必须作的。 \r\n· 优先级:对于企业价值什么是最重要的。 \r\n· 发行的组合:什么是必须在发行版中的,一定是有用的? \r\n· 发行的日期:什么时候需要发行? \r\n\r\n程序员决定:\r\n· 评估添加一个特征的时间 ,以及每个特征的风险 \r\n· 使用各种技术选项所花费的成本 :程序员解释程序选择的结果,但是用户作决定 \r\n· 过程:小组怎么样工作,团队怎么组织 \r\n· 细节时间表:在一个迭代中特征先开发风险最大的那一个特征可以减轻风险\r\n\r\nXP 的核心价值为:\r\n· 交流。 项目的问题往往可以追溯到某人在某个时刻没有和其他人一起商量某些\r\n 重要问题上。使用 XP,不交流是不可能的事。\r\n· 简单。 XP 建议您总是尽可能围绕过程和编写代码做最简单的事情。按照 Beck \r\n 的说法,\"XP 就是打赌。它打赌今天最好做些简单的事...而不是做更复杂但可能\r\n 永远也不会用到的事。\"\r\n· 反馈。 \r\n 更早和经常来自客户、团队和实际最终用户的具体反馈意见为您提供更多的机会\r\n 来调整您的力量。反馈可以让您把握住正确的方向,少走弯路。\r\n· 勇气。 \r\n 勇气存在于其它三个价值的环境中。它们相互支持。需要勇气来相信一路上具体\r\n 反馈比预先知道每样事物来得更好。需要勇气来在可能暴露您的无知时与团队中\r\n 其他人交流。需要勇气来使系统尽可能简单,将明天的决定推到明天做。而如果\r\n 没有简单的系统、没有不断的交流来扩展知识、没有掌握方向所依赖的反馈,勇\r\n 气也就失去了依靠。 \r\n\r\nXP的十二种实践方法: \r\n· 现场客户(On-site customer) \r\n· 规划策略(Planning game) \r\n· 小发行版(Small releases) \r\n· 测试(Testing)\r\n· 系统比喻(Metaphor) \r\n· 简单设计(Simple design) \r\n· 重构(Refactoring) \r\n· 成对编程(pair programming) \r\n· 编码标准(Coding standards) \r\n· 集体代码所有权(Collective ownership) \r\n· 持续集成(Continuous integration) \r\n· 一周40小时 (40-hour week) \r\n\r\n5.3 相关资源\r\n-------------------------------------------------------------\r\n - Extremeprogramming: http://www.extremeprogramming.org/\r\n - XPdeveloper: http://http://www.xpdeveloper.com/\r\n - Xprogramming:http://www.xprogramming.com/\r\n - Junit: http://www.junit.org/\r\n\r\n6.开发环境配置(在此定义开发环境为Win2k)\r\n=======================================================================\r\n6.1 JDK 1.3.1\r\n-------------------------------------------------------------\r\n下载:http://java.sun.com/products/jdk/1.3/\r\n\r\n安装:\r\n - 双击jdk1_3_1-win.exe文件进行安装,使用缺省配置进行安装,JDK的 缺省安装\r\n 目录为C:\\jdk1.3.1, JRE的缺省安装目录为C:\\Program Files\\JavaSoft\\JRE\\1.3\r\n - 更新下列环境变量:把\"C:\\jdk1.3.1\\bin\"目录追加到PATH中;\r\n 把\".;C:\\jdk1.3.1\\lib\"加入到CLASSPATH 中。\r\n 更新方法:控制面板->系统->环境->系统变量;\r\n - 测试applet:\r\n   1)打开cmd窗口;\r\n   2)切换到C:\\jdk1.2.2\\demo\\applets\\TicTacToe目录;\r\n    3)运行appletviewer example1.htm; \r\n    4)一切正常; \r\n - 测试application:\r\n   1)假设在\"D:\\Java\"目录下创建一个Test.java文件,内容如下: \r\n   public class Test       \r\n {   \r\n   public static void main(String arc[])\r\n {            \r\n System.out.println(\"JDK安装成功了,朋友!\");   \r\n      }  \r\n    } \r\n  2)打开cmd窗口;\r\n 3)切换到D:\\Java目录;\r\n   4)运行javac Test.java进行编译;\r\n   5)运行java Test运行这个程序; \r\n 6)一切正常。\r\n\r\n6.2 Apache\r\n-------------------------------------------------------------\r\n 下载Apache:http://www.apache.org\r\n 安装:略\r\n\r\n6.3 Tomcat\r\n-------------------------------------------------------------\r\nTomcat是一个Servlet容器和Jsp实现,可以自己单独使用,也可以和其他流行的\r\nWeb server结合使用。Tomcat Tomcat 3.2.2以上版本支持Servlet API 2.2 和 JSP 1.1。\r\n\r\n下载Tomcat:http://jakarta.apache.org/builds/tomcat/\r\n\r\n安装:\r\n - 将Tomcat压缩包解压到某一目录如:c:\\server\\tomcat下。\r\n 设置 set TOMCAT_HOME=c:\\server\\tomcat。\r\n 再设置JAVA_HOME。这样就可以以stand-alone方式运行tomcat了。\r\n 启动命令为bin\\startup.bat。\r\n tomcat中默认的http端口为8080。\r\n\r\n - Tomcat启动后会自动产生一个配置文件TOMCAT_HOME/conf/tomcat-apache.conf。\r\n 此时在$APACHE_HOME\\conf\\httpd.conf的最后加上\r\n Include %TOMCAT_HOME%/conf/tomcat-apache.conf (注:这里是正斜杠),\r\n 然后加载ApacheModuleJserv.dll到modules目录下面,\r\n 就可以将tomcat作为apache的plug-in使用了。\r\n\r\n - 如果加载的是mod_jserv.so,则Include % TOMCAT_HOME %/conf/tomcat.conf。\r\n\r\n - 推荐的配置:加载mod_jk.dll。\r\n mod_jk.dll既支持ajp13协议,也支持ajp12协议,但是ajp13协议更快、性能更好。\r\n 以前的版本用mod_jserv,最新版本也支持mod_jserv,但是mod_jserv比mod_jk\r\n 更复杂,并且只支持apache,对SSL的支持也没有mod_jk好。所以推荐使用mod_jk.dll.\r\n tomcat3.2.2启动时自动产生一个配置文件mod_jk.conf-auto,所以在\r\n $APACHE_HOME\\conf\\httpd.conf 的最后加上\r\n Include % TOMCAT_HOME %/conf/mod_jk.conf-auto。\r\n 将mod_jk.dll放入modules目录下。就可以启动。\r\n 注意tomcat使用端口8080。\r\n\r\n另外需要修改配置文件为server.xml。\r\n\r\n\r\n \r\n \r\n\r\n这里可以加速AJP连接。\r\n\r\n6.4 mysql的安装\r\n-------------------------------------------------------------\r\n下载mysql:http://www.mysql.com\r\n安装: 略\r\n\r\n使用:\r\n 运行服务器命令 %mysql_home%\\bin\\mysqld-nt.exe -standalone -datadir datadir\r\n 关闭服务器命令 %mysql_home%\\bin\\mysqladmin.exe shutdown\r\n 运行外壳程序:%mysql_home%\\bin\\mysql\r\n 启动数据库: use database\r\n 退出外壳程序:exit\r\n\r\n6.5 加载 JDBC 驱动程序\r\n-------------------------------------------------------------\r\n下载:http://industry.java.sun.com/products/jdbc/drivers\r\n安装:解压到某一目录%JDBC_HOME%,设置classpath=%CLASSPATH%; %JDBC_HOME%\r\n\r\n==================================================================\r\n----\r\n分类:[WebPM]','BrokenDoor','2002-01-23 14:48:28','2002-01-23 14:48:28',0,'N/A',48),('webpm 编码规范','[code]\r\n=======================================================================\r\nWebPM - v1.0 - 编码规范 - 2002年1月3日\r\n=======================================================================\r\n\r\n版本 1.0\r\nCopyLeft (l) 2001 Softme Studio\r\n\r\n浆糊 2002-1-31 15:54\r\n(BrokenDoor) 2002-1-3 20:04\r\n=======================================================================\r\n\r\n1 遵循编码规范的好处 \r\n------------------------------------------------------------- \r\n- 可以使用一致的风格编写代码。 \r\n- 增加了可读性,因此增加了代码的可维护性 \r\n- 有利于程序员共享代码,尤其是小组中的程序员。 \r\n- 可以更方便的使用自动生成工具辅助程序开发。 \r\n- 引导程序复览更容易。 \r\n- 节省开发时间。 \r\n\r\n使程序员注意于代码的语义要比花更多的时间去决定在给定位置什么是适合的特别的格式。 \r\n\r\n2 源文件 \r\n------------------------------------------------------------- \r\n按照类存储,即一个类一个.java文件。 \r\n配置文件文件名小写,例如: config.xml\r\n\r\n3 命名约定 \r\n------------------------------------------------------------- \r\n· 包名(全部小写):org.softme.webpm. \r\n· 类名用名词,第一个字母大写,其后每一个单词的首字母大写。 \r\n· 域名用名词: non-constant 域第一个字母小写,其后每一个单词的首字母大写; \r\n constants 全部用大写,单词连接处用下划线_。 \r\n· 方法名为动宾关系:第一个字母小写,其后每一个单词的首字母大写。 \r\n\r\n4 间隔的用法 \r\n------------------------------------------------------------- \r\n· 空白行 \r\n· 空格 \r\n· 锯齿排列,以四格为一个缩进单位。 \r\n· 行长度和延长 \r\n\r\n5 注释和javadoc的使用 \r\n------------------------------------------------------------- \r\njava支持三种注释: \r\n· 传统C语言风格: block \r\n/* comment \r\n* \r\n*/ \r\n\r\n· C++风格:single-line \r\n// comment \r\n\r\n· javadoc注释 \r\n/** comment \r\n* \r\n*/ \r\n\r\njavadoc工具自动将 \r\n/** \r\n*/ \r\n风格的注释产生HTML文档。所以要特别注意使用这种风格的文档。使用C++风格用作个人 \r\n注释和说明,使用javadoc注释发布公共信息API文档。在public类、方法、成员变量前 \r\n都必须加适当的javadoc注释。 \r\n注释中格式: \r\n- @author 针对类 \r\n- @createdate \r\n- @param 描述方法需要接受的参数。如:@param newParam String 类型, \r\n在1~16个英文字符以内。 \r\n- @return 描述方法返回的参数。如:@return theReturnValue String 类型, \r\n在1~16个英文字符以内。 \r\n- @exception 描述方法可能掷出的违例。如:@exception java.sql.SQLException \r\n\r\n\r\n4、文件名命名规范\r\n------------------------------------------------------------- \r\n4.1 jsp文件\r\n - 显示页面\r\n 名词,每个单词都为小写,可以使用\"_\",例如: wiki_edit.jsp\r\n - 处理页面\r\n 动宾结构,每个单词都为小写,可以使用\"_\"\r\n4.2 包含文件\r\n 在程序中多次(三次或三次以上)用到的程序块,建议作为一个Include文以命名:\r\n Name.inc.jsp\r\n Name单词小写,jsp为其扩展名,例如: wiki_topic.inc.jsp\r\n \r\n5、页面名称的命名规范\r\n------------------------------------------------------------- \r\n5.1 有FRAME的页面命名\r\n命名的格式规范是①xxx.._②xxx.._③xxx.. .jsp,当然扩展名可以根据实际情况进行调整。\r\n ①xxx..部分用来表示页面在浏览器窗口所处的位置,\r\n 如:处于浏览器窗口的顶部则标识为top,其它情况依次类推。\r\n ②xxx..部分用来标识当前页面隶属于整个系统中的那一功能模块,\r\n 如:属于系统管理则被表示为sys,其它情况依次类推。\r\n ③xxx..部分用来标识当前页面所要完成的功能,\r\n 如:完成用户登录的功能则被标识为login,其它情况依次类推。\r\n\r\n5.2 不包含FRAME的页面命名\r\n 命名的格式规范是①XXX.._②XXX.. .jsp,当然扩展名可以根据实际情况进行调整。\r\n ①xxx..部分用来标识当前页面隶属于整个系统中的那一功能模块,\r\n 如:属于系统管理则被表示为sys,其它情况依次类推。\r\n ②xxx..部分用来标识当前页面所要完成的功能,\r\n 如:完成用户登录的功能则被标识为login,其它情况依次类推。\r\n\r\n 所有字母都为小写。\r\n 例: 主窗体命名为index.jsp。\r\n\r\n5.3 页面中脚本函数的命名规范\r\n 脚本函数都以webpm_xxxxxx..的方式命名,其中\r\n xxxxxx..表示函数所要实现的功能(动宾结构),所有字母一律小写。\r\n\r\n5.4 页面中HTML标记的命名规范\r\n 页面中所以HTML标记一律小写。\r\n\r\n5.5 Global(全局)变量的命名规范\r\n 全局变量遵循下列规则\r\n gname\r\n name要求首字母大写,如果该名称是又多个单词组成,每个单词的首字母都要大写。\r\n \r\n5.6 Cookie变量的命名规范\r\n Cookie变量命名\r\n sess_name Name所有首字母一律小写。\r\n \r\n5.7 Form(表单)的有关命名规范\r\n 表单的名字以及所有的页面元素全部小写,例如:orderform,textvalue \r\n —— 参看 数据库表字段命名规范\r\n\r\n5.8 页面脚本中所用内部变量命名规范\r\n 脚本内部所用变量的命名规范可参照本文变量命名的有关命名约定。\r\n\r\n6、系统后台数据库的有关命名规范\r\n------------------------------------------------------------- \r\n 约定:\r\n 表名参照如下命名规则,\r\n t_+scope+_name\r\n 其中:\r\n scope为模块范围缩写,小写。\r\n name为表的英文意思,一律小写。\r\n \r\n 字段名参照如下命名规则,\r\n f+name\r\n 其中:\r\n [name]为字段英文意思,首字母小写\r\n\r\n7 相关资料 \r\n------------------------------------------------------------- \r\n- java coding standards \r\n\r\n8 附录\r\n------------------------------------------------------------- \r\n整个页面程序的组织如下图:\r\n\r\nWebPM 目录组织请着重注意Src节点下的有关内容\r\n\r\n$\\webpm_java 项目的根目录\r\n├─bin 二进制可执行文件和控件(.exe, .dll, .ocx, etc)\r\n│ ├─Debug 内部debug版本\r\n│ └─Release 分发给客户的release版本\r\n├─db 数据库相关文件(例如:建库SQL文件、数据导出文件等)\r\n├─doc 项目文档目录\r\n│ ├─数据库设计 数据库设计文档\r\n│ ├─相关文件 相关文件\r\n│ ├─系统设计 系统设计文档\r\n│ └─项目管理 项目管理文档\r\n├─dist 发布给用户的安装程序\r\n├─test 测试程序源码目录\r\n└─src 源程序目录\r\n ├─components 客户端组件源程序目录\r\n │ ├─WebPrint \r\n │ └─… \r\n ├─lib 其它相关程序包\r\n ├─jsp 网站JSP源程序目录\r\n │ ├─images 图片资源\r\n │ ├─inc 头文件\r\n │ ├─pub 公共信息模块\r\n │ ├─[module] 其它模块\r\n │ └─… \r\n └─org java 程序目录\r\n ├─softme\r\n ├─webpm\r\n ├─pub 公共程序目录\r\n ├─servlet 程序目录\r\n ├─utility 工具程序目录\r\n ├─jwiki wiki程序目录\r\n ├─[module] 其它模块\r\n └─… \r\n[/code]\r\n----\r\n分类:[WebPM]','BrokenDoor','2002-02-20 22:22:06','2002-02-20 22:22:06',0,'浆糊',49),('安装说明','[no]\r\n具体安装步骤如下。\r\n1.在mysql中新建一个库,库名任意\r\n2.新建数据表,具体数据结构见doc/db中的数据库结构文件.\r\n3.数据库配置设置,修改config.xml :\r\n\r\n\r\nDriver:数据库驱动\r\nURL :数据库连接地址\r\nUserName:用户名\r\nPassword:密码\r\nhost:主机地址\r\nport:端口\r\n把\"yourdatebase\"设置为你刚才新建的库名\r\n\r\n4.确定你所用平台需要的config文件,所有config在conf目录下,把符合你平台的config文件改名为config.xml\r\n5.用ant编译原码,运行ant命令,将在war目录中形成webpm.war文件\r\n6.把webpm.war放到webapp的目录下\r\n7.启动服务器\r\n8.浏览器中输入 http://host:port/webpm/ \r\n便可以使用\r\n\r\n如果运行后出现中文乱码,请根据实际情况设置config.xml中的中文编码参数\r\n\r\n以上安装在 \r\nred hat7.2+mysql3.24+tomcat4.0 \r\nwindows2000+mysql3.24+tomcat4.0 \r\nwindows2000+mysql3.24+resin2.0\r\n上通过 \r\n[/no]\r\n\r\n有什么问题请到[安装问题]讨论','浆糊','2002-02-22 00:18:12','2002-02-22 00:18:12',0,'浆糊',90),('webpm CVS 使用指南','======================================================================= \r\nWebPM - v1.0 - CVS 使用指南 - 2001年12月27日 \r\n======================================================================= \r\n\r\n版本 1.0 \r\nCopyLeft (l) 2001 Softme Studio \r\n======================================================================= \r\n\r\nBrokenDoor 2001-12-27\r\n======================================================================= \r\n\r\n1.说明 \r\n======================================================================= \r\nCVS是一个版本控制系统,用于在多人开发环境下的源码的维护.从理论上CVS可以 \r\n维护任意的文本文档的开发,而不是局限于程序设计.CVS用copy-midify-merge \r\n变化表支持对文件的同时访问和修改. \r\n\r\n2.连接到WebPM项目的CVS \r\n======================================================================= \r\ncosoft要求开发人员使用ssh来访问cvs,这样才有写权限,所以首先要下载相应的 \r\nssh客户端软件。 在Linux下可以使用openssh,windows下可到http://www.ssh.com \r\n下载。 \r\n\r\n安装完成之后先用命令行测试能否连上cvs.cosoft.org.cn, 比如: \r\nssh -l yourname cvs.cosoft.org.cn \r\n\r\n接下来为cvs设置环境变量:CVS_RSH=ssh \r\n\r\n然后就可以直接使用cvs了 \r\n\r\ncvs -d :ext:yourname@cvs.cosoft.org.cn:/sfroot/cvs/webpm ... \r\n\r\n每执行一次cvs命令server会提示你输入密码,所以不用login。 \r\n如果经常使用可以用ssh自带的工具keygen制作公/私密钥对,将公用密钥上传到 \r\ncosoft,私用密钥放到本机的home/.ssh目录中,以后就自动验证不在要求输口令了。 \r\n\r\n3.一般的常用的命令 \r\n======================================================================= \r\ncvs checkout \r\n从仓库中得到某版本的代码.在本地产生一个copy \r\n\r\ncvs update \r\n从仓库中更新本地的代码 \r\n\r\ncvs commit \r\n将本地修改后的代码提交仓库,并产生新版本. \r\n\r\ncvs add \r\n添加新的文件到仓库,在cvs commit命令后生效. \r\n\r\n一般的流程是 \r\ncvs checkout or cvs update \r\n用你喜欢的编辑器修改本地副本 \r\ncvs commit \r\n提交修改. \r\n\r\n4.浏览 WebPM CVS 仓库 \r\n======================================================================= \r\n你可以通过Web浏览器直接访问 WebPM 的 CVS 仓库,以确定目前存在的模块和版本: \r\nhttp://cvs.cosoft.org.cn/cgi-bin/cvsweb.cgi?cvsroot=webpm \r\n\r\n5. cosoft 二级域名 \r\n======================================================================= \r\n由于Apache 的二级域名服务可能不被某些环境支持,如果出现解析的问题,可以在 \r\n本机的DNS服务器设置中加入如下的地址: \r\n211.100.7.111 \r\n\r\n6. 资源 \r\n======================================================================= \r\n更多的关于CVS使用的问题,请到小组:“CVS我学我用” \r\nhttp://www.smiling.com.cn/group/homepage.ecgi?group_id=16967 \r\n\r\n7. cosoft SSH2的使用 \r\n======================================================================= \r\n7.1 获取SSH2客户端 \r\nhttp://the.wiretapped.net/security/cryptography/ssh/ \r\n含有大量的工具,另外windows用户推荐使用 \r\nhttp://the.wiretapped.net/security/cryptography/ssh/SSH/SSHWinClient-3.1.0-build235.exe \r\n\r\n7.2 设置环境变量 \r\nset CVS_RSH = ssh2 \r\n\r\n7.3 修改WinCVS配置 \r\n在 Admin => Preferences 选项中设置: \r\n1) CVS_ROOT \r\n:ext:username@cvs.cosoft.org.cn:/sfroot/cvs/webpm \r\n\r\n2) Authentication \r\nSSH Server \r\n\r\n3) Ports 选项卡 \r\n激活\"Check for an alternate rsh name\" , 设置为 ssh2 \r\n\r\n4) WinCVS 选项卡 \r\n选择 HOME folder \r\n\r\n7.4 Check-Out 源程序 \r\n在 Create => Checkout module 选项中设置: \r\n1) module name \r\n可以在cosoft Web CVS 中浏览可以选择的模块名称: \r\n例如: webpm_wiki \r\n\r\n2) Local folder to checkout to \r\n本地的 checkout 路径 \r\n例如:G:\\Softme\\WebPM\\src \r\n\r\n点击 OK 按钮,会有一个DOS窗口提式输入用户密码。 \r\n\r\n============================================================== \r\n-----\r\n分类: [WebPM]\r\n \r\n','BrokenDoor','2002-01-23 15:06:10','2002-01-23 15:06:10',0,'N/A',50),('自由软件开发讨论',' 自由软件工程讨论 \r\n主题: 自由软件开发讨论! \r\n作者: admin (61.149.7.---) \r\n时间: 2002-01-14 22:26\r\n点击: 13 \r\n\r\n自由软件的开发 \r\n确定一个核心开发团体,他们有的不仅仅是对这个项目的爱好,他们同时也是有着迫切需求的用户,他们对项目需求有着切身的体会,同时具备了开发这个项目所需的背景知识,经验,及愿意把时间和精力花在上面!这是自由软件项目的成功的前提! \r\n\r\n成功推动成功,它的魅力在于我们可以看到我们努力的成果,就象看着一个婴儿已经出世,我们为之欣喜,但同时我们还会看到它走起来还是脚步蹒跚,我们就会下决心去把它进一步完善。在这里就是说我们尽量有一个可用的,可运行的版本来鼓励我们这个团队走向更大的成功。 \r\n\r\n已对于项目创始人来说,他要有百折不挠的决心,象bronkendoor所说的\"对这个项目有不做到不罢休的决心,要准备好没有人自己一个人也要作到底的决心\"。如果你承担了一个子项目,那么你就对整个团体做出了承诺。每个成员都把自己的智力和时间贡献出来,从而会鼓励其他的成员贡献出更多。 \r\n\r\n有很多开发者email给你,要加入你的项目,这样会给你很多鼓励,但同时我们也需要了解新的开发者他的技能和经验,以及他愿意付出的时间和智慧是多少,他到底可以在这个项目中承担多少工作。记住一个teamleader不仅需要激情,也需要仔细的考虑,某个成员到底会为这个项目做出多少贡献!从而合理的分配项目的开发进度。软件开发是一项艰苦的脑力劳动,而不是我们的休闲方式! \r\n\r\n在核心开发人员之间要有定期的,有效的交流方式,项目管理员要善于聆听每个成员的建议,并进行讨论来确定项目发展的目标,并且在一段时间内让项目小组的每个人看到项目前进的步伐,这样不会使项目浅搁! \r\n\r\n采用模块化,OO的方法来开发整个项目。TeamLeader来控制main,并给出清晰的,图形化的系统结构,从而使每个成员都明白自己在项目中的角色。尽量采用松偶合的模块,并具有高度的可扩展性。不会使某个子项目的进度而影响整个项目的运行。 \r\n\r\n可以通过CVS分支(branch)来包容项目不同的发展方向,每个人必须有良好的编码习惯,并愿意不断的学习。 \r\n我相信只有付出,才有回报!\r\n\r\n----\r\n主题: RE: 自由软件开发讨论! \r\n作者: brokendoor (61.141.204.---) \r\n时间: 2002-01-22 10:55\r\n点击: 1 \r\n\r\n呵呵,那段话是一位早期的webpm开发者说的。虽然目前他暂时退出了。但是我依然表示谅解,同时也非常感谢他对我们的鼓励!\r\n \r\n----\r\n他说的和我们现在地情况很像阿,虽然我们迈出了第一步,但后面的工作还有很多。需要更多的人员加入,来支持我们的项目。现在要宣传我们的项目,以及它实现的价值,我们需要支持,毕竟我们现在还很孤单...\r\n --浆糊 2002-01-23 \r\n----\r\n分类:[自由软件开发]','BrokenDoor','2002-01-24 15:30:40','2002-01-24 15:30:40',0,'N/A',51),('bugn','这里是我组织的[url=http://dimension5.org/modules/wiki]wiki[/url]','61.157.85.2','2002-01-23 18:20:52','2002-01-23 18:20:52',0,'N/A',52),('takaka','[user=takaka]\r\ntakaka 是个好战士啊,哥们拉我一把吧,一个PLMM 在追我啊,快帮我解决了她。。踏冰先谢谢你了。\r\n----\r\ntakaka, 我们找了你快半年了!不会用的话来问我们啊! BrokenDoor 2002/1/31\r\n----\r\ntakaka,你能不能来留个言,踏冰想你了。呵!\r\n----\r\n[破门],不用这么夸张吧,我只是这两个月忙一些,并没有失踪半年啊。我现在有点会用wiki了。\r\n\r\ntakaka,好久不见了啊,好吗? ---notyy\r\n-----\r\ntakaka过得不太好,最近报表缠身。\r\n-----\r\n正在向领导争取,有望在3月底4月初重见天日。\r\n刚才看了一下源码,看不懂的地方太多了,是不是可以开一个[webpm源码分析]的专题呢?\r\n---takaka\r\n----\r\ntakaka及家人\r\n[img]http://210.192.109.59:8080/webpm/doc/users/takaka/2.jpg[/img]','61.167.164.161','2002-02-07 22:40:23','2002-03-06 17:03:31',0,'takaka',53),('工作流','我们在这里讨论一下,如何在 WebPM 中引入 工作流。 [踏冰]\r\n\r\n----\r\n请各位高人指教:[NRFF工作流引入方案(部分1/10)|http://www.tabing.8u8.com/project_nrff/Project_web/workflow/nrffworkflow.zip]\r\n----\r\n好的!\r\n\r\n这里作为工作流相关知识介绍吧,去[webpm_info 讨论区]讨论如何引入工作流..BrokenDoor - 2002/1/24\r\n----\r\n\r\n\'\'\'概念\'\'\'\r\n\r\n* GroupWare\r\n\r\n* [工作流程管理简介] - by BrokenDoor - 2002/2/6\r\n\r\n\'\'\'标准\'\'\'\r\n* [WfMC] - Workflow Management Coalition\r\n\r\n----\r\n分类:[WebPM]','61.167.164.161','2002-02-09 15:16:22','2002-02-09 15:16:22',0,'61.138.18.13',54),('JAVA 技术','CoolJavaBeanLibrary ---- \'\'将scaler的文章转移到这里了,看看大家有没有好的推荐? BrokenDoor 2002/3/13\'\' \r\n\r\n谁新开的主题,也不留言就跑了。。什么意思???《踏冰》\r\n\r\n我开的,我想大家应该对这个东东话题比较多,自己建就是了... BrokenDoor 2002/1/23\r\n\r\n----\r\n[Java基础]\r\n\r\nWebService --java实现\r\nwebservice为什么是Java 技术?\r\n\r\n[J2EE]\r\n----\r\n分类: [主题分类]','61.167.164.161','2002-01-25 10:58:19','2002-03-13 21:33:10',0,'BrokenDoor',55),('NeedRecharge','NeedRecharge 自由软件工作室 由《踏冰》发起,由于 《踏冰》菜的很,暂时没有什么成绩,感兴趣的朋友可以访问[url=http://www.tabing.8u8.com]《踏冰》 的主页 [/url]','61.167.164.161','2002-01-23 22:31:57','2002-01-23 22:31:57',0,'N/A',56),('CopyLeft','\'\'\'经过WebPM小组主要成员讨论,[webpm_wiki] 1.0版本采用[GNU通用公共许可证(GPL)]\'\'\'\r\nBrokenDoor 2002/2/6\r\n----\r\nbugn有个问题,能否先把webpm的copyright和license明确写出来,不要就干写个copyleft,可能很多人搞不明白。另外就是webpm我觉得务必要支持多语言才好,一开始就做进去。\r\n--我也搞不懂啊?所以只好先CopyLeft?了,反正开放原码是肯定了,最终选择合适的版权协议还要经过大家讨论。 - BrokenDoor - 2002/1/24\r\n----\r\nYour License:\r\n(copyright is different from the license)\r\nGPL/BSD ? \r\n由于对于GPL/BSD等版权协议不够了解,暂时保留版权,仅开放原码。 \r\n有什么好建议和介绍请到 OpenSource, [自由软件] 讨论区 \r\nBrokenDoor 2002/1/29\r\n\r\n你这里的保留版权意味着All rights reserved, 就是别人无法从你的代码得到任何好处。\r\n另外如果你的代码从GPL的代码衍生过来的话,你就无法做到All rights reserved,你先在想的虽然是Open source,但做的仍是Proprietary软件。而且你用了衍生代码,就侵犯了GPL的协议,除非你也是GNU的。你可以附加条款,但是不能违反任何原来GPL的一条。\r\n\r\nGPL和BSD的主要区别是GPL软件无法用在Proprietary软件里,而BSD则允许。所以GPL叫copyleft,而BSD则准许别人任意使用。GPL保证你的软件以及从你的软件来的衍生产品都必须是GPL的,也就是说别人不能占有它。国内不少人没搞懂这一点,以为从别人的代码改一改就是自己的了。例如XX公司开发appserver竟然是基于jboss的。\r\n\r\n另外Open source和免费完全是两回事。你首先要明确的是你的软件是否会向用户收取费用。\r\n\r\n如果你要看有关的中文文档可以到[url=http://aka.org.cn]AKA[/url],那里讲得比较详细。\r\n下面我转贴一部分。\r\n\r\n[GNU通用公共许可证(GPL)]\r\n[为什么你不应使用LGPL发布下一个库?]\r\n\r\n----\r\n分类:[WebPM] [自由软件]','BrokenDoor','2002-02-06 04:33:48','2002-02-06 04:33:48',0,'202.105.101.159',57),('自由软件','这里是自由软件有关资料。\r\n\r\n* [自由软件开发] - 有关自由软件开发的讨论\r\n-----\r\n\r\n----\r\n分类: [主题分类]\r\n参考:[自由软件开发]','BrokenDoor','2002-01-24 21:37:58','2002-01-24 21:37:58',0,'N/A',58),('OpenSource','请到[自由软件]讨论区...','BrokenDoor','2002-01-24 00:10:15','2002-01-24 00:10:15',0,'N/A',59),('webpm_info 讨论区','在这里讨论 WebPM 项目管理部分的主要功能...\r\n----\r\n问题1: [WebPM 与 SourceForge 的异同]? \r\n\r\n问题2: [如何在 WebPM 项目中引入工作流管理]?\r\n\r\n\r\n----\r\n分类:[WebPM] | [webpm_info]\r\n','BrokenDoor','2002-01-24 21:39:06','2002-01-24 21:39:06',0,'N/A',60),('webpm_info','WebPM 项目管理部分\r\n\r\n\'\'\'主要内容\'\'\'\r\n\'\' 标记\'\'\r\n----\r\n(x) -- 用户故事优先级\r\n- x -- x个100%工作日 \r\n- TBD -- 未预计的故事 \r\n\r\n\'\'\'会员注册和资料修改\'\'\'\r\n-----------------------------------------------------------------\r\n1.新用户注册: (1) - 0.5\r\n系统应提供一个界面,让新用户输入基本信息(包括:用户名、口令、昵称、性别、年龄、Email、等等),并反馈其输入的信息、成功与否、其它信息等; \r\n\r\n2.查看并修改个人信息:(1) - 1\r\n系统应提供一个界面让用户查看并修改个人信息,这个界面应与注册界面相似; \r\n\r\n3.密码提示: (2) - 1\r\n系统应提供一个界面让用户安全地得到忘记的密码。 \r\n\r\n4.用户注销: (3) - 0.5\r\n提供界面让用户注销(并不用户信息删除,只做注销标记) \r\n\r\n5.功能设置: (3) - 1\r\n提供用户按个人喜好设定与页面或功能有关参数(如:每页缺省行数,Email提醒功能等) \r\n\r\n6.删除用户: (3) - 1\r\n为管理员提供一个界面,可以得到已注销用户的相关信息并安全地删除。 \r\n\r\n7.用户信息管理: (3) - 1\r\n为管理员提供一个界面,可以得到已注册用户的列表,相关统计等,同时可能修改单个用户的部分信息。 \r\n\r\n\'\'\'项目信息发布\'\'\'\r\n-----------------------------------------------------------------\r\n1.项目申请: (1) - 1\r\n新为已注册的用户提供个人信息主页,在个人信息主页中提供一个链接,允许用户填写新项目申请, \r\n提供项目名称、不重复的项目简称(缩写), 以及必要的描述信息。 \r\n\r\n2.项目确认: (1) - 1\r\n给系统管理员提供新提交的项目申请列表,可以查询项目申请内容,并进行审核确认。 \r\n系统管理员审核确认后项目正式生效,发布人自动成为该项目的管理员。\r\n需要通过邮件反馈项目确认消息,并且要在个人信息主页有明显的提示。 \r\n\r\n3.项目注销: (2) - 2\r\n在个人信息主页列出用户拥有的项目名称,提供申请注销选定项目的链接。 \r\n给项目管理员提供一个界面填写项目注销申请。 \r\n\r\n4.项目注销确认:(2) - 1\r\n给系统管理员提供一个界面查询申请注销的项目,并进行确认操作。 \r\n系统管理员审核确认后项目正式注销,相关成员自动从该项目中退出。\r\n需要通过邮件反馈项目注销确认消息,并且要在项目成员个人信息主页有明显的提示。 \r\n\r\n5.项目接管: (3) - TBD \r\n项目成员(包括原项目管理员)可以通过个人信息主页中的链接提出申请接管已经注销或关闭的项目。 (需要系统管理员确认) \r\n\r\n6.指定管理员: (3) - 0.5\r\n系统管理员可以为项目重新指定新的管理员。 \r\n\r\n7.关闭项目: (3) - 1\r\n系统管理员可以通过一个操作界面强制关闭已发布的项目。 \r\n\r\n\r\n\'\'\'项目信息分类管理 \'\'\'\r\n-----------------------------------------------------------------\r\n1.项目分类目录: (3) - TBD\r\n系统管理员可以通过维护界面新建或者修改项目分类的目录信息。项目分类目录是多级树型结构的。 \r\n\r\n2.项目分类: (3) - TBD\r\n项目管理员可以修改项目的分类信息,一个项目可以放置在多个项目分类目录下。 \r\n\r\n\'\'\'项目检索查询\'\'\'\r\n-----------------------------------------------------------------\r\n1.会员项目检索 (1) - 2\r\n所有注册用户可以通过个性化页面查询和检索项目信息。查询方式有两种: \r\n一是通过关键字快速查询; 二是通过项目查询表单进行自定义查询。 \r\n\r\n2.公共项目检索 (2) - 1\r\n未注册的用户(访客)可以通过公共网站主页查询和检索项目信息。 \r\n\r\n\'\'\'项目人力资源组织\'\'\'\r\n-----------------------------------------------------------------\r\n1. 信息发布: (2) - TBD\r\n为项目管理员提供一个项目信息管理界面,允许项目管理员发布和维护人力资源需求信息。 \r\n包括工作内容、技能要求、时间期限等内容。 \r\n\r\n2. 加入项目: (2) - 1\r\n注册会员查看项目人力资源需求时,可以申请加入并可以要求承担某一份空缺。 \r\n\r\n3. 确认加入: (3) - 1\r\n项目管理员可以在项目成员列表中看到会员申请,并可以拒绝或者确认。\r\n该信息自动通过 e-mail 或短消息发送给申请者。 \r\n\r\n4. 申请退出: (3) - 1\r\n项目成员可以在个性化主页申请退出项目。\r\n\r\n5. 退出确认: (3) - 1\r\n项目管理员在成员列表中可以确认成员的退出申请。\r\n\r\n6. 强制退出: (3) - 1\r\n项目管理员可以强制项目成员退出,系统自动给成员发送通知信息。 \r\n----\r\n参考:[webpm_info 讨论区]\r\n----\r\n分类:[WebPM]','BrokenDoor','2002-01-24 10:23:20','2002-01-24 10:23:20',0,'N/A',61),('GNU通用公共许可证(GPL)','GNU General Public License\r\nGNU通用公共许可证\r\n作者:www.gnu.org\r\n\r\n翻译: 佚名\r\n\r\n--------------------------------------------------------------------------------\r\n\r\n\r\n 下面的正文是自由软件基金会GNU通用公共许可证原始文档的副本。Linux操作系统以及与它有关的大量软件是在GPL的推动下开发和发布的。 你将看到:如果你打算为了发布的目的修改,更新或改进任何受通用公共许可证约束的软件,你所修改的软件软件同样必须受到GNU通用许可证条款的约束。 \r\n\r\n\r\n--------------------------------------------------------------------------------\r\n\r\nGNU通用公共许可证 \r\n1991.6 第二版 \r\n\r\n版权所有(C)1989,1991 Free Software foundation, Inc. \r\n675 Mass Ave, Cambridge, MA02139, USA \r\n允许每个人复制和发布这一许可证原始文档的副本,但绝对不允许对它进行任何修改。 \r\n\r\n\r\n--------------------------------------------------------------------------------\r\n\r\n序言 \r\n\r\n 大多数软件许可证决意剥夺你的共享和修改软件的自由。对比之下,GNU通用公共许可证力图保证你的共享和修改自由软件的自由。——保证自由软件对所有用户是自由的。GPL适用于大多数自由软件基金会的软件,以及由使用这些软件而承担义务的作者所开发的软件。(自由软件基金会的其他一些软件受GNU库通用许可证的保护)。你也可以将它用到你的程序中。 \r\n\r\n\r\n 当我们谈到自由软件(free software)时,我们指的是自由而不是价格。 我们的GNU通用公共许可证决意保证你有发布自由软件的自由(如果你愿意,你可以对此项服务收取一定的费用);保证你能收到源程序或者在你需要时能得到 它;保证你能修改软件或将它的一部分用于新的自由软件;而且还保证你知道你能做这些事情。 \r\n\r\n\r\n 为了保护你的权利,我们需要作出规定:禁止任何人不承认你的权利,或者要求你放弃这些权利。如果你修改了自由软件或者发布了软件的副本,这些规定就转化为你的责任。 \r\n\r\n\r\n 例如,如果你发布这样一个程序的副本,不管是收费的还是免费的,你必须 将你具有的一切权利给予你的接受者;你必须保证他们能收到或得到源程序;并且将这些条款给他们看,使他们知道他们有这样的权利。 \r\n\r\n\r\n 我们采取两项措施来保护你的权利。 \r\n(1)给软件以版权保护(copyright)。 \r\n(2)给你提供许可证。它给你复制,发布和修改这些软件的法律许可。 \r\n\r\n\r\n 同样,为了保护每个作者和我们自己,我们需要清楚地让每个人明白,自由软件没有担保(no warranty)。如果由于其他某个人修改了软件,并继续加以传播。我们需要它的接受者明白:他们所得到的并不是原来的自由软件。由其他人引入的任何问题,不应损害原作者的声誉。\r\n\r\n \r\n 最后,任何自由软件不断受到软件专利的威胁。我们希望避免这样的风险,自由软件的再发布者以个人名义获得专利许可证。事实上,将软件变为私有。为防止这一点,我们必须明确:任何专利必须以允许每个人自由使用为前提,否则就不准许有专利。 \r\n\r\n\r\n下面是有关复制,发布和修改的确切的条款和条件。 \r\n\r\n\r\n\r\n有关复制,发布和修改的条款和条件 \r\n\r\n0. 此许可证适用于任何包含版权所有者声明的程序和其他作品,版权所有者在声明中明确说明程序和作品可以在GPL条款的约束下发布。下面提到的“程序”指的是任何这样的程序或作品。而“基于程序的作品”指的是程序或者任何受版权法约束的衍生作品。也就是说包含程序或程序的一部分的作品。可以是原封不动的,或经过修改的和/或翻译成其他语言的(程序)。在下文中,翻译包含在修改的条款中。每个许可证接受人(licensee)用你来称呼。\r\n\r\n\r\n许可证条款不适用于复制,发布和修改以外的活动。这些活动超出这些条款 的范围。运行程序的活动不受条款的限止。仅当程序的输出构成基于程序作品的 内容时,这一条款才适用(如果只运行程序就关)。是否普遍适用取决于程序具体用来做什么。 \r\n\r\n1. 只要你在每一副本上明显和恰当地出版版权声明和不承担担保的声明,保持此许可证的声明和没有担保的声明完整无损,并和程序一起给每个其他的程序接受者一份许可证的副本,你就可以用任何媒体复制和发布你收到的原始的程序的源代码。 \r\n\r\n\r\n你可以为转让副本的实际行动收取一定费用。你也有权选择提供担保以换取一定的费用。 \r\n\r\n2. 你可以修改程序的一个或几个副本或程序的任何部分,以此形成基于程序的作品。只要你同时满足下面的所有条件,你就可以按前面第一款的要求复制和发布这一经过修改的程序或作品。 \r\n\r\n\r\na) 你必须在修改的文件中附有明确的说明:你修改了这一文件及具体的修改日期。 \r\nb) 你必须使你发布或出版的作品(它包含程序的全部或一部分,或包含由程序的全部或部分衍生的作品)允许第三方作为整体按许可证条款免费使用。 \r\nc) 如果修改的程序在运行时以交互方式读取命令,你必须使它在开始进入常规的交互使用方式时打印或显示声明:包括适当的版权声明和没有担保的声明 (或者你提供担保的声明);用户可以按此许可证条款重新发布程序的说明;并告诉用户如何看到这一许可证的副本。(例外的情况:如果原始程序以交互方式工作,它并不打印这样的声明,你的基于程序的作品也就不用打印声明)。 \r\n\r\n\r\n这些要求适用于修改了的作品的整体。如果能够确定作品的一部分并非程序的衍生产品,可以合理地认为这部分是独立的,是不同的作品。当你将它作为独立作品发布时,它不受此许可证和它的条款的约束。但是当你将这部分作为基于程序的作品的一部分发布时,作为整体它将受到许可证条款约束。准予其他许可证持有人的使用范围扩大到整个产品。也就是每个部分,不管它是谁写的。 \r\n\r\n\r\n因此,本条款的意图不在于索取权利;或剥夺全部由你写成的作品的权利。 而是履行权利来控制基于程序的集体作品或衍生作品的发布。 \r\n\r\n\r\n此外,将与程序无关的作品和该程序或基于程序的作品一起放在存贮体或发布媒体的同一卷上,并不导致将其他作品置于此许可证的约束范围之内。 \r\n\r\n3. 你可以以目标码或可执行形式复制或发布程序(或符合第2款的基于程序的作品),只要你遵守前面的第1,2款,并同时满足下列3条中的1条。 \r\na)在通常用作软件交换的媒体上,和目标码一起附有机器可读的完整的源码。这些源码的发布应符合上面第1,2款的要求。或者 \r\nb)在通常用作软件交换的媒体上,和目标码一起,附有给第三方提供相应的机器可读的源码的书面报价。有效期不少于3年,费用不超过实际完成源程序发布的实际成本。源码的发布应符合上面的第1,2款的要求。或者 \r\nc)和目标码一起,附有你收到的发布源码的报价信息。(这一条款只适用于非商业性发布,而且你只收到程序的目标码或可执行代码和按b款要求提供 的报价)。 \r\n\r\n\r\n作品的源码指的是对作品进行修改最优先择取的形式。对可执行的作品讲, 完整的源码包括:所有模块的所有源程序,加上有关的接口的定义,加上控制可执行作品的安装和编译的script。作为特殊例外,发布的源码不必包含任何常规发布的供可执行代码在上面运行的操作系统的主要组成部分(如编译程序,内核等)。除非这些组成部分和可执行作品结合在一起。 \r\n\r\n\r\n如果采用提供对指定地点的访问和复制的方式发布可执行码或目标码,那么,提供对同一地点的访问和复制源码可以算作源码的发布,即使第三方不强求与目标码一起复制源码。 \r\n\r\n4. 除非你明确按许可证提出的要求去做,否则你不能复制,修改,转发许可证和发布程序。任何试图用其他方式复制,修改,转发许可证和发布程序是无效的。而且将自动结束许可证赋予你的权利。然而,对那些从你那里按许可证条款得到副本和权利的人们,只要他们继续全面履行条款,许可证赋予他们的权利仍然有效。 \r\n\r\n5. 你没有在许可证上签字,因而你没有必要一定接受这一许可证。然而,没有任何其他东西赋予你修改和发布程序及其衍生作品的权利。如果你不接受许可证,这些行为是法律禁止的。因此,如果你修改或发布程序(或任何基于程序的作品),你就表明你接受这一许可证以及它的所有有关复制,发布和修改程序或基于程序的作品的条款和条件。 \r\n\r\n6. 每当你重新发布程序(或任何基于程序的作品)时,接受者自动从原始许可证颁发者那里接到受这些条款和条件支配的复制,发布或修改程序的许可证。你不可以对接受者履行这里赋予他们的权利强加其他限制。你也没有强求第三方履行许可证条款的义务。 \r\n\r\n7. 如果由于法院判决或违反专利的指控或任何其他原因(不限于专利问题)的结果,强加于你的条件(不管是法院判决,协议或其他)和许可证的条件有冲突。他们也不能用许可证条款为你开脱。在你不能同时满足本许可证规定的义务及其他相关的义务时,作为结果,你可以根本不发布程序。例如,如果某一专利许可证不允许所有那些直接或间接从你那里接受副本的人们在不付专利费的情况下重新发布程序,唯一能同时满足两方面要求的办法是停止发布程序。 \r\n\r\n\r\n如果本条款的任何部分在特定的环境下无效或无法实施,就使用条款的其余 部分。并将条款作为整体用于其他环境。 \r\n\r\n\r\n本条款的目的不在于引诱你侵犯专利或其他财产权的要求,或争论这种要求 的有效性。本条款的主要目的在于保护自由软件发布系统的完整性。它是通过通 用公共许可证的应用来实现的。许多人坚持应用这一系统,已经为通过这一系统发布大量自由软件作出慷慨的供献。作者/捐献者有权决定他/她是否通过任何其他系统发布软件。许可证持有人不能强制这种选择。 \r\n\r\n本节的目的在于明确说明许可证其余部分可能产生的结果。 \r\n\r\n8. 如果由于专利或者由于有版权的接口问题使程序在某些国家的发布和使用受到限止,将此程序置于许可证约束下的原始版权拥有者可以增加限止发布地区的条款,将这些国家明确排除在外。并在这些国家以外的地区发布程序。在这种情况下,许可证包含的限止条款和许可证正文一样有效。 \r\n\r\n9. 自由软件基金会可能随时出版通用公共许可证的修改版或新版。新版和当前的版本在原则上保持一致,但在提到新问题时或有关事项时,在细节上可能出现差别。 \r\n\r\n\r\n每一版本都有不同的版本号。如果程序指定适用于它的许可证版本号以及“任何更新的版本”。你有权选择遵循指定的版本或自由软件基金会以后出版的新版本,如果程序未指定许可证版本,你可选择自由软件基金会已经出版的任何版本。 \r\n\r\n10. 如果你愿意将程序的一部分结合到其他自由程序中,而它们的发布条件不同。写信给作者,要求准予使用。如果是自由软件基金会加以版权保护的软件, 写信给自由软件基金会。我们有时会作为例外的情况处理。我们的决定受两个主要目标的指导。这两个主要目标是:我们的自由软件的衍生作品继续保持自由状态。以及从整体上促进软件的共享和重复利用。 \r\n\r\n\r\n没有担保 \r\n\r\n11. 由于程序准予免费使用,在适用法准许的范围内,对程序没有担保。除非 另有书面说明,版权所有者和/或其他提供程序的人们“一样”不提供任何类型的担保。不论是明确的,还是隐含的。包括但不限于隐含的适销和适合特定用途的保证。全部的风险,如程序的质量和性能问题都由你来承担。如果程序出现缺陷,你承担所有必要的服务,修复和改正的费用。 \r\n\r\n12. 除非适用法或书面协议的要求,在任何情况下,任何版权所有者或任何按许可证条款修改和发布程序的人们都不对你的损失负有任何责任。包括由于使用或不能使用程序引起的任何一般的,特殊的,偶然发生的或重大的损失(包括但不限于数据的损失,或者数据变得不精确,或者你或第三方的持续的损失,或者程序不能和其他程序协调运行等)。即使版权所有者和其他人提到这种损失的可能性也不例外。 \r\n\r\n\r\n条款和条件结束 \r\n\r\n\r\n如何将这些条款用到你的新程序 \r\n\r\n如果你开发了新程序,而且你需要它得到公众最大限度的利用。要做到这一点的最好办法是将它变为自由软件。使得每个人都能在遵守条款的基础上对它进行修改和重新发布。 \r\n\r\n\r\n为了做到这一点,给程序附上下列声明。最安全的方式是将它放在每个源程序的开头,以便最有效地传递拒绝担保的信息。每个文件至少应有“版权所有” 行以及在什么地方能看到声明全文的说明。 \r\n\r\n<用一行空间给出程序的名称和它用来做什么的简单说明> \r\n版权所有(C) 19XX <作者姓名> \r\n\r\n\r\n这一程序是自由软件,你可以遵照自由软件基金会出版的GNU通用公共许可 证条款来修改和重新发布这一程序。或者用许可证的第二版,或者(根据你的选 择)用任何更新的版本。 发布这一程序的目的是希望它有用,但没有任何担保。甚至没有适合特定目的的隐含的担保。更详细的情况请参阅GNU通用公共许可证。 你应该已经和程序一起收到一份GNU通用公共许可证的副本。如果还没有, \r\n写信给: \r\nThe Free Software Foundation, Inc., 675 Mass Ave, Cambridge, \r\nMA02139, USA \r\n\r\n\r\n还应加上如何和你保持联系的信息。 \r\n\r\n如果程序以交互方式进行工作,当它开始进入交互方式工作时,使它输出类似下面的简短声明:\r\n\r\n \r\nGnomovision 第69版, 版权所有(C) 19XX, 作者姓名, \r\nGnomovision绝对没有担保。 要知道详细情况,请输入‘show w’。 \r\n这是自由软件,欢迎你遵守一定的条件重新发布它,要知道详细情况, \r\n请输入‘show c’。 \r\n\r\n假设的命令‘show w’和‘show c’应显示通用公共许可证的相应条款。当然,你使用的命令名称可以不同于‘show w’和‘show c’。根据你的程序的具 体情况,也可以用菜单或鼠标选项来显示这些条款。 \r\n\r\n如果需要,你应该取得你的上司(如果你是程序员)或你的学校签署放弃程序版权的声明。下面只是一个例子,你应该改变相应的名称: \r\n\r\n\r\nYoyodyne公司以此方式放弃James Harker \r\n所写的 Gnomovision程序的全部版权利益。 \r\n,1989.4.1 \r\nTy coon付总裁 \r\n\r\n这一许可证不允许你将程序并入专用程序。如果你的程序是一个子程序库。 你可能会认为用库的方式和专用应用程序连接更有用。如果这是你想做的事,使用GNU库通用公共许可证(LGPL)代替本许可证。 \r\n\r\n \r\n\r\n\r\n--------------------------------------------------------------------------------\r\n\r\n','61.157.85.2','2002-01-24 01:08:27','2002-01-24 01:08:27',0,'N/A',62),('为什么你不应使用LGPL发布下一个库?',' \r\nWhy you shouldn\'t use the Library GPL for your next library\r\n为什么你不应该使用LGPL发布你的下一个库\r\n\r\n作者 Richard Stallman \r\n\r\n翻译:worm[AKA] \r\n\r\n\r\n--------------------------------------------------------------------------------\r\n\r\n GNU计划在使用库时有两个首要的许可证.一个是GNU LGPL(库GPL);另一个是普通的GNU GPL.选择不同的许可有很大的不同:选择LGPL允许在私有程序中使用该库;选择普通的GPL则只允许在自由软件中使用它.\r\n\r\n 关于哪一种许可证对指定的库是最好的这一问题实际上是一个策略问题,它取决于实际情况.当前,大多数的GNU库被采用LGPL,这意味着我们只使用着其中的一个策略,而忽略了另一个. 所以现在我们在寻求更多以普通的GPL许可证形式发布的库.\r\n\r\n 私有软件开发者有金钱上的优势;自由软件开发者需要相互之间利用各自的优势.对一个库采用普通的GPL对自由软件开发者的优势要大于对私有软件开发者: 他们可以使用的库对于私有软件开发者是不可利用的.\r\n\r\n 使用普通的GPL并不是对于所有的库都有好处.在某些情况下更有理由来使用LGPL.最常见的情况就是当一个自由库的特性可以很容易地被私有软件以其他可替代库来实现.在这种情况下,库不能给与自由软件任何特别的优势,因而最好还是为LGPL发布该库.\r\n\r\n 这也就是为什么我们为GNU C 库选择LGPL.总之,有很多的其他C库;我们使用GPL发布该库,将迫使私有软件开发者不得不使用其它的库--对他们来说这不成问题,而我们则有了麻烦.\r\n\r\n 然而,当一个库所提供的功能是非常独特的时候,如GNU Readline, 情况就大不一样了. Readline库可实现输入编辑和记录交互式程序操作,这在别处通常是不可多得. 在GPL下发布它并限制它只能在自由程序中使用, 这我们的社团是一个重要的促进.至少今天某个应用程序之所以是自由软件,只是因为它必需要用到Readline.\r\n\r\n 如果我们收集一些强大的、私有软件中没有相类似东西的、采用GPL的库,它们将提供一系列有用的模块用于新的自由软件的构造. 这对于将来的自由软件开发将是一个显著的优势, 一些项目将为了使用这些库而考虑使软件自由化. 大学的项目是易于被影响的;而且今天,随着某些公司开始考虑使软件自由化, 甚至一些商业项目也会由此受到影响.\r\n\r\n 私有软件开发者试图否认自由竞争的重要性, 他们会拼命说服作者不要将库使用GPL来发布. 例如,他们会呼吁利己主义,信誓旦旦地说如果我们让他们在私有软件产品中使用代码,将有“更多的用户”用到该库. 流行是一种诱惑,它使一个库开发者倾向于相信这种观点:社会首先需要的是促进一种库的流行;.\r\n\r\n 但是我们不应该听从这种诱惑,因为如果我们联合起来,我们可以做得更好.我们这些自由软件开发者应该相互支持. 通过发布只能为自由软件使用的库,我们可以互相帮助,使彼此的自由软件包优于其它的私有替代品. 整个自由软件运动将会有更多的机会,因为自由软件作为一个整体将会在竞争中表现更佳.\r\n\r\n 因为\"LGPL(Library GPL)\"的称呼传达了关于这一问题的错误观点,我们计划将称呼改为\"次级GPL(Lesser GPL)\".事实上要更换名称要花一定的时间,但你不必再等--你可以现在就发布应用GPL许可证的库.\r\n\r\n\r\n--------------------------------------------------------------------------------\r\n\r\n校对: waterbird[AKA] \r\n','61.157.85.2','2002-01-24 01:09:12','2002-01-24 01:09:12',0,'N/A',63),('WebPM 与 SourceForge 的异同','WebPM和SourceForge有什么异同点?\r\n\'\'个人的感觉:\'\'SourceForge 是一个复杂而优秀的网络项目信息发布平台。为众多的软件开发者提供了一个大的资源库,从而极大地减少了自由软件开发过程中的重复劳作。但是,SourceForge也有其没有完全解决或者没去解决的方面。这就是网络开发项目组的交流和沟通问题,这在自由软件开发过程中是很重要的一个方面。目前只能依赖于邮件列表,Chat Room 这些简陋的设施,不能不说是一个遗憾。 \r\n\r\n\r\n这样列举sourceforge缺点有问题:难道你能提供比chat, mailing list更好的方式吗? 视频会议?XP讲究的是refactoring, 但不是wiki这样的修改,每一步都要是个大概可以工作的版本,这就跟sourceforge现在采用的cvs一样了。\r\n\r\n希望你这里能明确提出到底webpm有什么特色?\r\n\r\n另外就是[url=http://www.twiki.org]twiki[/url]这里你也可以去看一下。\r\n\r\n\r\nWebPM 的提出,正是希望能够寻求一些好的解决方案。同时作为XP的支持者,寻求一种能够在互联网络上自由发挥每个开发者能力的方法以及能够支持这种方法的协作平台。究竟能够做成怎么样?让我们大家一起努力吧! - brokendoor 2002/1/10 \r\n----\r\n[big]明确的说,WebPM 项目需要解决三个方面的问题:[/big]\r\n\'\'\'其一:Web 项目开发的信息和知识交流问题。\'\'\'\r\n传统的信息发布可以列举一下: 留言簿、新闻组和邮件列表、论坛、定制的信息网站、还有wiki。\r\n在这里我们选择了wiki这种简单、自由的方式作为非实时的交流平台。\r\n而实时的交流是一个较大的问题,视频会议应该是更理想的选择。但是在目前网络环境的限制下,我们不可能拥有这样的条件。我们希望更简单、方便地解决网络实施交流的问题,所以我考虑选择 Chat + WhiteBoard,解决在线会议的问题。具体内容可以参看 [webpm_net] 子项目。\r\n\r\n\'\'\'其二:Web 项目开发的组织和管理问题。\'\'\'\r\n目前在web上并没有好的解决方案,几乎所有的项目都依赖小组成员自觉、自发的进行。那么,究竟能不能够引入更好的方法呢?比如:支持特定的软件工程方法、提供工作流支持等等?\r\n目前我们考虑的是引入XP方法的支持,并且提供工作流支持环境。\r\n\r\n\'\'\'其三:Web 项目的源代码和文档管理的问题\'\'\'\r\n这个就是cvs啦。有些朋友希望能够有在线的IDE,有完全基于Web的源代码和文档管理。有什么问题呢?我们还没有走到这么远,以后再讨论吧。\r\n BrokenDoor 2002/1/24\r\n----\r\n----\r\n说实话,我对wiki的兴趣远大于WebPM,WebPM的目标太大了。[panhwa]\r\n----\r\n--------------------------------------------------------------------------------\r\n\r\n分类: [WebPM]\r\n\r\n','BrokenDoor','2002-01-24 15:45:25','2002-03-01 16:00:33',0,'panhwa',64),('铁马','lakdjfa;lkdfja;ldkfj','218.12.255.1','2002-01-24 15:22:29','2002-01-24 15:22:29',0,'N/A',65),('webpm_net','定义\r\nWebPM 的核心子项目,当前的用户故事如下:\r\n\r\n\'\'\'WebpmChat\'\'\'\r\n1、用applet/servlet实现chat的功能;\r\n2、chat 的数据可以保存到数据库;\r\n3、项目成员可以申请项目会议,自动保留会议记录。\r\n\r\n\'\'\'WebpmWhiteBoard 白板\'\'\'\r\n1、用applet/servlet实现白板的功能;\r\n2、白板的数据可以保存到数据库;\r\n3、项目成员可以申请项目会议白板,自动保留会议白板记录。\r\n\r\n\'\'\'待办事项\'\'\'\r\n----\r\n关于白班\r\n可以使用SVG或是简化的SVG描述通讯协议\r\n----\r\n踏冰,已经启动,开始做原型CHAT。\r\n----\r\n什么是[SVG],可以介绍一下吗?\r\n----\r\nI like coding ...like coding jianghu ...\r\n----\r\n分类:[WebPM]\r\n参考:[webpm_net 讨论区]','BrokenDoor','2002-02-08 15:47:58','2002-03-14 00:14:47',0,'踏冰',66),('qzhl(灌篮高手)','我很想加入,但是我水平比较菜!主要简介如下:\r\n\r\n1、熟悉网站前台各种技术。\r\n2、熟练,较深入的asp应用开发。\r\n\r\n3、有一定计算机理论基础,包括(原理,数据结构,数据库,软件工程,线性代数,离散数学等)\r\n\r\n4、现在正在学习 Java 已经大概读了一遍 Think In Java 对基本思想和语法 有比较清楚的理解。但对API熟悉的还很少。\r\n5、Jsp,Servlet,JavaBeans,EJB 等应用也正在学习中。\r\n\r\n希望能得到各位高手的指点。[email=qzhl@inhe.net]E-mail[/email]','218.12.255.1','2002-01-24 21:40:05','2002-01-24 21:40:05',0,'N/A',67),('webpm_net 讨论区','在这里讨论 webpm_net 子项目的相关问题!\r\n----\r\n需要具体的需求\r\n----\r\nCHAT 原型的实现方案======[踏冰]\r\n1、客户端,JSP+APPLETE实现,其中APPLETE主要用于 将来的 白板功能扩展。\r\n\'\'\'--可以考虑是否也提供application?不会有太多的额外开发量\'\'\'--[浆糊]\r\n2、用APPLICATION对象保存聊天记录,记录==100条,就写入数据库一次。这样就实现了会议记录的保存。\r\n3、白板,客户端用APPLETE 实现,其与服务器的传输,定制基于XML的协议,以便生成SVG。或者直接生成 \r\n SVG 信息流。\r\n\r\n 待续\r\n[扫地的癞蛤蟆]\r\n我先想问这样一些问题,大家考虑考虑,然后给个回答,以便一起讨论。\r\n首先,\r\n通信的问题:\r\n1.采用的是什么结构(架构),用集中式还是复制式?各自的优点和缺点。(B/S结构似乎已经将他限制在集中式的圈子里了!怎么样才能实现复制式的结构?)\r\n\'\'\'--能否详细的介绍一下集中式与复制式,我对这两个概念不是很清楚,呵呵.. 我想说,是否考虑尽量少的使用server端,考虑胖客户端(是不是有人要扁我 ,呵呵.),减少server的开销,我们的client用的是applet升级不会太麻烦.,---[浆糊]\'\'\'\r\n集中式的结构,一般就是一个或多个集中式的服务器和一些客户之间的交互.所有的事件调度都有服务器来承担,因此事件的调度会比较简单,不存在并发的问题.但是性能会降低,适合实时性不强的系统\r\n复制式的则是将服务器的功能下放到可户端,系统中的每个节点有双重的身份,各个进程之间都是对等的,这个就是所谓的peer to peer,哈哈.因为每个节点都复制了一个相同的某重对象,所以叫复制式.嘿嘿.缺点是开销小,一个节点瘫痪,不过对系统产生影响,而且瘫痪节点可以马上得到恢复.复制式么,复制一个回来:).但是这种结构的复杂程度很高,比方说事件是否都能按照同样的 顺序 到达各个节点,所以调度策略比较烦!!\r\n混合式就是两个的结合[扫地的癞蛤蟆]\r\n----\r\n2.用TCP还是UDP,tcp还是混合使用,比方说多媒体数据用udp,控制信号用tcp,怎么处理两者之间的权衡的关系??使得系统的开销小,传输数据不湿真。什么什么的,哈哈\r\n\'\'\'--webservice不知道能不能传过防火墙,好像可以.是否考虑用它?tpc,udp如何穿墙?谁知道?\'\'\'\r\ntcp和udp穿墙比较痛苦,似乎只能用1080代理出来了?webservice我不太懂,但感觉主要优点是可以解决各个系统之间的整合的问题把,喝喝,我是文盲,说错了不要打我[扫地的癞蛤蟆]\r\n----\r\n3。防火墙的问题,因为是用在webpm的项目中,各个用户可能处在不同的防火墙之后,这个是挑战,也是机遇,呵呵,。否则大家就用netmeeting了,即便是unix系统上,也是有相关产品的,比方说sunforum!\r\n\'\'\'--我想可以采用http协议,作为通讯协议,这样可以解决这个问题.其它有没有更好的协议?不过http本身存在很多的弱点,看看有没有解决的办法,例如如何解决实时性.我们的东西肯定不能存在防火墙的问题,不然就没有太大的意义.tcp,udp估计有问题.\'\'\'--[浆糊]\r\n用soap走http的协议,实时性能不好,其实为了考虑性能和可靠性udp和tcp的使用都是有讲究的.用了http,同步只类的问题更加麻烦[扫地的癞蛤蟆]\r\n\r\nAccsess Control.\r\n1。如何发现会议(就是一个个讨论的主题)\r\n\'\'\'--我的想法:会议主持人可以开设一个会议,然后别人可以加入这个会议.象QQ的聊天室\'\'\'\r\n\'\'\'喝喝,用了这样的方式,显然就只能做集中式的结构了\'\'\'[扫地的癞蛤蟆]\r\n2。会议中权限的分发,有的时候如果不需要太考虑并发的控制的时候就可以用这个方法来解决一些冲突上的问题。因为在现实生活中的讨论,大家都不会各说各的,必须要提供一个排队的算法。\r\n\'\'\'--排队的话,我想一个队列应该可以了\'\'\'\r\n还可以用串形算法的,包括悲观酸法和乐观算法,这些东西我以前看过些[扫地的癞蛤蟆]\r\n----\r\n还有的就是一些心理学上的问题。\r\n比方说协作感知。因为现实的协作中你可以看到对方在干什么,这样心理就有一个底,否则,总不是很爽的,如果有一些协作上的感知了,自然会少掉一些冲突上的问题,比方说在MSN中,我就观察到他对这点做的还是不错的,至少还有什么“糨糊正在输入信息”什么的。在白板中比方可以显示各个用户的鼠标轨迹什么的,(需不需要这个,还有待讨论。呵呵,谁能提供一个好的协作模型?)\r\n\r\n我想做一个whiteboard之前这些问题是应该先问一问自己的,即使不做这些功能,也要为以后做准备,否则所谓的只满足以前的需求,对以后的改动很可能就是一场噩梦啊。即使想不做噩梦,估计也只能重新做过了。\r\n\r\n\r\n呵呵,刚好想到了这么几点,欢迎大家补充,一起讨论!\r\n----\r\n看了大家的讨论,真得不错。为了增强会议的实时性,我自己认为P2P是最好的解决方案。但是,具体的实现方案就需要考虑了。关于WebService,可能效率的问题是致命的,我们还要观望,但是我希望在这方面做多点研究(Spike),以便跟上发展的要求。目前我的想法还是先采用集中式策略,作出一个原型,至少目前WebPM项目就等着用呢。 -- BrokenDoor 2002/3/15\r\n\'\'\'补充一点:\'\'\' 白板实际上是c/s结构的,客户端负责画图和显示,服务器只处理客户端提交的基于SVG定义的白板数据(协议)。因为\'\'\'SVG是纯文本\'\'\'的,我认为可以像处理聊天数据一样的方式处理,而不会为服务器增加更多的压力。我想这点才是我最初设想的关键。\r\n----\r\nB/S就一定限制在 集中式的圈子了吗??? 服务器 做成分布式的,可以说,那就是 集中式与分布式 的“完美结合” 了。。。。 CHAT的原型已经弄了很多了,不过白板功能还没启动。CHAT 用的完全是HTTP协议,墙是没问题的,会议记录也可以进行保存。 初步考虑,白板 功能, 首先由嵌套在APPLETE中的 解释器,将客户端 的图形,转变成 SVG 文本,然后,还是利用 HTTP协议,request服务器,由服务器,将SVG文本,发送到其他客户端,这可以利用刷新了。。[踏冰]\r\n踏冰,你所说的服务器 做成分布式的,其实就是一个备份服务器的概念,这个还是属于集中控制的,只是集中控制服务器还保留了其他的几个备份而已.你自己想想,其实,优点并没能体现出多少,最多在一个笨亏了的时候有另一台......可是为什么本亏??很可能是性能被耗光了,所以,这种并不能解决实质的问题.[扫地的癞蛤蟆]\r\n----\r\nP2P的P并不一定要是用户所在的客户端,否则怎么会有这么多的厂商关注,仅仅是个人用户是没有这么多\"钱途\"的!\r\n企业运算同样可以有P2P.不仅仅是备份服务(当然也是其中之一).B/S结构中作为web server端的进程也可以是Peer,他们使用整个P2P的服务,而Browser端仅仅是做为完全的表现层(当然也可以有少量的计算).一个大型的Web Chat的后台服务完全可以使用分布式的(p2p的). [kert]\r\n----\r\n分类:[WebPM] | [webpm_net]\r\n\r\n----\r\n','BrokenDoor','2002-01-24 15:32:36','2002-03-17 12:38:35',0,'211.154.68.168',69),('87ZD','看看!','202.104.111.177','2002-01-24 15:48:26','2002-01-24 15:48:26',0,'N/A',70),('要','[email=qzhl@inhe.net]那里有源码我很想看看[/email]\r\n\r\n等正式版本发布的时候,会提供原码的 !!!!!!!!!!!!!!!!!!。 浆糊 2002-01-24\r\n\r\n我等不及了!!\r\n\r\n[url=http://cosoft.org.cn/projects/webpm]cosoft 上的cvs[/url] - BrokenDoor 2002/1/24\r\n\r\n要你就说啊,你不说我怎么知道你想要呢…………','218.12.255.1','2002-01-25 11:11:54','2002-02-27 21:59:17',0,'takaka',71),('developer','66','61.151.231.139','2002-01-24 15:55:13','2002-01-24 15:55:13',0,'N/A',72),('aa','aa','218.12.255.1','2002-01-24 16:03:21','2002-01-24 16:03:21',0,'N/A',73),('自由软件及其在我国的发展','[h3]自由软件及其在我国的发展[/h3]\r\n\'\'\'芬兰赫尔辛基理工大学研究科学家 宫敏\'\'\'\r\n\r\n\'\'\'什么是自由软件\'\'\'\r\n  自由软件的英文称谓是“Free Software”,由于英文Free这个字的二意性,有些人把它理解为免费软件,包括国内出版的一些书籍也将其误译、曲解为免费软件。关于这一点美国自由软件基金会的版权声明中说得明白:“当提到Free Software时,我们指的是自由而不是价格,我们所设计的通用公共许可证是为了保证您有散发自由软件和拷贝的自由,您会得到源代码或当您想得到时可以得到,……”这个版权声明是由律师写给律师看的,非常绕口但意思明确,告知是“自由”而不是“免费”。这一版权声明通常被称为GPL,或被幽默地称为CopyLeft,它是与Copyright相对的。一般所说的自由软件指的是用GPL作为版权声明的软件而不一定是自由软件基金会的产品。注意区别以下几类软件:\r\n\r\n  公共域软件(Public Domain);\r\n  共享软件(Shareware);\r\n  商业软件(Commercial Software)。\r\n\r\n  公共域软件是作者明言允许他人将其包含在自己的私有版权产品中出售或允许任意处置。这类软件都提供源代码。\r\n\r\n  共享软件是所谓“先尝后买”软件,用户可以得到软件并试用,一旦决定继续使用下去就必须向作者缴付注册费,这类软件不提供源程序,属于商业软件的一种形式。\r\n\r\n  自由软件由MIT的M.Stallman首先倡导,全球千千万万软件专家纷纷响应,并在他们积极的开发与维护下形成了大量的高质量软件产品。当时在麻省理工学院做研究工作的Stallman不满于一些软件厂家的傲慢与狭隘,决定将自己开发的软件产品与他人共享,既能够不胫而走又保证成果不被奸商窃取,提出了自由软件的概念,成立了自由软件基金会,至今自由软件的开发方兴未艾,一发不可收拾。\r\n\r\n  狭义的自由软件就是以GPL为版权声明的软件。我们在这里所说的自由软件指的是广义的自由软件,包括公共域软件在内,在使用和二次开发时一定要注意尊重并遵守原作者的版权说明,该致谢的致谢,该付款的付款,原作者要求不提名的不提名。\r\n\r\n\'\'\'有哪些优秀的自由软件\'\'\'\r\n  世界上有着大量的优秀自由软件,下面笔者提及一些,但由于篇幅有限不能一一列举。\r\n\r\n  操作系统:\r\n\r\n    Linux符合POSIX并兼容system V和BDS克隆\r\n    Mach微内核\r\n\r\n  语言系统:\r\n\r\n    GCC C语言编译器\r\n    C++ C++语言编译器\r\n    G77 Fortran语言编译器\r\n    Java 一种脚本语言,广泛应用于Internet\r\n\r\n  窗口系统:\r\n\r\n    X-Windows X窗口系统\r\n\r\n  应用系统:\r\n\r\n    Ingress 数据库管理系统\r\n    Postgress 数据库管理系统\r\n    Alliance VHDL\r\n\r\n  文字处理:\r\n\r\n    Tex LaTex 印刷出版系统\r\n    GhostScript Postscript观看和打印系统\r\n\r\n  网络支持:\r\n\r\n    与一般的微软产品不同,作为自由软件的Linux不需任何其它软件,在内核中就包含对Internet的基本支持,例如:\r\n\r\n    TCP/IP Socket\r\n    固定路由\r\n    地址捆扎和反向地址捆扎\r\n    光纤分布式数据网(FDDI)\r\n\r\n  编辑器和软件工程工具:\r\n\r\n    Emacs 多用途编辑器\r\n    gdb 源程序级调试程序,可调试运行中的进程甚至内核\r\n    xxgdb 带Xwindows支持的gdb\r\n    RCS & CVS 源程序控制系统\r\n    Strace 跟踪软件\r\n\r\n  另外,所有标准的UNIX实用程序都有自由软件的版本,它们通常都在原有版本的基础上作了扩充或在兼容的基础上作了改进。还有大量的科学计算软件包。\r\n\r\n  很多厂家都或多或少地支持自由软件。Intel、MIPS等一些处理器生产商纷纷为GCC提供专用的代码优化器等,并按规矩给出源程序。一些著名软件厂商也开始为自由操作系统提供应用程序,如Netscape、Lotus、Adobe和WordPerfect等,有些厂商还采取资助的方式支持自由软件。由此看来,自由软件异军突起,已引起了各方面的注意。\r\n\r\n\'\'\'自由软件在我国的发展\'\'\'\r\n  随着社会的进步和科学技术的发展,特别是Internet的流行,一个全球性的管理和社会经济网络化、信息化的热潮正在影响着我国信息产业的发展,面临这样的形势,用什么软件的问题摆在了我们面前。我们究竟需要什么,该用谁的产品?\r\n\r\n  美国政府曾经制订了联邦采购法。该采购法规定政府机构不得采用非POSIX兼容的产品,这样一来某些公司的某些产品就被排除了,美国政府并不是和这些公司过不去,只是不愿被个别厂商牵着鼻子走,那么什么是POSIX呢?\r\n\r\n  POSIX是可移植操作系统接口标准(Portable Operating System Interface Standard),该标准由IEEE制订,并由国际标准化组织接受为国际标准。作为公开的标准,POSIX不属于任何公司,任何想和美国政府作生意的公司都必须拿出符合标准的产品。某公司为了使自己的产品能够进入政府的采购单,不得不在某产品中号称加入了POSIX的支持软件。\r\n\r\n  由于自由软件产生的背景,其遵循的标准只能是POSIX。因此自由操作系统Linux、自由编译器GCC从它们诞生之日就符合POSIX。\r\n\r\n  有些大公司说他们的产品符合POSIX,但是他们不提供源代码,一旦系统有问题只能找他们解决,这一般最快也得等到下一版本的推出,作为用户则得花钱购买升级版或购买版本升级服务,举一个笔者亲身经历,有助于说明此问题。\r\n\r\n  当笔者在赫尔辛基理工大学做研究工作时,最初是购买了Interactive UNIX作为软件平台,同时采用Data General的AViiON工作站,后来发现二者的TCP/IP代码都有些问题。笔者向相应的厂家报告了问题,其中一家在半年后答复道,该问题已经在新版本中解决了,请我们购买其升级版。当升级版买回后发现问题并没有完全解决,只得通过极其麻烦的手续退货,而另一家直至五年后的今天仍未给出解决办法。\r\n\r\n  Linux发表之后,笔者立即采用了Linux,当时Linux还比较原始,但那时所支持的硬件设备已经不少,以后很快就超过了商品的UNIX。笔者在使用中发现的一些问题,通过USENET NEWS发出求救信息后,短则几天长则个把月就可得到解决方案。一般来说,如果超过一个月没有得到解决方案就可以考虑查看源程序自行修改,当问题解决后将解决方案通过USENET NEWS张贴,并通过电子邮件寄给相应代码的原作者,他一般会致谢。下次您在新闻中看到相同问题的求助后也就可以拔刀相助了。\r\n\r\n  由此可以看出自由软件胜于商业软件。\r\n\r\n  自由软件不仅适用教育和科研环境,同时也适用于社会。事实上,在世界很多机构都采用自由软件作为软件平台。据笔者所知,我国也有公司用自由软件提供Internet上服务。很多大公司如IBM、DEC和OSF都在他们的产品关键部位采用了某种形式的自由软件,如X-Windows和Mach微内核,这些都充分说明自由软件技术水平的先进性和使用的便利性。\r\n\r\n  鉴于自由软件的水平之高、应用面之广并有源代码,当前广泛提倡使用自由软件、学习自由软件、参与开发自由软件,对于方便用户使用、保护用户投资、提高软件应用与开发的综合水平、打破商业软件的垄断和控制都具有重大意义,是非常必要的。\r\n\r\n  笔者认为,目前在我国推广自由软件的条件已经成熟。诚然,自由软件的推广应用需要一定条件,例如必须有获取来源,有人散发,有人提供技术服务,有人进行开发等等,但这些问题是不难解决的。基于本人在国外的工作经验以及对自由软件与Internet的认识,提出两点建议,谨供参考。\r\n\r\n  1.建立位于国内的、内容齐全的自由软件档案库。由于自由软件的开发工作发生于世界各地,自由软件的存档也散见于世界各地,加上规模之巨大,国内各个单位分头通过Internet提取是不经济、不合理的,加上查找不便甚至十分困难,建立位于国内的自由软件档案库有助于以多种媒体形式为国内提供自由软件。\r\n\r\n  2.建立若干相应自由软件的中文USENET NEWS讨论组并转载国外相应讨论组的英文文章,组织双向转载(Cross-Posting),有人负责将讨论组文章定期归档。讨论组的建立有助于大家进行经验交流、难题解答和互助。由于目前自由软件多为国际人士开发与维护,建立国际联系、取得国际技术支持及难题解答是极其重要的。\r\n\r\n  (本文是根据一篇讲话稿编辑的,作者于今年5月11日回国,并带回了大量自由软件档案,以帮助中国软件行业协会国际自由软件应用分会建立自由软件档案库和支持平台之用。——编者)\r\n\r\n----\r\n分类:[自由软件]\r\n\r\n','BrokenDoor','2002-01-24 18:35:24','2002-01-24 18:35:24',0,'N/A',74),('WebService','[WebService java实现]\r\n\r\n----\r\n资源:\r\n[http://www.htennant.com/hta/askus/webservices.htm|http://www.htennant.com/hta/askus/webservices.htm]','浆糊','2002-01-24 23:52:02','2002-02-26 23:44:19',0,'浆糊',75),('GroupWare','\'\'\'Group Ware 群件\'\'\'\r\n----\r\n帮助用户更好地进行合作或更有效地进行工作的一种工具,它包括应用在网络上的一些软件和硬件。群件的目的在于帮助人们共享信息,协调好彼此的角色,更好的进行合作。群件产品出现在Intranet之前,Intranet技术的诞生给群件市场带来了很大的变化。几乎所有的群件产品都开始向Intranet靠拢。按照人们使用群件工具的方式可以将群件分为两类:(1)会议工作群件,(2)个人工作群件。 \r\n\r\n由于计算机网络与通信技术的发展,使得许多人可以通过计算机系统在不同的地点协同工作。把支持群体工作的计算机软硬件系统称为群件。按功能分,群件有三大类:以计算机为媒介的沟通、会议与决策的支持、分担应用任务或对象。\r\n----群件结合了文档数据、信息传输系统及系统设定的能力,使得我们可在上面创造实用的应用系统。群件本身就有数据库的复制能力,能实时地使数据库中的数据保持一致。群件最大的好处在于协同工作,从而提高工作效率,充分实现信息资源的共享。\r\n\r\n----目前,最有名的群件是Lotus Notes。Lotus Notes是一个专用的Client/Server软件,它支持小组通信、电子邮件、小组讨论、数据库复制,同时包括一个应用程序开发环境。\r\n\r\n----Lotus Notes不同于其他关系数据库,它是一个文档数据库管理系统。其数据库的基本元素是文档。一个文档可以包含多种对象,如文本、电子表格、图形和图像。用户把文档存储在不同服务器上的多个数据库中,也可以在本地硬盘上创建本地数据库。\r\n\r\n----Lotus Notes具有全文搜索能力,还允许用户利用它的集成电子邮件功能交换信息,并在此基础上创建工作流系统。\r\n\r\n----Lotus Notes的复制很有特点,可单向复制、有选择地复制和双向复制。当远程用户与Notes服务器建立连接之后,可以把服务器的数据库复制到本地硬盘中;或者有选择地把数据库的部分文档复制到本地硬盘中,而无需拷贝整个数据库。当用户下次连接Notes服务器时,Notes将自动更新服务器和本地硬盘上的数据库。Notes客户端可以多种方式访问服务器:通过调制解调器连接服务器、通过内部网连接服务器或者两者兼而有之。\r\n\r\n----\r\n分类:[工作流] \r\n参考:[我们还需要哪些新的群件应用?]','61.171.116.205','2002-02-06 04:41:03','2002-02-06 04:41:03',0,'202.105.101.159',76),('AOP','Aspect Oriented Programming\r\n----\r\nResource\r\n*[url=http://www.aspectj.org]AspectJ[/url]\r\n*[url=http://www.research.ibm.com/hyperspace/index.htm]ibm hyperspace[/url]','61.171.116.205','2002-01-25 11:24:52','2002-01-25 11:24:52',0,'N/A',77),('中文关键字','帮助','202.120.28.78','2002-01-25 23:30:54','2002-01-25 23:30:54',0,'N/A',78),('WikiWikiWeb','WiKiWiKiWeb允许任何人可以在任何内容上进行协作。\r\n世界上第一个、最著名、使用人数最多的Wiki是[url=http://c2.com/cgi-bin/wiki]波兰模式库[/url]-Portland Pattern Repository。 \r\n\r\nWiki的出发点是可以方便地编辑文本,可以快速寻找页面.是的 \r\n\r\n除了方便快速外,Wiki也体现了常被称为WabiSabi的禅宗思想.\r\n\'\'\'禅从缺陷和短暂中发现美. When it comes down to it, that\'s all you need. \'\'\'\r\n----\r\n\'\'\'* Wiki 的特点?\'\'\'\r\n在Wiki的页面上每一个人都可以对几乎所有的页面进行修改(不是全部页面,WebPM Wiki 提供了页面锁定功能),只要你在页面左下角上的“编辑此页”上点击即可进入编辑状态。这样,我们每个人都可以参与到这个网站的维护中去,做出自已的努力,因此它可以为团队的协作开发提供支持。当然,也许有恶意的人会闯进来把你的东西全部删掉,但愿这种事情不会发生。针对这种情况,WebPM Wiki 提供了所有文章的版本备份,如果你发现自己的文章被其他人破坏(也可能是无意之中造成),请立刻通知[管理员寻呼],我们的管理员会从备份中找出最近的文章恢复出来。\r\n\r\nWebPM 项目组正对wiki系统的扩充性能开展研究,不久将会推出基于wiki系统的项目管理平台。希望大家多提建议!\r\n----\r\n\'\'\'* 我应该如何增加文章?\'\'\'\r\n 每一个初次接触JWIKI这类系统的朋友都会有此疑问。不要紧,我保证不到一分钟您就会解决这个问题。点一下左下脚“\'\'\'编辑此页\'\'\'”的连接,你会看到本文的原始文本。花点时间看看应该如何建立连接。WebPM Wiki系统使用[关键字]标记一个关键字连接,其他的标记请看[文件格式化规则]。\r\n当你建立了一个本系统并不存在的连接时,你输入的关键字后面会跟上一个小小的问号——“?”。点一下这个问号,就会有一个可以编辑的新页让你输入内容了。在保存之后,文章就进入了JWIKI系统。\r\n----\r\n\'\'\'* 为什么这里的导航乱七八糟?\'\'\'\r\n 同样是因为大家对JWIKI这类系统的使用不太适应造成的。好的,这里有几个小小的建议,帮助大家建立一个良好导航的知识库。\r\n\'\'\'1.如果您希望自己的文章能一目了然,就应该建立自己的专栏。\'\'\'\r\n——在[签名簿]签下您的大名,为您的大名建立一个连接。之后所有的文章都由您的大名下开始建立新关键字(不好意思,暂时还是需要您手工做的)。\r\n\'\'\'2.如果您希望把自己的文章加入到[主题分类],就应该在相应的分类下建立自己的分类或文章。\'\'\'\r\n\'\'\'3.尽量为自己的文章选择合适的[主题分类],并在文章底部清楚的加入分类连接。\'\'\'\r\n----\r\n\'\'\'其他的Wiki:\'\'\'\r\n\r\n* 国内\r\n\'\'\'ERPTAO Wiki\'\'\' [http://www.erptao.org/wiki|http://www.erptao.org/wiki]\r\n--ERP和设计相关的讨论区\r\n\r\n\'\'\'Dimension5 Wiki\'\'\' [url=http://dimension5.org/modules/wiki]http://dimension5.org/modules/wiki[/url]\r\n-- 以C++设计为主要话题\r\n\r\n* 国外\r\n[Portland Pattern Repository|http://www.c2.com/cgi-bin/wiki]\r\n----\r\n参加讨论: [WebPMAndWiki]','BrokenDoor','2002-02-22 08:37:32','2002-03-06 10:38:00',0,'61.174.215.53',79),('基础夏威夷语','基础夏威夷语\r\n\r\n对于尚未入门的学习者来说,夏威夷语听上去就象一连串的辅音m,k 和h之间随意夹杂着一些元音,没有固定的顺序。就拿夏威夷州的州鱼的发音为例,这种鱼叫作humuhumunuknukuapuaa。您只要把每个字母的音都发出来,就掌握这种语言了——不过,准确地说是差不多掌握这种语言了!夏威夷语只有12个字母,其中包括所有的元音和辅音h,k,l,m,n,p和 w。元音 a的发音为{ a:},e 的发音为{ei},I为{i: },o为{ ★}, u为{ u:}。\r\n\r\n夏威夷语词汇 含义\r\n\r\na’a 一种渣状熔岩。地质学家已普遍采用此词作为这种熔岩的名称。\r\n\r\nae 是的\r\n\r\nali’I 夏威夷酋长\r\n\r\naloha 表示问候和道别的最普通用词\r\n\r\naole 不\r\n\r\nhale 房子\r\n\r\nhaole 白种人。原指外国人\r\n\r\nhapa 一半\r\n\r\nhapa haole 混血儿\r\n\r\nheiau 夏威夷寺庙,内有建在石台上的木质建筑群。不过到目前,庙里通常只剩下当年建平台的石头了\r\n\r\nhula 夏威夷草裙舞,又叫呼拉舞\r\n\r\nhuli huli 烧烤,(吃烤肉的)野外宴会\r\n\r\nimu 砌于地下的烤炉,用烧热的石头做饭\r\n\r\nkahuna 牧师。在夏威夷,他们更象是既有回天之力,又能把人置于死地的巫师\r\n\r\nkalua 在地下的烤炉中进行烤制。比如用此法烤猪\r\n\r\nkamaaina 指具有不同种族背景的岛上居民,他闪在所有方面均享受一定的优惠价\r\n\r\nkane 男人。一般用来指男洗手间\r\n\r\nkapu 禁止入内\r\n\r\nkapuna 长老,富有智慧的长者\r\n\r\nkeiki 孩子或孩子们。许多宾馆都有为他们准备的节目\r\n\r\nlanai 走廊或阳台\r\n\r\nlei 花链,或花环,常和鲜花或藤条编织而成\r\n\r\nlomilomi 古老的夏威夷寓言或训诫\r\n\r\nluau 夏威夷式的盛餐\r\n\r\nmahalo 谢谢\r\n\r\nmakai 朝向大海\r\n\r\nmauka 朝向高山\r\n\r\nmauna 山\r\n\r\noana 海\r\n\r\nmuumuu 由传教士引入的宽松肥大的女装\r\n\r\nohana 广义的家庭\r\n\r\nono 好吃\r\n\r\npa’hoehoe 一种质密光滑的绳状熔岩。地质学家已普遍采用此词作为这种熔岩的名 称。\r\n\r\nPali 山崖\r\n\r\nPaniolo 夏威夷牛仔\r\n\r\nPoi 捣烂的芋头(完全是一种逐渐养成的口味)\r\n\r\nPuka 洞,孔\r\n\r\npu pu 一种开胃品。招待会上常大量提供,吃了它,人们反而吃不下正餐了\r\n\r\ntapa 一种传统的用树皮制成的布料、\r\n\r\ntutu 祖母\r\n\r\nukulele 尤克里里琴(一种象吉它的四弦琴,流行于夏威夷等地)。这是夏威夷词汇中为数不多的被世人通晓的词之一\r\n\r\nwahine 年轻妇女。一般用来指女洗手间\r\n\r\nwiki 快\r\n\r\nwiki wiki 很快\r\n\r\n\r\n--------------------------------------------------------------------------------\r\n[url=http://202.102.170.208/travel/02/06/meiguo/files/080113.htm]原文[/url]\r\n\r\n','BrokenDoor','2002-01-29 09:27:47','2002-01-29 09:27:47',0,'61.141.204.2',80),('2001年1月28日 会议记录','□ 欢迎光临『QQ聊天中心』的【自建聊天室(六)】□ \r\n \r\n★欢迎您来到『webpm』房间★ \r\n \r\n★这间房间的主人是『 OICQ_16048561 』★ \r\n \r\n浆糊: 我来了。 \r\n \r\n踏冰: 你昨天跑什么地方去了。 \r\n \r\n浆糊: 回家了。好久没有见老婆了,回家看了看 \r\n \r\nbrokendoor: 说一下昨天的内容 \r\n \r\n浆糊: 好。我的重构工作完成了一半。文章的部分好了。还差标签部分 \r\n \r\nbrokendoor: 我们昨天讨论了工作流的需求,还有网站的建设问题 \r\n \r\n浆糊: 有具体的文档马?需求 \r\n\r\nbrokendoor: 还没有空整理 \r\n\r\nbrokendoor: 我简单说一下:关于网站建设 \r\n\r\nbrokendoor: webpm的网站全部主页都会建立在wiki的基础上! \r\n \r\n浆糊: 这点我同意。就是要对wiki进行扩展 \r\n \r\nbrokendoor: 需要对wiki进行扩展,以建立用户注册、项目注册。 \r\n \r\nbrokendoor: 用户信息显示、项目信息显示、最近加入用户、项目等 \r\n \r\nbrokendoor: 项目注册后自动生成项目主页(可以使用预定模板) \r\n \r\n浆糊: 嗯。需要具体的user toary \r\n \r\nbrokendoor: 先大概说一下,今天标书定稿了我就有时间了 \r\n \r\n浆糊: 模般应该是可以自由修改。 \r\n \r\nbrokendoor: 模板包括单页面和多页模板。其实一样的 \r\n \r\n浆糊: 如果加入其它功能,例如工程。那么需要对wiki进行比较多的扩展 \r\n \r\nbrokendoor: 你说软件工程? \r\n \r\n浆糊: 还有就是你们讨论了代码集成的问题了没有。 \r\n \r\nbrokendoor: 暂时没有好办法 \r\n \r\n浆糊: 就是用wiki进行项目管理。 \r\n \r\n踏冰: 弄个 RUP,XP 摸板什么的就OK。 \r\n \r\nbrokendoor: 我们讨论了利用工作流支持项目管理流程 \r\n \r\n浆糊: 对! 模板要可定义。 \r\n \r\n浆糊: 不过这样好像和工作流有关吧。 \r\n \r\n踏冰: 我们的特色。(破门说的) \r\n \r\n踏冰: :) :) \r\n \r\nbrokendoor: 用户故事提出、评估、审核、拆分、编程、代码审核、验收、完成 \r\n \r\nbrokendoor: 最后生成相关的自动统计。 \r\n \r\nbrokendoor: 所以wiki一定要有好的扩展接口,我觉得都类似code标记的扩展。 \r\n \r\n浆糊: 嗯。可定义的工作流应该可以 拼装成xp,rup ...等软件开发过程吧。 \r\n \r\nbrokendoor: 没问题的,有些东西可以做成工作流的扩展应用。 \r\n \r\n浆糊: wiki的这些我都考虑进去了。不过xp说,只对今天的需求进行设计,呵呵。。 \r\n \r\n浆糊: 工作流这个东西的开发量很大啊 \r\n \r\n浆糊: 踏冰死了,哈哈 ~~ \r\n \r\nbrokendoor: 比如我们昨天讨论了代码集成:假设我们有了这种工具,可以增加一个自动环节,让工 \r\n \r\nbrokendoor: 让工作流自动调用,确定是否能够进行下一步任务 \r\n \r\n浆糊: 嗯。好办法。 \r\n \r\n踏冰: 没死。 还活的好好的。 \r\n \r\nbrokendoor对浆糊说: 工作流没有想象中那么复杂的 \r\n \r\n踏冰: 这些东西,昨天我们讨论过的。 \r\n \r\n浆糊: 呵呵。。说你啊。要做工作流,工作很多阿。 \r\n \r\n踏冰: 我还是怕 coding. \r\n \r\nbrokendoor对浆糊说: 我在公司用了3个月就搞定了基本环境,大部分是我用vb写的代码 \r\n \r\nbrokendoor对踏冰说: 我也很怕啊。 \r\n \r\n踏冰对brokendoor说: 那就让 浆糊 coding 吧 :) \r\n \r\n踏冰对浆糊说: 怎么样。呵。 \r\n \r\n踏冰对浆糊说: 不会推辞吧。呵呵。 \r\n \r\nbrokendoor: 还算了测试、稳定的时间 \r\n \r\n浆糊: 靠,~~。这算不算欺负我啊,呵呵。。 \r\n \r\n踏冰对brokendoor说: 如果 我们 简单化 流程 转移条件,就会更快。 \r\n \r\nbrokendoor对浆糊说: 你找的那个家伙呢? \r\n \r\nbrokendoor对踏冰说: 是的,其实可以先不做,让用户自己决定 \r\n \r\n踏冰对brokendoor说: 呵。顺便做了吧。 \r\n \r\nbrokendoor: 以后再重构 \r\n \r\n浆糊: 你说的基本环境是说已可以实现基本功能? \r\n \r\nbrokendoor对浆糊说: 说一下重构的感觉 \r\n\r\n踏冰: 对,你们的工作流运行环境是什么??? \r\n \r\nbrokendoor对踏冰说: ASP/IIS/COM/Oracle \r\n \r\n浆糊: 简直就是一个字:酷~ \r\n \r\n踏冰对浆糊说: 怎么酷的。 \r\n \r\n踏冰对brokendoor说: 哦。。 \r\n \r\n浆糊: 先设计,再编码。很帅的。一下子接口就出来了。 \r\n \r\n浆糊: 不是设计,是测试。 \r\n \r\nbrokendoor对浆糊说: 我可以想象一下,用UnitTest保证功能 \r\n \r\nbrokendoor对浆糊说: 然后,完成一块就是一块 \r\n \r\nbrokendoor对浆糊说: 然后,就完成了 \r\n \r\n浆糊: 恩,是的。 速度也很快。 \r\n \r\n踏冰对brokendoor说: 继续刚才我们说的吧。 \r\n \r\n踏冰对brokendoor说: 用户登录后 的 任务列表。 \r\n \r\nbrokendoor对踏冰说: 好的,今天说到流程处理界面 \r\n \r\n浆糊: 工作流包括哪些实质的东西? \r\n \r\nbrokendoor对踏冰说: 任务列表划分为 待办、在办、已办、暂停等状态 \r\n \r\nbrokendoor对浆糊说: 一个流程定义工具 \r\n \r\n踏冰对brokendoor说: 够了 \r\n \r\nbrokendoor对浆糊说: 流程自动化运行环境 \r\n \r\n浆糊: 我说的那个家伙好像把diff搞定了。不过他也是初学者。 \r\n \r\nbrokendoor对浆糊说: 流程处理统一界面 \r\n \r\nbrokendoor对浆糊说: 最后是流程跟踪监控和统计分析 \r\n \r\n踏冰对浆糊说: DIFF是什么? \r\n \r\n浆糊: wiki的diff功能 \r\n \r\n踏冰对浆糊说: 具体点。 \r\n \r\nbrokendoor对踏冰说: 对比两个版本 \r\n \r\n踏冰对brokendoor说: 对比什么两个版本??? \r\n \r\nbrokendoor对踏冰说: wiki文章 \r\n \r\n踏冰对brokendoor说: 哦。 \r\n \r\n浆糊: 工作流的开发工作什么时候开始? \r\n \r\n踏冰对浆糊说: 这不都开始了吗。 \r\n \r\n踏冰对浆糊说: 呵呵。 \r\n \r\n踏冰: 任务列表 的信息是够了。。 \r\n \r\nbrokendoor对浆糊说: 关键问题:code标记的处理如何? \r\n \r\n浆糊: 我说的具体story出来后,是不是马上开始开发?谁开发? \r\n \r\nbrokendoor对浆糊说: 踏冰没时间的话,可能是我来 \r\n \r\n浆糊: 我对code标记单独用了一个CodeParse implements TagParser \r\n \r\nbrokendoor对浆糊说: 可以了么? \r\n \r\n踏冰对浆糊说: 扩展什么时候搞定? \r\n \r\n浆糊: 没有重构,不过测试写好了。没有问题的。 \r\n \r\nbrokendoor对踏冰说: 如果code搞定了,就算搞定了 \r\n \r\n浆糊: 这个星期吧。 \r\n \r\n踏冰对brokendoor说: 那工作流我和 浆糊就应该OK。 \r\n \r\nbrokendoor: 好了,继续 \r\n \r\nbrokendoor: 待办列表需不需要签收? \r\n \r\n踏冰对brokendoor说: 需要, \r\n \r\n浆糊: 靠~又让我编代码阿,呵呵。。踏冰 \r\n \r\n踏冰对brokendoor说: 就一个 电子签名的问题 \r\n \r\nbrokendoor: 我觉得手工签收是必要的 \r\n \r\n踏冰对浆糊说: 怎么会呢,呵,我也要 CODING。 \r\n \r\n浆糊: 恩。是的。签收一定要的。 \r\n \r\nbrokendoor: 然后就转到在办,并自动打开对应的wiki页 \r\n \r\n浆糊: 哦,那就好。我们也试试pair呵呵。。 \r\n \r\n踏冰: 电子签名 我已经OK了。 \r\n \r\n踏冰: 电子签名实现的操作如下:你们看够不够。 \r\n \r\n踏冰: 1、待阅 ----》》》 已阅 。 \r\n \r\n踏冰: 2、登记其 签名时间, \r\n \r\n踏冰: 3、 记录其 批示。 \r\n \r\nbrokendoor: 如果,对wiki页不想做过多的扩展的话。是不是让流程操作全部在待办列表中处理? \r\n \r\n浆糊: 打断一下,关于代码的问题:编码风格好统一 \r\n \r\n踏冰对浆糊说: 到时候发给你,不就得了。 \r\n \r\n踏冰对浆糊说: 你一修改就OK 了。呵:) \r\n \r\n浆糊: 重复劳动。 \r\n \r\nbrokendoor对踏冰说: 还是统一吧,浆糊你的新约定呢? \r\n \r\n浆糊: 没做好呢。这个星期完成那个之后,下个星期写出来。 \r\n \r\n踏冰对浆糊说: 因为 电子签名 我已经OK了,呵,发给你你去统一如何。 \r\n \r\n浆糊: 等我的部分也完成吧。 \r\n \r\n浆糊: 继续工作流 \r\n \r\nbrokendoor对浆糊说: 最好早点出来 \r\n \r\n浆糊: 好 \r\n \r\nbrokendoor对浆糊说: 如果对wiki页不想做过多的扩展的话。是不是让流程操作全部在待办列表中处理? \r\n踏冰对brokendoor说: 你说具体点? \r\n \r\nbrokendoor: 我觉得可能会不方便,但是如果在wiki页中加入流程操作的话会很麻烦。 \r\n \r\n踏冰对brokendoor说: 我想不应该麻烦啊。 \r\n \r\nbrokendoor: 一般流程操作指的是,签收、转发等 \r\n \r\n浆糊: 我的看法。让wiki尽量的简单一点,不要太依靠它。它因该作为一个信息发布 \r\n \r\n踏冰对浆糊说: 老熊很喜欢 WIKI 的。呵。 \r\n \r\nbrokendoor: 没问题的,浆糊你能不能让wiki的接口程序访问文章的信息? \r\n \r\nbrokendoor对踏冰说: 嗯,我喜欢简单明快的东西 \r\n\r\n浆糊: 文章信息是什么意思? \r\n \r\n踏冰对浆糊说: 那我们就多用 WIKI 。 \r\n \r\n踏冰对浆糊说: 全部往 上 靠。。。不过就要麻烦你老兄了。 \r\n \r\nbrokendoor对浆糊说: 比如,存储在文章里的标题、编号等 \r\n \r\n浆糊: 那个人来了,要不要叫他来。 \r\n \r\nbrokendoor对浆糊说: 好啊 \r\n \r\n踏冰: 在引入 标签。 \r\n \r\nbrokendoor对踏冰说: 不会麻烦他的,只要他定义好扩展接口。我们按约定实现功能就行了。 \r\n \r\n踏冰: 用户在输入文章时,在文章 正文内使用此标签表示 关键词。 \r\n \r\n踏冰: 这样就能加快检索了。 \r\n \r\n浆糊: 嗯。可以地,写一个story给我 \r\n \r\n踏冰对浆糊说: 你说什么可以 \r\n \r\n踏冰对brokendoor说: 把会议记录弄好啊。呵:) \r\n \r\n浆糊: 比如,存储在文章里的标题、编号等 \r\n \r\nbrokendoor对踏冰说: 我曾经和浆糊讨论过一个话题,关于流程环境和使用流程业务的关联性。 \r\n \r\n浆糊: 我开会了。走了。 \r\n \r\nbrokendoor对浆糊说: bye \r\n \r\n踏冰对浆糊说: 8 \r\n \r\n踏冰: 你们都有会开,都在上班,我学生,放假了。有时间。 \r\n \r\nbrokendoor对踏冰说: 你在你的文件流传中如何处理的? \r\n \r\nbrokendoor对踏冰说: 也就是文件如何跟流程关联? \r\n \r\n踏冰: 就是 过程定义库 与 业务库 的关系。 \r\n \r\nbrokendoor对踏冰说: 是过程记录库吧 \r\n \r\n聪明鸽子: Ok \r\n \r\nbrokendoor对聪明鸽子说: 你好 \r\n \r\n聪明鸽子: 你们好。 \r\n \r\n踏冰: 你是不是想问我,是如何推进流程 ? \r\n \r\n踏冰: 在 文件流传中,如何控制流程。 \r\n \r\n聪明鸽子: 都是 前辈啊。 :) \r\n \r\nbrokendoor对聪明鸽子说: 不是,是如何从一份文件找到与文件对应的流程。 \r\n\r\nbrokendoor对聪明鸽子说: 你先看看,我们在讨论工作流程的处理。 \r\n \r\n踏冰对brokendoor说: 用户在发送文件时,要指定流程的。 \r\n \r\n聪明鸽子对brokendoor说: 好的。 \r\n \r\nbrokendoor对踏冰说: 嗯,这个流程和文件的关联方式是什么? \r\n \r\n踏冰对brokendoor说: 其流程索引 保存在 文件基本信息表的 一个字段中。 \r\n \r\nbrokendoor对踏冰说: 流程id \r\n \r\n聪明鸽子对浆糊说: 我把代码 给你 \r\n \r\n踏冰对brokendoor说: 恩,流程ID。 \r\n \r\nbrokendoor对聪明鸽子说: 浆糊开会去了 \r\n\r\nbrokendoor对聪明鸽子说: 你发到 webpm@topica.com 吧 \r\n \r\n聪明鸽子: 好的。 \r\n \r\nbrokendoor对踏冰说: 流程的状态和流转记录呢? \r\n \r\n聪明鸽子: 我是 新手。我给 浆糊 我的情况介绍了…… \r\n \r\n踏冰对brokendoor说: 流程的信息,运行情况 保存流程状态表。 \r\n \r\nbrokendoor对踏冰说: 是qzhl? \r\n \r\n聪明鸽子: 是的。 我是 qzhl \r\n \r\n踏冰对brokendoor说: 用外键来索引。 \r\n \r\nbrokendoor对踏冰说: 流程状态如何与文件关联? \r\n \r\nbrokendoor对踏冰说: 把文件id也存入状态表么? \r\n \r\n踏冰对brokendoor说: 流程实例化的 ID号,在文件基本信息表中记录。 \r\n \r\n踏冰对brokendoor说: 这样就 OK了。 \r\n \r\nbrokendoor对踏冰说: 不错 \r\n \r\n聪明鸽子: 我再 看一下哪个代码,然后发到:webpm@topica.com 。 \r\n \r\nbrokendoor对聪明鸽子说: 好的 \r\n \r\n踏冰对聪明鸽子说: 你是搞什么的。呵? \r\n \r\n聪明鸽子: 在 softme.org 上有 我的大概介绍。 \r\n \r\n踏冰对brokendoor说: 这部分结构还可以,更合理一些的。 \r\n \r\nbrokendoor对踏冰说: 待办列表其实是流程任务的实例化信息列表。 \r\n \r\n聪明鸽子: 我以前主要做 asp 现在刚刚 学习 java \r\n \r\nbrokendoor对踏冰说: 按照wfmc的定义,应该是实例化后分配了用户的任务信息列表 \r\n \r\n踏冰对brokendoor说: 我想代办列表,应该和 流程任务表分开吧, \r\n \r\nbrokendoor对踏冰说: 我设计了 ProcessInstance / ActivityInstance表 \r\n \r\n踏冰对brokendoor说: 应该是根据 任务表 来 生成 代办列表吧。 \r\n \r\nbrokendoor对踏冰说: 现在考虑要不要加 WorkItem 表 \r\n \r\n踏冰对brokendoor说: 你有ROSE吗? \r\n \r\n聪明鸽子: 改天再详细说。有事叫我。 \r\n \r\nbrokendoor对踏冰说: 没有 \r\n \r\n踏冰对聪明鸽子说: 聊聊啊。 \r\n \r\n踏冰对brokendoor说: 那惨。 \r\n \r\n踏冰对brokendoor说: 你要是有ROSE可以看一下我的 数据模型。 \r\n\r\n----\r\n破门去嘘嘘,删掉这段踏冰和鸽子的闲聊\r\n----\r\nbrokendoor对踏冰说: Rose 不是可以转成网页么? \r\n \r\n踏冰对brokendoor说: 好的。。等我 晚上发给你。 \r\n\r\n踏冰对brokendoor说: 要不现在给你。 \r\n \r\n踏冰对brokendoor说: 还是晚上吧,ROSE 太慢了。呵。 \r\n \r\n踏冰对brokendoor说: 你在干什么? \r\n \r\nbrokendoor对踏冰说: 刚接了电话,要改一点东西 \r\n \r\nbrokendoor对踏冰说: 我觉得流程环境我们的理解差不多,应该问题不大了。 \r\n \r\n踏冰对brokendoor说: 那你忙去吧,,,代办列表部分,应该不难。 \r\n \r\n踏冰对brokendoor说: 应该很容易搞定 :) \r\n \r\n聪明鸽子对踏冰说: 我 java 刚刚学 以后还请多多 帮助。 \r\n \r\n踏冰对聪明鸽子说: JAVA我不懂什么的。呵 :) \r\n \r\nbrokendoor对踏冰说: 我看第一件事是把用户注册加入到wiki系统。 \r\n \r\n聪明鸽子对踏冰说: 啊???不会把??? \r\n \r\n踏冰对聪明鸽子说: 你要去问 浆糊。 \r\n \r\n踏冰对brokendoor说: 加入 不难啊, \r\n \r\n踏冰对brokendoor说: 你认为有麻烦吗? \r\n \r\nbrokendoor对踏冰说: 没有说难,而是说这是第一件任务 \r\n \r\n踏冰对brokendoor说: 用户注册,要作为独立的 ,不要加里去。 \r\n \r\n踏冰对brokendoor说: 用户注册 已经 可以了。。 \r\n \r\nbrokendoor对踏冰说: 嗯,功能是独立的。但界面标记总是要加的 \r\n \r\nbrokendoor对踏冰说: 要不然怎么在主页显 \r\n \r\n踏冰对brokendoor说: 你是说在 WIKI 中 提供 用户 注册的页面???? \r\n \r\nbrokendoor对踏冰说: 难道不行? \r\n \r\n踏冰对brokendoor说: 主页要 WIKI 的? \r\n \r\nbrokendoor对踏冰说: 很简单的 \r\n \r\n踏冰对brokendoor说: 可以的。。 \r\n \r\nbrokendoor对踏冰说: 昨天不是讨论了半天么 \r\n \r\n踏冰对brokendoor说: 不过我想,在 WIKI页中加一个 用户注册的连接 不是更好吗? \r\n \r\nbrokendoor对踏冰说: 嗯,也没问题 \r\n \r\n踏冰对brokendoor说: 呵 :) \r\n \r\n踏冰对brokendoor说: 你忙去吧。 \r\n \r\n踏冰对聪明鸽子说: 呵。 \r\n\r\n----\r\n分类: [WebPM] | [WebPM 小组会议] ','BrokenDoor','2002-01-29 11:37:50','2002-01-29 11:37:50',0,'61.141.204.2',83),('ddd','Nothing','浆糊','2002-01-29 17:51:11','2002-01-29 17:51:11',0,'192.168.1.228',84),('宗子昱','哇,真的很好玩,真希望早点开放出来啊。','61.133.182.154','2002-01-29 19:31:50','2002-01-29 19:31:50',0,'61.133.182.154',85),('Wader','','浆糊','2002-01-30 14:39:39','2002-02-26 13:06:38',0,'浆糊',86),('2002年1月30日 聊天记录','----\r\n说明: 姑娘你真靓 就是 大家都爱的 踏冰 (你可别恶心的吐出来)\r\n----\r\n\r\n2002-01-30 20:31:09 浆糊\r\n??\r\n(通过服务器中转)\r\n\r\n2002-01-30 22:07:40 姑娘你真靓!\r\nwhat?\r\n\r\n2002-01-30 22:04:16 浆糊\r\n没有什么事情,今天心情特别差\r\n(通过服务器中转)\r\n\r\n2002-01-30 22:08:33 姑娘你真靓!\r\n为什么?\r\n\r\n2002-01-30 22:05:46 浆糊\r\n感到特别的。。\r\n说不出是什么心情,也许是一个人在写wiki感觉有点寂寞\r\n(通过服务器中转)\r\n\r\n2002-01-30 22:10:09 姑娘你真靓!\r\n你不是找到一个人一起弄了吗?\r\n\r\n2002-01-30 22:06:56 浆糊\r\n那个家伙刚学,不太会\r\n(通过服务器中转)\r\n\r\n2002-01-30 22:11:33 姑娘你真靓!\r\n是吗。\r\n\r\n2002-01-30 22:08:29 浆糊\r\n嗯。也不是单这个事情。\r\n心情复杂\r\n(通过服务器中转)\r\n\r\n2002-01-30 22:13:01 姑娘你真靓!\r\n怎么了。说来听。\r\n\r\n2002-01-30 22:10:13 浆糊\r\n你说我现在花那么多的时间作wiki有意义吗?\r\n(通过服务器中转)\r\n\r\n2002-01-30 22:14:33 姑娘你真靓!\r\n你怎么认为呢?\r\n\r\n2002-01-30 22:11:10 浆糊\r\n意义不大。因为没有人用\r\n(通过服务器中转)\r\n\r\n2002-01-30 22:16:41 姑娘你真靓!\r\n没人用不一定没意义, 用的人多 ,意义不一定大。\r\n\r\nWINDOWS 用的人多,如果你 只 是 无任何意义的在别人的指导下去做,等于没有提高。\r\n但是在小的一个系统,是你分析设计的,那就是 你的 锻炼。\r\n\r\n2002-01-30 22:14:07 浆糊\r\n这个我承认,但是现在感觉webpm要实现的东西,太多了,而且没有一个详细的开发计划,给我感觉是在无序的\r\n\r\n乱作\r\n(通过服务器中转)\r\n\r\n2002-01-30 22:18:48 姑娘你真靓!\r\n你怎么不去问 熊刚??? :) :) \r\n\r\n给他提点意见。\r\n\r\n2002-01-30 22:16:03 浆糊\r\n他也是很忙,好像最闲的人就是我\r\n(通过服务器中转)\r\n\r\n2002-01-30 22:20:48 姑娘你真靓!\r\n其实,我并不总是在工作,但是我平常,也总在考虑 我的 东西,我的理想,我想做什么,应该怎么去做。\r\n\r\n2002-01-30 22:18:04 浆糊\r\n对,你想的很对。\r\n但是我却不同。我其实工作很忙。wiki都是我晚上,还有就是上班抽空。\r\n一个人很累。\r\n(通过服务器中转)\r\n\r\n2002-01-30 22:23:35 姑娘你真靓!\r\n知道你累,我也想 弄一下WIKI 但是,真的,有好多好多的东西值得去学习,值得去实验,WIKI在\r\n\r\n弄也就是 炼 CODING。\r\n\r\n2002-01-30 22:21:27 浆糊\r\n嗯。\r\n我现在感到没有什么动力了。\r\n为什么国内就没有国外的那样的组织,我很羡慕\r\n(通过服务器中转)\r\n\r\n2002-01-30 22:26:16 姑娘你真靓!\r\n那好,我就陪你谈谈国外的组织,但是声明我不理解你所指的组织。\r\n\r\n2002-01-30 22:24:02 浆糊\r\n例如apache,jive我想应该很多,一群技术人员,为了一个项目或者一组项目,始终孜孜不倦\r\n(通过服务器中转\r\n\r\n)\r\n\r\n2002-01-30 22:28:54 姑娘你真靓!\r\n恩。。。当然了。。。\r\n不过你想过吗,难道他们真的是自由组织吗???他们的背后是否有什么呢?\r\n\r\n2002-01-30 22:26:00 浆糊\r\n难道就没有 自由组织吗?\r\n我想也应该有”自由“的吧\r\n(通过服务器中转)\r\n\r\n2002-01-30 22:31:47 姑娘你真靓!\r\n应该有的,当然有,\r\n我刚才的话就回答了你,为什么中国没有APACHE等。\r\n(2002-01-30 22:28:54) 温婉宁静\r\n恩。。。当然了。。。\r\n不过你想过吗,难道他们真的是自由组织吗???他们的背后是否有什么呢?\r\n(通过服务器中转)\r\n\r\n2002-01-30 22:29:05 浆糊\r\n我也不知道,应该和国情也有关系。和人的素质有关吗?\r\n(通过服务器中转)\r\n\r\n2002-01-30 22:33:40 姑娘你真靓!\r\n和中国人的 多疑  有直接关系。\r\n\r\n2002-01-30 22:31:54 浆糊\r\n我想也是。\r\n网上见了那么多的讨论,从来就没有看到过坚持下去的,很伤心,也不知道是为什么伤心。\r\n只是想为什么国人就这么地 让人无奈\r\n(通过服务器中转)\r\n\r\n2002-01-30 22:36:23 姑娘你真靓!\r\n你怎么看 webpm \r\n\r\n2002-01-30 22:33:44 浆糊\r\n对于webpm我一开始觉得不错。\r\n但是看了webcvs的功能后,我觉得距离还是很大。\r\n\r\n对于组织的看法,还是两个字 “无助”\r\n(通过服务器中转)\r\n\r\n2002-01-30 22:38:59 姑娘你真靓!\r\n现在呢,破门 想主要依靠 WIKI ,也就是他说的要有特色,不象COSOFT 全部利用 论坛形式\r\n\r\n 。你觉得呢?\r\n\r\n2002-01-30 22:37:28 浆糊\r\n我觉得可以参考webcvs,的确很不错。\r\n\r\nwiki如果提供junit ,webcvs,online edit的话,我想还是不错,但是谁来做?我?一个人做一两年差不多。\r\n(\r\n\r\n通过服务器中转)\r\n\r\n2002-01-30 22:42:27 姑娘你真靓!\r\nWEBCVS我没用过, 不过 破门的 意思是 要有自己的特色。\r\n我问你一句话吧:\r\n  WEBPM 的主要目的是什么?\r\n\r\n2002-01-30 22:39:17 浆糊\r\n通过网络进行软件开发的一个平台。\r\n(通过服务器中转)\r\n\r\n2002-01-30 22:44:04 姑娘你真靓!\r\n如果你是 用户 你希望 WEBPM 提供什么呢?你会不会关心他是什么开发的呢???\r\n你是关心功能,还是关心他的是实现。\r\n\r\n2002-01-30 22:40:43 浆糊\r\n功能\r\n\r\n2002-01-30 22:45:29 姑娘你真靓!\r\n那你说 WEBPM 现在应该如何实现呢?\r\n\r\n2002-01-30 22:44:22 浆糊\r\n我的想法:\r\n借助现有的软件cvs来进行代码管理。\r\n让wiki支持onine edit ,ant.\r\n类似zope.\r\n这只是对于开发而言,项目管理和系统设以及交流还有很多要做。\r\n\r\n2002-01-30 22:49:28 姑娘你真靓!\r\n是啊。。。你对 WEBPM 的将来 怎么看?\r\n\r\n2002-01-30 22:46:20 浆糊\r\n有发展的机会,今后是网络的时代,网络合作是一种趋势\r\n\r\n2002-01-30 22:51:25 姑娘你真靓!\r\n是趋势,应该如何才能提高我们的开发效率呢。\r\n\r\n2002-01-30 22:48:38 浆糊\r\n首先是要保证投入和持续性。\r\n利用现有的软件设施,例如cvs等\r\n\r\n2002-01-30 22:54:00 姑娘你真靓!\r\n你认为现在 我们的进度,实现了多少呢???\r\n\r\n2002-01-30 22:50:45 浆糊\r\n5%\r\n\r\n2002-01-30 22:54:43 姑娘你真靓!\r\n0。1%\r\n\r\n2002-01-30 22:51:57 浆糊\r\n也许。不好确定。\r\n的确要做的太多了。\r\n\r\n\r\n2002-01-30 22:56:02 姑娘你真靓!\r\n现在是 目标 不明确,,,任务混乱。\r\n\r\n2002-01-30 22:52:43 浆糊\r\n人呢\r\n\r\n2002-01-30 22:57:14 姑娘你真靓!\r\n人,,,就你老兄时间用的多,\r\n\r\n2002-01-30 22:54:09 浆糊\r\n因为大家都忙,这也是原因\r\n\r\n2002-01-30 22:58:23 姑娘你真靓!\r\n恩,其实我们的实力很强的。\r\n\r\n2002-01-30 22:56:12 浆糊\r\n可是现在地情况看并不是这样,你觉得呢。目前我们很弱,至少作为一个团队来说。\r\n\r\n2002-01-30 23:00:49 姑娘你真靓!\r\n(2002-01-30 22:58:23) 温婉宁静\r\n恩,其实我们的实力很强的。\r\n\r\n\r\n我是说其实啊。。。我们每个人的实力很强,但是组合到一起,就成了低能的儿童。\r\n\r\n2002-01-30 22:57:31 浆糊\r\n我说的就是这个\r\n\r\n2002-01-30 23:02:29 姑娘你真靓!\r\n是的。我说的也是啊。。。\r\n\r\n2002-01-30 22:59:10 浆糊\r\n所以我也感到无奈。\r\n\r\n2002-01-30 23:04:13 姑娘你真靓!\r\n如果是你现在是 破门 你应该如何进行呢?\r\n\r\n2002-01-30 23:03:34 浆糊\r\n重新制定计划:\r\n1。开发过程的相关文档的形成\r\n2。每个小版本的发布计划\r\n3。人员的职责分配(很难)\r\n\r\n\r\n2002-01-30 23:08:09 姑娘你真靓!\r\n是的。。。老兄在提点好的,你刚才说的,大家都知道。:)\r\n\r\n2002-01-30 23:05:20 浆糊\r\n没有什么好的,就是这点,如果能做到,那已经很好了。\r\n你有什么好的。\r\n\r\n2002-01-30 23:09:51 姑娘你真靓!\r\n我也一直在想,如何能提高 网络协作开发的效率呢,就拿我们 WEBPM为例吧,这是很值得我们去研究的。。。\r\n\r\n。\r\n\r\n2002-01-30 23:07:07 浆糊\r\n我觉得网络很作不是大的问题,如果都有相关文档来形成标准,效率不会太差。\r\n\r\n2002-01-30 23:11:14 姑娘你真靓!\r\n真的,你肯定???\r\n\r\n2002-01-30 23:07:59 浆糊\r\n嗯。\r\n你有什么问题\r\n\r\n2002-01-30 23:12:54 姑娘你真靓!\r\n文档出来了,就一定能合作愉快吗?\r\n\r\n2002-01-30 23:09:35 浆糊\r\n不是网络很作,就是在一个屋子里面也不一定愉快\r\n\r\n2002-01-30 23:14:28 姑娘你真靓!\r\n是啊。。。这虽说是一个不可避免的问题,但是我们难道就不能找到一个好的解决办法 使它降到最底点吗??\r\n\r\n?\r\n\r\n如果我们能提出好的方法,这才是WEBPM 最大的成功。\r\n\r\n2002-01-30 23:11:49 浆糊\r\n但是不去做又如何能找到问题,如果知道想出来的办法是不是适合\r\n\r\n2002-01-30 23:16:05 姑娘你真靓!\r\n我现在一点思路都没有,又如何去实验呢???\r\n\r\n2002-01-30 23:12:42 浆糊\r\n关想能想出来吗?\r\n\r\n2002-01-30 23:17:28 姑娘你真靓!\r\n我能。。。老兄,不信你去实验吧,有一些东西,实验也是没用的。\r\n要靠自己的思路,不光是 软件这一行的, 生活经验等同等重要。\r\n\r\n2002-01-30 23:14:04 浆糊\r\n什么时候能想出来\r\n\r\n2002-01-30 23:18:03 姑娘你真靓!\r\n也许在干别的事时,突然发现了解决的方法。\r\n\r\n2002-01-30 23:18:11 姑娘你真靓!\r\n靠,那谁知道。:)\r\n\r\n2002-01-30 23:14:25 浆糊\r\n问题是什么\r\n\r\n2002-01-30 23:18:32 姑娘你真靓!\r\n问题是 如何提高网络协作开发的效率 \r\n\r\n2002-01-30 23:15:05 浆糊\r\n现在效率哪个方面低?\r\n\r\n2002-01-30 23:19:11 姑娘你真靓!\r\n最底的是 交流 \r\n\r\n2002-01-30 23:15:57 浆糊\r\n什么地方体现出来\r\n\r\n2002-01-30 23:19:57 姑娘你真靓!\r\n你想想,WEBPM 吧。\r\n\r\n2002-01-30 23:16:25 浆糊\r\n怎么了。\r\n\r\n2002-01-30 23:20:22 姑娘你真靓!\r\n交流的好吗???\r\n\r\n2002-01-30 23:21:07 姑娘你真靓!\r\n交流 如果只是 是 效率低还好,,,如果大家平常的用语和表达的方式不同,就惨了。\r\n\r\n2002-01-30 23:18:03 浆糊\r\n交流我觉得不是太大的问题。\r\n文档+聊天 基本可以凑活\r\n\r\n2002-01-30 23:22:20 姑娘你真靓!\r\n:) \r\n看法不同了。\r\n\r\n2002-01-30 23:18:41 浆糊\r\n但是我们现在主要的还不是这个问题,我感觉\r\n\r\n2002-01-30 23:23:16 姑娘你真靓!\r\n我们 WEBPM 的当然不是这个问题了。。\r\n我是说 如果想提出好的方法 那是个问题。\r\n\r\n2002-01-30 23:20:06 浆糊\r\n就事论事来说,当前webpnm的问题是什么\r\n\r\n2002-01-30 23:24:36 姑娘你真靓!\r\n任务的里程碑 不明确。\r\n\r\n2002-01-30 23:21:42 浆糊\r\n这个是问题。就是版本发布的阶段性不明确。\r\n需求也不明确。\r\n\r\n2002-01-30 23:26:13 姑娘你真靓!\r\n总之说句 破门不喜欢听的话, 文档的质量还需要提高 。\r\n\r\n2002-01-30 23:24:04 浆糊\r\n是的。这个要和破门说的。不然基本不能做下去了。\r\n结果就是大家失去信心,然后散伙\r\n\r\n2002-01-30 23:28:48 姑娘你真靓!\r\n那你看文档的结构应该如何呢?\r\n\r\n2002-01-30 23:27:13 浆糊\r\n版本: 下个版本的详细描述\r\n需求:详细的user story\r\n开发: 开发规范\r\n设计:test class,UML\r\n维护: bug report,\r\n也许还有其它的,你补充\r\n\r\n2002-01-30 23:32:17 姑娘你真靓!\r\n角色划分,\r\n角色目标,\r\n开发文档,\r\n\r\n\r\n2002-01-30 23:28:51 浆糊\r\n具体的\r\n\r\n2002-01-30 23:33:04 姑娘你真靓!\r\n什么意思?\r\n\r\n2002-01-30 23:30:09 浆糊\r\n开发文档 test and uml可以了。\r\n\r\n2002-01-30 23:34:37 姑娘你真靓!\r\n还是需要 文字的 :)\r\n\r\n2002-01-30 23:31:33 浆糊\r\n我觉得基本差不多,如果有的地方不是太清楚,可以用文字描述一下\r\n\r\n2002-01-30 23:35:58 姑娘你真靓!\r\n文字有文字的好处的。。。UML 和文字的都要,我认为最好。\r\n\r\n2002-01-30 23:34:02 浆糊\r\n嗯。可以。\r\n设想一下:\r\n文档详细,开发有user story描述,uml,代码有cvs,有统一的开发环境,有专人进行集成。\r\n还有什么问题\r\n\r\n2002-01-30 23:38:29 姑娘你真靓!\r\n你设想的那么好,我怎么知道还有什么问题。\r\n\r\n2002-01-30 23:35:07 浆糊\r\n可是我们没有这样试过,作了就知道问题了。\r\n\r\n2002-01-30 23:39:04 姑娘你真靓!\r\n是的。呵:)\r\n\r\n2002-01-30 23:35:36 浆糊\r\n咳\r\n\r\n2002-01-30 23:40:10 姑娘你真靓!\r\n明天和破门说说。\r\n\r\n2002-01-30 23:36:49 浆糊\r\n今天的谈话贴上去。\r\n\r\n2002-01-30 23:41:03 姑娘你真靓!\r\n那你不是出卖我了吗?小子。我可是说了破门坏话了。。:)\r\n\r\n2002-01-30 23:38:02 浆糊\r\n呵呵。。没有关系的,大家是讨论问题啊,破门不会在意的 :)\r\n\r\n2002-01-30 23:43:59 姑娘你真靓!\r\n那可不须修改,包括这句话,\r\n就从 你的 \r\nHERE?\r\n还是,到我这句话结束。\r\n\r\n2002-01-30 23:40:25 浆糊\r\n好的。\r\n\r\n2002-01-30 23:44:38 姑娘你真靓!\r\n那你就高兴点吧。\r\n\r\n2002-01-30 23:41:33 浆糊\r\n没有什么高兴的 :(\r\n\r\n2002-01-30 23:45:57 姑娘你真靓!\r\n哦。。那你就难受吧,我一会要去WC了,忍了好久了。\r\n----\r\n浆糊的难受说明他开始体会webpm的真正目标和需求,我很高兴,但绝对不是幸灾乐祸。\r\n破门 2002/1/31\r\n----\r\n分类:[WebPM] | [WebPM 小组会议]\r\n','浆糊','2002-01-31 15:45:24','2002-01-31 15:45:24',0,'N/A',87),('2002年1月31日 聊天记录','用户:16048561(brokendoor)\r\n\r\n==================================================\r\n消息组:WebPM\r\n==================================================\r\n消息类型:聊天记录\r\n==================================================\r\n\r\n--------------------------------------------------\r\n消息对象:3413384(浆糊)\r\n--------------------------------------------------\r\n破门 (17:03:34): 哦\r\n浆糊 (18:37:28): 在马?\r\n浆糊 (09:04:33): http://210.192.109.59:8080/webpm/jwiki/jwiki.jsp?topic=2002%C4%EA1%D4%C230%C8%D5+%C1%C4%CC%EC%\r\n破门 (09:06:15): 版本么?\r\n浆糊 (09:06:46): 什么意思\r\n破门 (09:06:51): 这个连接是什么?\r\n浆糊 (09:07:34): 昨天我们踏冰的谈话,关于webpm\r\n破门 (09:07:58): 我怎么连到起点了,呵呵\r\n浆糊 (09:08:44): WebPM 小组会议 \r\n破门 (09:09:28): 我看到最近变化了,我能理解你的心情\r\n浆糊 (09:10:25): 很茫然,也许是无奈。以前已经经历了不少\r\n浆糊 (09:11:14): \r\n还要就是我最近看了webcvs,的确是个好东西。\r\n\r\n破门 (09:11:17): 你现在感受的就是我原来提出webpm的目的,没有一个提供网络小组开发的环境\r\n浆糊 (09:11:54): 那国外的组织也不一定有这样的平台阿\r\n破门 (09:11:57): 很多东西没有办法组织,如果说我们是市集,也只是一个没有人光顾的小卖部\r\n破门 (09:12:23): 你看看我们的邮件小组一天有几封邮件?\r\n破门 (09:13:01): 我也只能抽出那么一点时间写了一些文档,但是远远不够\r\n浆糊 (09:13:45): 但是我想我们应该在现有的条件下能做的更好。因为我有这样的决心,我甚至可以写代码写到天亮,因为我觉得值得。\r\n浆糊 (09:14:26): 就像我们昨天讨论的,文档的质量不过关。\r\n破门 (09:15:21): 你如果参加了我在公司的项目,就会发现我现在的文档已经比我在公司写得好了\r\n破门 (09:15:31): 这里是交流的问题\r\n破门 (09:15:59): 很多时候我们的交流文档都没有好好的记录下来!\r\n浆糊 (09:16:53): \r\n呵呵。。\r\n不过因为网络开发有他的弊端,所以文档的详细能够减少一点这方面\r\n破门 (09:16:52): 而且,我需要一个一个人的面对面交谈。后来我发现了wiki,他可以解决重复这个问题。你现在不是这么做了么?\r\n浆糊 (09:17:27): \r\n是的。\r\n还有就是详细的版本计划。需求文档\r\n破门 (09:17:58): 这个是问题,我很高兴看到你们的讨论。你们发现了网络开发的一些问题\r\n浆糊 (09:18:34): 是的。因为我感到危机已经来领 :)\r\n破门 (09:19:06): 组织的松散,人员力量的分散,时间分配的不均匀性。等等\r\n破门 (09:19:40): 你如果到 clinux.org 上看,也会看到我的无奈\r\n浆糊 (09:20:30): \r\n你说的这个是问题。\r\n如何解决,好像挺难,完全要靠大家的对项目的热情和责任感\r\n破门 (09:20:58): 无论如何,我非常感谢JWiki的成果,他使得我们有了一个较好的交流场所。并且能够让其他网友看到我们的交流。wiki是很有用的\r\n破门 (09:21:27): 在web开发上,源代码管理是次要的。组织才是重要的\r\n浆糊 (09:21:54): \r\n我看到了,和我感受一样。\r\n就好像是在 一群聋子面前表演唱歌一样,无奈\r\n破门 (09:22:00): 信息发布是web的强项,所以一定要好好利用\r\n浆糊 (09:22:43): \r\n嗯。是的。\r\n但是我觉得如果能支持 online edit complie那就更好了。\r\n破门 (09:23:00): 需求要大家都能理解,理想需要细分为显示能够实现的部分\r\n浆糊 (09:23:23): \r\nhttp://cvs.apache.org/viewcvs.cgi/jakarta-alexandria/src/java/org/apache/alexandria/jxr/pacman/ImportType.java?annotate=1.3\r\n\r\n这是一个webcvs,你看看。我感觉很棒\r\n破门 (09:23:49): webcvs的功能我们就算不提供,webpm也会成功。只要我们解决了目前我们面临的问题\r\n浆糊 (09:24:23): \r\n是的。但是每个版本都应该有不同的,详细的需求文档。这样一个一个功能来实现。\r\n现在地情况是想到一些改一些,重复工作\r\n浆糊 (09:25:29): 我的感受是:目前webpm地问题是 文档。\r\n浆糊 (09:26:44): \r\n1。开发过程的相关文档的形成 \r\n2。每个小版本的发布计划 \r\n3。人员的职责分配(很难) \r\n\r\n\r\n版本: 下个版本的详细描述 \r\n需求:详细的user story \r\n开发: 开发规范 \r\n设计:test class,UML \r\n维护: bug report, \r\n\r\n角色划分, \r\n角色目标, \r\n开发文档, \r\n\r\n这些是我昨天和踏冰说的一些东西\r\n\r\n浆糊 (09:27:14): 如果大家时间紧,我可以停下来,写文档\r\n破门 (09:27:07): 嗯,wiki是新提出来的需求,我们需要时间。我给你的建议是不要立刻动手,让这些需求也列入待办事项。\r\n浆糊 (09:28:09): 但不能总是待办啊\r\n破门 (09:28:04): 你应该写的文档也必须早点提供出来。我写的编码标准大家都不执行,一定是有问题,但是又没有人提出来!\r\n破门 (09:28:51): 这是你的问题了,你需要有序的版本计划,就不要立刻动手。\r\n浆糊 (09:29:03): 嗯。这个我知道的。我太专注于wiki了\r\n浆糊 (09:29:31): 那应该如何?\r\n破门 (09:29:42): 我一直考虑,webpm太散乱。我们的力量无法集中。\r\n浆糊 (09:30:23): 是的。就像踏冰说的,我们每个人都很强,但是在一起却。。\r\n破门 (09:30:53): 这个问题是sourceforge也存在的,我一开始按照他们的功能提出需求。也是没办法,但是现在我想改变,尽量将基础设施建在同一的平台下\r\n浆糊 (09:32:10): 嗯。可以。我们甚至可以提供一个简单的webcvs,java来开发。\r\n破门 (09:32:28): cvs 我想用现成的\r\n浆糊 (09:32:59): \r\n那也可以。\r\n总之是少不了的。\r\n破门 (09:33:18): 下一步我想集中力量在过程管理上,wiki的功能我觉得暂时够了。\r\n破门 (09:33:37): 我一直在问你code标记支持的怎么样了\r\n破门 (09:34:07): 因为wiki上进行过程管理扩展会依赖于这个技术\r\n浆糊 (09:34:17): \r\n我昨天一直在弄这个。\r\n彩色代码的只是马上就可以实现了。\r\n浆糊 (09:34:44): \r\n嗯。好的。\r\n我用的apache的code view改进的。\r\n破门 (09:34:50): 不需要马上提供彩色代码支持,这些可以在版本计划中描述。\r\n浆糊 (09:35:09): webcvs的code view真是做的太棒了。\r\n破门 (09:35:17): 所以我说,待办列表就让他待办好了。\r\n浆糊 (09:35:29): 不过现在应该马上可以支持了。\r\n破门 (09:35:44): 你只要支持了空格,这个版本计划就可以结束了!\r\n浆糊 (09:36:17): \r\n那好。\r\n我尽快吧。\r\n破门 (09:36:29): 我暂时没有整理wiki标记,因为这个不是当前的优先级\r\n浆糊 (09:38:27): \r\n嗯。好的。\r\n但是下个版本的计划要出来了。\r\n我的规范也要出来。以及这个版本的开发文档。\r\n人员职责,也就是角色划分和目标\r\n\r\n破门 (09:38:38): 这个需要开发布计划会议!\r\n破门 (09:38:57): 你整理好规范,我会整理出新的需求\r\n浆糊 (09:40:11): 是啊。如何进行,什么时候,多少时间完成。主要内容。 这些应该发布出来\r\n浆糊 (09:40:22): 好的。\r\n破门 (09:40:43): 这个都是会议要讨论,看一下XP的发布计划和迭代计划的描述就知道了\r\n浆糊 (09:41:17): 嗯,这个你来把握吧\r\n破门 (09:41:22): 好的\r\n破门 (09:42:09): 这之前我还是要先完成工作流的介绍文档,你可以看回书或者忙一下公司的事了。\r\n浆糊 (09:42:54): 我要做 code\r\n破门 (09:43:07): 嗯,还要写这个标记的接口处理说明\r\n浆糊 (09:43:37): 好。这些我会在开发文档里写的。\r\n破门 (09:44:10): 好的,成功会一步一步向我们靠近的!\r\n浆糊 (09:45:15): 嗯。那我开工了。\r\n破门 (09:45:23): 我也开工了\r\n\r\n----\r\n分类: [WebPM] | [WebPM 小组会议]','BrokenDoor','2002-01-31 10:41:10','2002-01-31 10:41:10',0,'61.141.204.2',88),('WfMC','一个关于工作流标准的组织:\r\nhttp://www.wfmc.org\r\n\r\n* [WfMC Standards]\r\n\r\n----\r\n分类:[工作流]','BrokenDoor','2002-02-01 10:48:39','2002-02-01 10:48:39',0,'61.141.204.2',92),('WfMC Standards','\'\'\'WfMC Standards\'\'\'\r\n\r\nPublications and working documents on standards still under development reside on the members only pages. If you have a need to have an early view of standards before they are published, these can now be made available on application to the [WfMC Secretariat|http://www.wfmc.org/contact.htm].\r\n(Scroll down for \'\'\'\'\'General Publications\'\'\'\'\') \r\n\r\nTo help you navigate to the documents you need, read this first\r\n[Workflow Standards and Associated Documents|http://www.wfmc.org/standards/docs/Stds_diagram.pdf] [本地|/wfmc/Stds_diagram.pdf]\r\n(One page PDF Document)\r\n[WfMC Document Index|http://www.wfmc.org/standards/docs/docindex.pdf] (PDF) [本地|/wfmc/docindex.pdf]\r\nTC-1002 Issue 5.0 March \'99 (7 pages 30KB)\r\n\r\n* \'\'\'Interface 1\'\'\' - Process Definition Interchange \r\n** V 1.1 Final (WfMC-TC-1016-P) [510Kb pdf|http://www.wfmc.org/standards/docs/TC-1016-P_v11_IF1_Process_definition_Interchange.pdf] (October \'99) [本地|/wfmc/TC-1016-P_v11_IF1_Process_definition_Interchange.pdf]\r\n \r\n** Process Definition Q & A and Examples \r\n(WfMC-TC-1016-X) [174Kb pdf|http://www.wfmc.org/standards/docs/TC-1016-X_Process_Definition_Interchange_QnA_IF1.PDF]\r\n[本地|/wfmc/TC-1016-X_Process_Definition_Interchange_QnA_IF1.PDF]\r\n \r\n** \'\'\'Workflow Process Definition Interface -- XML Process Definition Language. (XPDL)\'\'\' (May 22, 2001) \r\n\'\'\'Document Number WFMC-TC-1025\'\'\'\r\n\'\'\'Document Status – Draft 0.03a (Alpha Status)\'\'\'\r\nThis forms part of the documentation relating to “Interface one” - supporting Process Definition Import and Export. This interface includes a common meta-model for describing the process definition and also a DTD for the interchange of process definitions.\r\n[XPDL_010522.PDF|http://www.wfmc.org/standards/docs/xpdl_010522..pdf] (329kb)\r\n[XPDL.DTD|http://www.wfmc.org/standards/docs/xpdl.dtd] (7kb)\r\nThe intended audience for this document is primarily vendor organizations who seek to implement the XML Process Definition Language (XPDL) of the Workflow Management Coalition (WfMC). It may also be of interest to those seeking to assess conformance claims made by vendors for their products. Comments should be addressed to the Workflow Management Coalition.\r\n \r\n* \'\'\'Interface 2\'\'\' - Workflow Client Application Application Programming Interface (Interface 2 & 3) Specification \r\n**(WFMC-TC-1009 - Specification) V 2.0 [494Kb pdf|http://www.wfmc.org/standards/docs/if2v20.pdf]\r\n**(WFMC-TC-1013 - Naming Conventions) V 1.4 [74Kb pdf|http://www.wfmc.org/standards/docs/tc013v14a.pdf]\r\n**(WfMC-TC-1009 - Specification) V 1.1 [207Kb pdf|http://www.wfmc.org/standards/docs/if21009v11.PDF]\r\n \r\n \r\n* \'\'\'Interface 3\'\'\' - Invoked Applications \r\nnow amalgamated into Interface 2, TC-1009. \r\n \r\n* \'\'\'Interface 4\'\'\' - Interoperability \r\n[Abstract Specification WFMC-TC-1012|http://www.wfmc.org/standards/docs/TC-1012_Nov_99.pdf] (PDF) November \'99 2.0a 208KB\r\nAbstract Specification (WFMC-TC-1012, 20-Oct-96, 1.0) [147Kb pdf|http://www.wfmc.org/standards/docs/if4-a.pdf] \r\n \r\n* \'\'\'Interface 4\'\'\' - Interoperability \r\nInternet e-mail MIME Binding\r\n(WFMC-TC-1018, 7-Jan-00, Version 1.2) [373Kb pdf|http://www.wfmc.org/standards/docs/tc018v12.pdf]\r\n \r\n* \'\'\'Interface 4\'\'\' - Interoperability\r\n \r\n** \'\'\'[Proposal for an Asynchronous HTTP binding of Wf-XML|http://www.wfmc.org/standards/docs/http_binding_proposal.pdf] June 1, 2000\'\'\'\r\nThis document represents a workflow protocol that aims for interoperable, reliable and practical interactions between services using HTTP protocol. This protocol is based on Wf-XML and extended for the sake of enterprise EDI applications.\r\n(66 pages PDF 184kb)\r\n \r\n** \'\'\'Interoperability Wf-XML Binding (May 8, 2000)\'\'\' \r\n[Wf-XML Binding Document Number WFMC-TC-1023|http://www.wfmc.org/standards/docs/Wf-XML-1.0.pdf] \r\n[Wf-XML v1.0 DTD|http://www.wfmc.org/standards/docs/Wf-XML-1.0.dtd] \'\'\'(for developers)\'\'\'\r\nThis document represents a specification for an XML language designed to model the data transfer requirements set forth in the Workflow Management Coalition’s Interoperability Abstract specification (WFMC-TC-1012) [1]. This language will be used as the basis for concrete implementations of the functionality described in the abstract in order to support the WfMC’s Interface 4 (as defined by the workflow reference model [2]).\r\n \r\n** \'\'\'Access database of tracked Wf-XML comments\'\'\' (courtesy of [Joseph Rogowski|mailto:rogowski@mail1.monmouth.army.mil] and [Michael Rossi|mailto:mrossi@crusher.jcals.csc.com]) \r\n \r\n* \'\'\'Interface 5\'\'\' - Audit Data Specification \r\n(WFMC-TC-1015, 22-Sep-98, 1.1) [211Kb pdf|http://www.wfmc.org/standards/docs/if5v11b.PDF]\r\n \r\n\'\'\'\'\'WfMC General Publications\'\'\'\'\'\r\nPlease ensure that you have the most recent version of [Adobe Acrobat|http://www.adobe.com/products/acrobat/readstep.html] when downloading these documents, otherwise you may encounter font and other format errors. \r\n\r\n* \'\'\'[Workflow: An Introduction|http://www.wfmc.org/standards/docs/Workflow_An_Introduction.pdf] by Rob Allen, Open Image Systems Inc., UK\'\'\'\r\nA free chapter from the [Workflow Handbook 2001|http://www.wfmc.org/information/handbook.htm] (24 pages PDF)\r\n \r\n* [The Key to e-Commerce and to Process Scalability|http://www.wfmc.org/standards/docs/article_key_to_ecommerce.PDF]\r\nArticle by Working Group 4 (PDF 12 pages, 73 kb)\r\n \r\n* \'\'\'White paper:\'\'\' [Stand-alone and embedded workflow management systems|http://www.wfmc.org/standards/docs/MzM_RA_WfMC_WP_Embedded_and_Autonomous_Workflow.pdf].\r\n8 pages, PDF format\r\n\'\'Michael Zur Muehlen and Rob Allen. March 10, 2000\'\'\r\nThis paper distinguishes, at a high level, the differences between workflow engines and simple trigger routines. Its main function is to clarify the segmentation between autonomous and embedded workflow deployment. \r\n \r\n* \'\'\'[White Paper - Events|http://www.wfmc.org/standards/docs/Workflow_events_paper.pdf]\'\'\'\r\n\'\'David Hollingsworth, ICL A&TC. 11 pages, WinWord. April 99.\'\'\r\nThis document contains a proposed approach for classifying and handling the processing associated with Events. It includes proposals for extensions to I/Fs 1, 2/3 and 4 (and potentially audit data which may be associated with particular event occurrences). It builds upon the proposals originally made by Steve Dworkin (May 1998) and earlier draft notes from Klaus Dieter Kreplin, Dave Holllingsworth and Mike Anderson.\r\n \r\n* \'\'\'[Discussion Paper - A Common Object Model|http://www.wfmc.org/standards/docs/TC-1022_commom_Object%20Model_Paper.pdf]\'\'\' \r\nDocument Number - WfMC-TC-1023, by \'\'David Hollingsworth, ICL A&TC.\'\' March 99. 16 pages, WinWord.\r\nThis document describes the current status of the WfMC standardization program and identifies the current work on object related standards which includes interface bindings for both OLE Automation and OMG/IDL objects. The scope of the current Reference Model is discussed, plus possible extensions to support a lower granularity component architecture, internal to the workflow enactment service, as a complement to existing work focused on the service functions provided at the boundary of a workflow enactment service. This is postulated on the basis of defining a common underlying object model which can be mapped to the two important component architectures emerging in the industry, the OMG object architecture and services and the ActiveX/DCOM architecture.\r\n \r\n* \'\'\'Workflow Interoperability - Enabling E-Commerce\'\'\'\r\nApril 1, 1999 WfMC White Paper [83kb pdf|http://www.wfmc.org/standards/docs/IneropChallPublic.PDF]\r\n \r\n* \'\'\'Workflow and the Internet: Catalysts for Radical Change\'\'\'\r\nJune 11, 1998. WfMC announces major [White Paper|http://www.wfmc.org/standards/docs/Workflow_Internet_catalysts_for_change.pdf]. \r\n \r\n* \'\'\'JSA Interworkflow Definition\'\'\'\r\nFeb 1997 (WfMC TC 2102) [98kb pdf|http://www.wfmc.org/standards/docs/Jsa2102.pdf] \r\n\r\n\'\'\'Presentation by Kanagawa Institute of Technology\'\'\'\r\non Interworkflow Management System\r\n(Tokyo, Dec 3, 1999) [193kb|http://www.wfmc.org/standards/docs/Tokyointerworkflow.pdf] (New) \r\n \r\n* \'\'\'Reference Model\'\'\' - The Workflow Reference Model\r\n(WFMC-TC-1003, 19-Jan-95, 1.1) [211Kb pdf|http://www.wfmc.org/standards/docs/tc003v11.pdf] \r\n \r\n* \'\'\'Terminology & Glossary\'\'\'\r\n(WFMC-TC-1011, Feb-1999, 3.0)\r\nEnglish: [198Kb pdf|http://www.wfmc.org/standards/docs/TC-1011_term_glossary_v3.pdf] (Revised)\r\nFrench: (of Version 2.0) : [68Kb pdf|http://www.wfmc.org/standards/docs/Glossary_French.PDF]\r\n \r\n* \'\'\'Workflow Security Considerations\'\'\'\r\nWhite Paper [54Kb pdf|http://www.wfmc.org/standards/docs/secure1.pdf]\r\n \r\n* \'\'\'[Workflow Standards and Associated Documents|http://www.wfmc.org/standards/docs/Stds_diagram.pdf]\'\'\'\r\n(One page PDF Document)\r\n \r\n-----\r\n分类: [工作流] | [WfMC]','BrokenDoor','2002-02-01 10:47:46','2002-02-01 10:47:46',0,'61.141.204.2',93),('WebPM JWIKI','mytest','127.0.0.1','2002-02-01 16:55:34','2002-02-01 16:55:34',0,'127.0.0.1',94),('2002年2月6日 会议记录','□ 欢迎光临『QQ聊天中心』的【自建聊天室(六)】□ \r\n\r\n★欢迎您来到『webpm』房间★ \r\n \r\n破门: 来了 \r\n \r\n浆糊: 呵呵。。那个家伙呢? \r\n \r\n破门: 等一下他会找我 \r\n \r\n浆糊: 那我们先开始吧 \r\n \r\n破门: 好!先讨论给wiki增加用户管理 \r\n \r\n浆糊: 你看了webpm_wiki吗,我写了一些简单的故事提要 \r\n \r\n破门: 我看了, preview, 统计等可以让其他人做 \r\n \r\n破门: 编辑保护用什么策略? \r\n \r\n浆糊: 编辑保护的话,只要找出最近的,然后比较一下就可以了。 \r\n \r\n浆糊: 本地话支持你觉得要吗?如:多语言支持 \r\n \r\n踏冰: 大家好。 \r\n \r\n破门: 维护一个关键字锁定标志好不好? \r\n \r\n浆糊对破门说: 什么意思? \r\n \r\n破门: 在keyindex里面加一个 \r\n \r\n浆糊: 谁做会议记录? \r\n \r\n踏冰对浆糊说: 别说让我。 \r\n \r\n浆糊对破门说: 这个会有问题的。例如有的人想编辑,但是最后没有编辑 \r\n \r\n破门: 嗯 \r\n \r\n破门: 比较最后修改时间应该可以 \r\n \r\n浆糊对破门说: 是的。 \r\n \r\n破门: 本地化我们必须考虑,不然以后会很麻烦 \r\n \r\n破门: 不过问题是,数据库的内容怎么办? \r\n \r\n浆糊对破门说: 数据库的内容就别翻译了,不然乱了 \r\n \r\n破门: 那本地化可以不管,没有几个页面,做个skin就行了 \r\n \r\n浆糊对破门说: 那么我们列一下现有的需求吧。 \r\n \r\n浆糊对破门说: 然后再确定优先级 \r\n \r\n浆糊对破门说: 和实现方法 \r\n \r\n破门: 好吧,目前提出的故事有三大块: \r\n \r\n破门: wiki \r\n \r\n破门: workflow \r\n \r\n破门: 白板 \r\n \r\n浆糊对破门说: chat是不是? \r\n \r\n破门: 算是吧。whiteboard+chat \r\n \r\n浆糊对破门说: 嗯,这个是三大方面。 \r\n \r\n破门: 一个个来,先说wiki \r\n \r\n浆糊对破门说: 1。用户注册 \r\n \r\n浆糊对破门说: 2。项目注册 \r\n \r\n浆糊对破门说: 其实这两个算是webpm的,不属于wiki \r\n \r\n破门: 算wiki扩展 \r\n \r\n浆糊对破门说: 那么项目管理的支持是不是也是一个子项目? \r\n \r\n破门: 那时工作流扩展。应该这样写:wiki标记扩展接口 \r\n \r\n浆糊对破门说: 这个需要workflow提出具体的需求 \r\n \r\n破门: preview \r\n \r\n破门: diff \r\n \r\n浆糊对破门说: 要什么样的接口,完成什么样的功能,有一个描述 \r\n \r\n浆糊对破门说: diff的实现是个问题 \r\n \r\n踏冰对浆糊说: 产生WIKI页面的接口。 \r\n \r\n破门: 这个接口必须通用化,就是定一个标记,然后写处理这个标记的扩展程序。返回解释后 \r\n \r\n破门: 就是最后的 html。 \r\n \r\n浆糊对破门说: workflow的用户故事有没有出来? \r\n \r\n破门: 没有 \r\n \r\n浆糊对破门说: 接口的没有问题。 \r\n \r\n破门: 但是上回也讨论过了,首先是代办事项列表。 \r\n \r\n破门: 流程定义是下一步。但是流转控制还没有讨论 \r\n \r\n破门: wiki 里增加用户信息的话应该如何实现? \r\n \r\n踏冰对破门说: 你指的是如何增加呢? \r\n \r\n踏冰对破门说: 用WIKI页面保存用户信息? \r\n \r\n浆糊对破门说: [user=brokendoor]怎么样 \r\n \r\n破门对踏冰说: 问题是,用用户信息查询的时候怎么做? \r\n \r\n浆糊对破门说: 用户信息查询 什么意思 \r\n \r\n破门对踏冰说: 用wiki保存用户信息没问题。如果要求用户登陆该如何处理? \r\n \r\n踏冰对破门说: 我看查询,可以利用搜索啊。 \r\n \r\n踏冰对破门说: 登录也应该没问题的。 \r\n \r\n踏冰对破门说: WIKI 的页面是如何存储在库中的。 \r\n \r\n破门对踏冰说: 怎么区分一篇文章是用户创建的还是仅仅进行了修改? \r\n \r\n踏冰对浆糊说: 你先回答我 \r\n \r\n踏冰对破门说: 等浆糊说。 \r\n \r\n浆糊对踏冰说: 可以看数据库结构 \r\n \r\n踏冰对浆糊说: 我没看 \r\n \r\n踏冰对浆糊说: 你先说一下, \r\n \r\n踏冰对浆糊说: WIKI页面的内容是如何存的。 \r\n \r\n踏冰对浆糊说: 是不是把所有文本都存到一个字段里了。 \r\n \r\n浆糊对踏冰说: 每一篇文章都有修改者 \r\n \r\n浆糊对踏冰说: 是文章内容 \r\n \r\n踏冰对浆糊说: 哦。。 \r\n \r\n浆糊对破门说: 好像不是太好确定 \r\n \r\n踏冰对破门说: 用户注册的时候就可以把用户信息单独保存在一个表中。 \r\n \r\n破门: 这是很大的问题 \r\n \r\n踏冰对破门说: 登录,还是用表了。 \r\n \r\n破门: 嗯,我们当时也是认为必须用表 \r\n \r\n破门: 所以我才问如何跟wiki结合 \r\n \r\n踏冰对破门说: 我发出去的那个已经做好了。 \r\n \r\n踏冰对破门说: 和WIKI结合,你想如何结合? \r\n \r\n踏冰对破门说: 你指什么时候需要呢? \r\n \r\n踏冰对破门说: 能不能说的具体点,什么时候需要结合,什么时候你需要用户信息。 \r\n \r\n破门: 我希望能够在wiki中查询到用户创建的文章和修改过的文章 \r\n \r\n浆糊对破门说: 关于踏冰的程序,我想需要按照开发规范来 \r\n \r\n踏冰对浆糊说: 可不可以修改库结构。 \r\n \r\n踏冰对浆糊说: OK。 \r\n \r\n踏冰对浆糊说: 呵呵:) \r\n \r\n破门对浆糊说: 嗯,规范一定要执行,不然就需要返工 \r\n \r\n浆糊对破门说: 可以,不过需要改动现有的实现类。 \r\n \r\n破门对浆糊说: 这里就是wiki接口的下一个问题,需要扩展数据库存储 \r\n \r\n踏冰对浆糊说: 那,文章的基本信息的表中,有没有 标识呢? \r\n \r\n浆糊对破门说: 其实主表里面存的都是最新的文章,为什么要区别新建的和修改的呢? \r\n \r\n破门: 我说一下我在公司工作流管理里面的做法,你们参考一下 \r\n \r\n浆糊对破门说: 如果要查询这个用户的文章,只要查author字段就可以了阿 \r\n \r\n破门: 嗯,如果要修改wiki源程序才能保存author的话就不太好 \r\n \r\n浆糊对破门说: wiki的数据库扩展 一般来说不对现有接口提出新需求,修改不是太麻烦 \r\n \r\n浆糊对破门说: 现在就有author \r\n \r\n破门: 我们很难不提出新需求,不过可以不断重构。 \r\n \r\n浆糊对破门说: 每一篇文章都有author and mender \r\n \r\n浆糊对破门说: 是的。 \r\n \r\n破门: 可能我这里想的太多了 \r\n \r\n浆糊对破门说: 不考虑明天的需求,呵呵。。 \r\n \r\n破门: 就这样吧,用踏冰做的用户注册程序(要先改成符合规范:))。 \r\n \r\n踏冰对破门说: 哦。 \r\n \r\n浆糊对破门说: 我的代码已经给踏冰了 \r\n \r\n破门: wiki的用户信息由session信息里取,怎么样? \r\n \r\n踏冰对浆糊说: 代码给我干什么??? \r\n \r\n踏冰对浆糊说: :( \r\n \r\n浆糊对破门说: wiki里面的用户信息用来做什么? \r\n \r\n浆糊对踏冰说: 参考阿,呵呵。。 \r\n \r\n破门: author 不能总是ip地址吧? \r\n \r\n踏冰对浆糊说: 参考个鸟啊,你还是弄个规范出来吧。 \r\n \r\n浆糊对破门说: 现在地问题是没有具体的用户故事的描述 \r\n \r\n踏冰对浆糊说: 你你写的东西我怎么参考,还是弄个规范出来得了。 \r\n \r\n破门: 规范已经修订了,在wiki里 \r\n \r\n浆糊对破门说: 我已经弄好了阿。在wiki里面啊。 你这只。。。 \r\n \r\n踏冰对浆糊说: 哦。没去看,昨天你小子的机器关了吧。 \r\n \r\n破门对浆糊说: 分清楚目标! \r\n \r\n浆糊对破门说: 呵呵。。。sorry :) \r\n \r\n破门: 好了,下面还是讨论wiki的问题 \r\n \r\n浆糊: ok! 我想下个阶段把信息发布功能继续加强 \r\n \r\n破门: 下面就是wiki页面模板,提供给项目注册后的主页 \r\n \r\n浆糊: 例如:彩色代码支持 \r\n \r\n浆糊: 不处理wiki代码的标签(很重要) \r\n \r\n浆糊: 多语言处理 \r\n \r\n破门: 彩色代码支持,先支持java \r\n \r\n浆糊: 是的。 \r\n \r\n破门: 多语言处理,改成支持换肤吧 \r\n \r\n浆糊: 大家有么有其它的需求? \r\n \r\n破门: 除了页面,我们没有其他的东西需要多语言支持了。 \r\n \r\n浆糊: 多语言支持实现不麻烦,皮肤的话,维护太繁琐,要修改两个版本 \r\n \r\n破门: 皮肤可能会方便使用者的创意展示 \r\n \r\n浆糊: 可以我们提供了多语言的皮肤(jsp)了阿 \r\n \r\n破门: 嗯,这样也好 \r\n \r\n浆糊: 还有其它的需求吗? \r\n \r\n破门: 这个阶段应该够了 \r\n \r\n破门对踏冰说: 你看呢? \r\n \r\n浆糊: 恩。那整理一下就是下个版本的发布计划了 \r\n \r\n踏冰对破门说: 够了,马上就过年了。 \r\n \r\n踏冰对破门说: 春节要到了,我明天就得回家了。 \r\n \r\n浆糊: 我10号回家 \r\n \r\n踏冰对浆糊说: 明天是 6 号。差不多了。 \r\n \r\n浆糊: 这4,5天时间可以完成不少功能 \r\n \r\n破门对浆糊说: 嗯,做不完都汇总给我。我春节留在深圳。 \r\n \r\n浆糊: 恩,好。 \r\n \r\n破门对浆糊说: 数据库备份也要! \r\n \r\n浆糊: 文档什么时候出来?具体的用户故事,发布计划等。。 \r\n \r\n破门对浆糊说: 我们还是要集中力量,个个突破! \r\n \r\n破门对浆糊说: 今晚以前! \r\n \r\n浆糊: 好! \r\n \r\n踏冰: 哦。 \r\n \r\n踏冰: 不错的计划。 \r\n \r\n破门对浆糊说: 那么,故事就这么多。我们讨论一下发布计划 \r\n \r\n浆糊: 其它子项目暂时不进行? \r\n \r\n踏冰: 强迫自己。 \r\n \r\n破门对浆糊说: 暂停,反正一直都在暂停。 \r\n \r\n浆糊: 发布计划要讨论些什么问题? \r\n \r\n浆糊: 关于wiki对项目管理的支持在这个版本里面不支持是不是? \r\n \r\n破门对浆糊说: 每一个故事的时间点。人员 \r\n \r\n踏冰对破门说: 对了,你以前弄的那个主页呢? \r\n \r\n踏冰对破门说: 还有 JAKAKA 弄的。 \r\n \r\n破门对踏冰说: 哪个? \r\n \r\n浆糊: 1。多语言支持 浆糊 1天 \r\n \r\n踏冰对破门说: 就以前 SOFTME 的那个。 \r\n \r\n破门对踏冰说: brokendoor.myetang.com \r\n \r\n浆糊: 我现在还有一个中文问题没有完工 \r\n \r\n破门对踏冰说: 2.用户注册修改 踏冰 时间点? \r\n \r\n踏冰对破门说: 老兄,修改 0。5 天就够了。 \r\n \r\n浆糊: 3。不解释wiki的标签 浆糊 2天 \r\n \r\n踏冰对破门说: 我这几天在收拾行李呢 \r\n \r\n浆糊对踏冰说: 靠,这么急,是不是有mm在家等你啊 \r\n \r\n破门对踏冰说: 那你抽0.5天改一下啊! \r\n \r\n踏冰对浆糊说: 要是有MM 就不用急了。 \r\n \r\n踏冰对破门说: 好的,我会的。。 \r\n \r\n踏冰对破门说: 我看了规范了。 \r\n \r\n踏冰对破门说: 不还是那以前那个版本吗? \r\n \r\n踏冰对破门说: 没什么变化了。。。。。。 \r\n \r\n破门对踏冰说: 4. 用户注册与wiki的结合 破门 0.5天 \r\n \r\n浆糊: 有啊,你没有仔细看而已,就照那个来吧 \r\n \r\n踏冰对浆糊说: 靠,那我的表都得改。 \r\n \r\n破门对踏冰说: 5、preview, 编辑保护 破门 1d \r\n \r\n踏冰对浆糊说: 问一下,MYSQL 中,流水号 能搞定吗? \r\n \r\n浆糊: 5。彩色代码支持 需要在3地基础上 1天 \r\n \r\n浆糊: 你要问破门,流水号他明白 \r\n \r\n破门: 6、preview, 编辑保护 破门 1d \r\n \r\n破门对踏冰说: mysql 的流水号可以用 \r\n \r\n浆糊: java diff如何解决?网上有一些现成的,但是要转到web上来也不容易,因为要对代码 \r\n \r\n踏冰对破门说: 我用别的DBMS 弄的。那就好。 \r\n \r\n破门对浆糊说: diff 延期吧 \r\n \r\n浆糊: 踏冰在修改程序的时候,数据库操作请参考我的程序好吗,尽量保持统一 \r\n \r\n踏冰对浆糊说: 好,好。 \r\n \r\n踏冰对浆糊说: :) \r\n \r\n踏冰对浆糊说: 不过,我要是没时间改了怎么办。 \r\n \r\n浆糊: 你发给破门吧,呵呵。。 \r\n \r\n破门对浆糊说: 7、wiki 页面模板 做不做? 好像来不及 \r\n \r\n踏冰对浆糊说: 如果没时间改了,就算 OVER了,然后我在补上。 \r\n \r\n踏冰对浆糊说: 我尽量找时间。 \r\n \r\n浆糊: 7。是什么意思? \r\n \r\n浆糊: 皮肤?jive有个皮肤的支持,到时候参考一下 \r\n \r\n破门对浆糊说: 第七个故事啊 \r\n \r\n浆糊: 7。我是说具体的意思 \r\n \r\n破门对浆糊说: 项目缺省主页 \r\n \r\n破门对浆糊说: 我觉得还是放后吧。 \r\n \r\n浆糊: 静态页面?可以考虑做一个 \r\n \r\n破门对浆糊说: 7、wiki skin \r\n \r\n破门对浆糊说: 模板应该是 wiki 文章的模板。最好是数据库 \r\n \r\n浆糊: “模板应该是 wiki 文章的模板。最好是数据库 “ 这个不是很理解 \r\n \r\n破门对浆糊说: 我们创建项目的时候,自动根据项目名称和模板创建项目主页相关的wiki页。 \r\n \r\n破门对浆糊说: 这个模板的内容可能需要根据项目信息进行必要的替换。 \r\n \r\n浆糊: 哦,这个地话,我考虑过了,需要考虑不少的问题 \r\n \r\n破门对浆糊说: 所以我们放到下一个计划吧 \r\n \r\n浆糊: 例如:库表的结构修改,关键字的问题等等。。 \r\n \r\n浆糊: 嗯。好。 \r\n \r\n破门对浆糊说: 那么第七个故事 wiki skin \r\n \r\n破门对浆糊说: 要不要我来做? \r\n \r\n破门对浆糊说: 破门 3d \r\n \r\n浆糊: wiki skin具体是什么? \r\n \r\n破门对浆糊说: 多语言支持和页面样式 \r\n \r\n浆糊: 哦,你完成多语言? \r\n \r\n浆糊: 这个优先级不是太高,现在地页面也不错 \r\n \r\n破门对浆糊说: 嗯 \r\n \r\n破门对浆糊说: 会不会牵涉到数据库驱动的问题? \r\n \r\n浆糊: 那这个先不考虑吧。 \r\n \r\n浆糊: 不会,因为数据库的问题,在业务层已经处理了 \r\n \r\n浆糊: 只要保证参数传递的时候都是正确的中文就可以了。 \r\n \r\n破门对浆糊说: 嗯。 \r\n \r\n浆糊: 用户故事还有马? \r\n \r\n破门对浆糊说: 应该说,多语言支持当中只有中文最难! \r\n \r\n浆糊: 最近浏览页面统计; 和点击数统计 要在这个版本里面实现马? \r\n \r\n破门对浆糊说: 多平台支持算不算 \r\n \r\n浆糊: 多平台支持已经做的差不多了。 \r\n \r\n破门对浆糊说: 8、最近浏览页面统计; 点击数统计 \r\n \r\n破门对浆糊说: 有没有其他帮忙的 \r\n \r\n浆糊: 好像没有 :( \r\n \r\n破门对浆糊说: 鸽子呢? \r\n \r\n浆糊: 他不再 \r\n \r\n破门对浆糊说: 他有没有时间?是不是已经放假回家了? \r\n \r\n浆糊: 不知道。没有联系过了。 \r\n \r\n浆糊: 要不这两个先不确定人员,但是要在这个版本里面完成。 \r\n \r\n破门对浆糊说: 好吧。我看你的时间已经够了。这个先算我的,要2d \r\n \r\n浆糊: 最近浏览页面统计的实现方式我想不用数据库,直接记录在内存里算了。 \r\n \r\n踏冰: 二位仁兄 : 我要下了,有MM 找啊。:) \r\n \r\n踏冰: 你们聊吧。 \r\n \r\n破门对浆糊说: 呵呵,这个计划到节后了 \r\n \r\n浆糊: 靠! \r\n \r\n浆糊: 好 \r\n \r\n破门对踏冰说: 小心啊,别是人妖! \r\n \r\n踏冰对破门说: 怎么会呢。 \r\n \r\n浆糊: 估计他就喜欢 \r\n \r\n踏冰: http://www.tabing.8u8.com/project_nrff/Project_web/workflow/nrffworkflow.zip \r\n \r\n浆糊: 什么东西阿 \r\n \r\n踏冰: 简单看一下,很多需要修改的。 \r\n \r\n踏冰对浆糊说: 看名字还不知道啊,笨蛋,切。 \r\n \r\n浆糊: 靠。人妖 \r\n \r\n踏冰对浆糊说: 妖个头啊。白。 \r\n \r\n破门对浆糊说: 妖~~。 \r\n \r\n浆糊对踏冰说: 呵呵。。 \r\n \r\n踏冰对破门说: 有时间给点指教了。 \r\n \r\n破门对踏冰说: 我会看的 \r\n \r\n踏冰对浆糊说: 我闪了,要不迟到了。 \r\n \r\n踏冰对破门说: 恩。 \r\n \r\n浆糊对踏冰说: 那么发布计划 地具体时间也应该出来了是不是? \r\n \r\n踏冰: 白 \r\n \r\n破门对浆糊说: 算一下。你的4d \r\n \r\n浆糊对破门说: 恩。争取年前完成。 \r\n \r\n破门对浆糊说: 我的 5 d \r\n \r\n破门对浆糊说: 春节前应该可以。 \r\n \r\n浆糊对破门说: 那么下一次的发布时间是什么时候? \r\n \r\n破门对浆糊说: 你什么时候上班? \r\n \r\n浆糊对破门说: 版本号是多少? \r\n \r\n浆糊对破门说: 8号 \r\n \r\n浆糊对破门说: 初8 \r\n \r\n破门对浆糊说: 差不多,我们2月21日发布吧。版本号还是 1.0。 \r\n \r\n破门对浆糊说: 明年我们主攻workflow! \r\n \r\n浆糊对破门说: 为什么是21号?问问而已。版本号不加一点? \r\n \r\n破门对浆糊说: 我 21 号上班 \r\n \r\n浆糊对破门说: 好得弄个 1.1阿 \r\n \r\n浆糊对破门说: 阿?你那么长的时间啊 \r\n \r\n浆糊对破门说: 那你在网上马? \r\n \r\n破门对浆糊说: 初十而已 \r\n \r\n破门对浆糊说: 20 号也行 \r\n \r\n浆糊对破门说: 哦,那好。 \r\n \r\n浆糊对破门说: 就21巴 \r\n \r\n破门对浆糊说: 好吧,我们20号下午碰头。准备发布!v1.1 \r\n \r\n破门对浆糊说: 21号去宣传 \r\n \r\n浆糊对破门说: ok! \r\n \r\n破门对浆糊说: 那先这样。我要去扛奖品了!:) \r\n \r\n浆糊对破门说: 那关于代码的lince怎么办? \r\n \r\n浆糊对破门说: 呵呵。。 \r\n \r\n破门对浆糊说: 我想过了,就先用 GPL 吧 \r\n \r\n浆糊对破门说: 还有帮助文件 \r\n \r\n破门对浆糊说: 嗯,文档永远是发布后的事 \r\n \r\n浆糊对破门说: 一些相关的文档,不少啊 \r\n \r\n浆糊对破门说: 哦,那好。 \r\n \r\n浆糊对破门说: 那你去吧,呵呵。。 \r\n \r\n破门对浆糊说: 好的 \r\n\r\n----\r\n分类: [WebPM] | [WebPM 小组会议] ','BrokenDoor','2002-02-05 17:28:13','2002-02-05 17:28:13',0,'61.141.204.2',123),('斯多夫死的test','Nothing','浆糊','2002-02-05 17:21:45','2002-02-05 17:21:45',0,'192.168.1.228',122),('2002年1月28日 会议记录','□ 欢迎光临『QQ聊天中心』的【自建聊天室(六)】□ \r\n \r\n★欢迎您来到『webpm』房间★ \r\n \r\n★这间房间的主人是『 OICQ_16048561 』★ \r\n \r\n浆糊: 我来了。 \r\n \r\n踏冰: 你昨天跑什么地方去了。 \r\n \r\n浆糊: 回家了。好久没有见老婆了,回家看了看 \r\n \r\nbrokendoor: 说一下昨天的内容 \r\n \r\n浆糊: 好。我的重构工作完成了一半。文章的部分好了。还差标签部分 \r\n \r\nbrokendoor: 我们昨天讨论了工作流的需求,还有网站的建设问题 \r\n \r\n浆糊: 有具体的文档马?需求 \r\n\r\nbrokendoor: 还没有空整理 \r\n\r\nbrokendoor: 我简单说一下:关于网站建设 \r\n\r\nbrokendoor: webpm的网站全部主页都会建立在wiki的基础上! \r\n \r\n浆糊: 这点我同意。就是要对wiki进行扩展 \r\n \r\nbrokendoor: 需要对wiki进行扩展,以建立用户注册、项目注册。 \r\n \r\nbrokendoor: 用户信息显示、项目信息显示、最近加入用户、项目等 \r\n \r\nbrokendoor: 项目注册后自动生成项目主页(可以使用预定模板) \r\n \r\n浆糊: 嗯。需要具体的user toary \r\n \r\nbrokendoor: 先大概说一下,今天标书定稿了我就有时间了 \r\n \r\n浆糊: 模般应该是可以自由修改。 \r\n \r\nbrokendoor: 模板包括单页面和多页模板。其实一样的 \r\n \r\n浆糊: 如果加入其它功能,例如工程。那么需要对wiki进行比较多的扩展 \r\n \r\nbrokendoor: 你说软件工程? \r\n \r\n浆糊: 还有就是你们讨论了代码集成的问题了没有。 \r\n \r\nbrokendoor: 暂时没有好办法 \r\n \r\n浆糊: 就是用wiki进行项目管理。 \r\n \r\n踏冰: 弄个 RUP,XP 摸板什么的就OK。 \r\n \r\nbrokendoor: 我们讨论了利用工作流支持项目管理流程 \r\n \r\n浆糊: 对! 模板要可定义。 \r\n \r\n浆糊: 不过这样好像和工作流有关吧。 \r\n \r\n踏冰: 我们的特色。(破门说的) \r\n \r\n踏冰: :) :) \r\n \r\nbrokendoor: 用户故事提出、评估、审核、拆分、编程、代码审核、验收、完成 \r\n \r\nbrokendoor: 最后生成相关的自动统计。 \r\n \r\nbrokendoor: 所以wiki一定要有好的扩展接口,我觉得都类似code标记的扩展。 \r\n \r\n浆糊: 嗯。可定义的工作流应该可以 拼装成xp,rup ...等软件开发过程吧。 \r\n \r\nbrokendoor: 没问题的,有些东西可以做成工作流的扩展应用。 \r\n \r\n浆糊: wiki的这些我都考虑进去了。不过xp说,只对今天的需求进行设计,呵呵。。 \r\n \r\n浆糊: 工作流这个东西的开发量很大啊 \r\n \r\n浆糊: 踏冰死了,哈哈 ~~ \r\n \r\nbrokendoor: 比如我们昨天讨论了代码集成:假设我们有了这种工具,可以增加一个自动环节,让工 \r\n \r\nbrokendoor: 让工作流自动调用,确定是否能够进行下一步任务 \r\n \r\n浆糊: 嗯。好办法。 \r\n \r\n踏冰: 没死。 还活的好好的。 \r\n \r\nbrokendoor对浆糊说: 工作流没有想象中那么复杂的 \r\n \r\n踏冰: 这些东西,昨天我们讨论过的。 \r\n \r\n浆糊: 呵呵。。说你啊。要做工作流,工作很多阿。 \r\n \r\n踏冰: 我还是怕 coding. \r\n \r\nbrokendoor对浆糊说: 我在公司用了3个月就搞定了基本环境,大部分是我用vb写的代码 \r\n \r\nbrokendoor对踏冰说: 我也很怕啊。 \r\n \r\n踏冰对brokendoor说: 那就让 浆糊 coding 吧 :) \r\n \r\n踏冰对浆糊说: 怎么样。呵。 \r\n \r\n踏冰对浆糊说: 不会推辞吧。呵呵。 \r\n \r\nbrokendoor: 还算了测试、稳定的时间 \r\n \r\n浆糊: 靠,~~。这算不算欺负我啊,呵呵。。 \r\n \r\n踏冰对brokendoor说: 如果 我们 简单化 流程 转移条件,就会更快。 \r\n \r\nbrokendoor对浆糊说: 你找的那个家伙呢? \r\n \r\nbrokendoor对踏冰说: 是的,其实可以先不做,让用户自己决定 \r\n \r\n踏冰对brokendoor说: 呵。顺便做了吧。 \r\n \r\nbrokendoor: 以后再重构 \r\n \r\n浆糊: 你说的基本环境是说已可以实现基本功能? \r\n \r\nbrokendoor对浆糊说: 说一下重构的感觉 \r\n\r\n踏冰: 对,你们的工作流运行环境是什么??? \r\n \r\nbrokendoor对踏冰说: ASP/IIS/COM/Oracle \r\n \r\n浆糊: 简直就是一个字:酷~ \r\n \r\n踏冰对浆糊说: 怎么酷的。 \r\n \r\n踏冰对brokendoor说: 哦。。 \r\n \r\n浆糊: 先设计,再编码。很帅的。一下子接口就出来了。 \r\n \r\n浆糊: 不是设计,是测试。 \r\n \r\nbrokendoor对浆糊说: 我可以想象一下,用UnitTest保证功能 \r\n \r\nbrokendoor对浆糊说: 然后,完成一块就是一块 \r\n \r\nbrokendoor对浆糊说: 然后,就完成了 \r\n \r\n浆糊: 恩,是的。 速度也很快。 \r\n \r\n踏冰对brokendoor说: 继续刚才我们说的吧。 \r\n \r\n踏冰对brokendoor说: 用户登录后 的 任务列表。 \r\n \r\nbrokendoor对踏冰说: 好的,今天说到流程处理界面 \r\n \r\n浆糊: 工作流包括哪些实质的东西? \r\n \r\nbrokendoor对踏冰说: 任务列表划分为 待办、在办、已办、暂停等状态 \r\n \r\nbrokendoor对浆糊说: 一个流程定义工具 \r\n \r\n踏冰对brokendoor说: 够了 \r\n \r\nbrokendoor对浆糊说: 流程自动化运行环境 \r\n \r\n浆糊: 我说的那个家伙好像把diff搞定了。不过他也是初学者。 \r\n \r\nbrokendoor对浆糊说: 流程处理统一界面 \r\n \r\nbrokendoor对浆糊说: 最后是流程跟踪监控和统计分析 \r\n \r\n踏冰对浆糊说: DIFF是什么? \r\n \r\n浆糊: wiki的diff功能 \r\n \r\n踏冰对浆糊说: 具体点。 \r\n \r\nbrokendoor对踏冰说: 对比两个版本 \r\n \r\n踏冰对brokendoor说: 对比什么两个版本??? \r\n \r\nbrokendoor对踏冰说: wiki文章 \r\n \r\n踏冰对brokendoor说: 哦。 \r\n \r\n浆糊: 工作流的开发工作什么时候开始? \r\n \r\n踏冰对浆糊说: 这不都开始了吗。 \r\n \r\n踏冰对浆糊说: 呵呵。 \r\n \r\n踏冰: 任务列表 的信息是够了。。 \r\n \r\nbrokendoor对浆糊说: 关键问题:code标记的处理如何? \r\n \r\n浆糊: 我说的具体story出来后,是不是马上开始开发?谁开发? \r\n \r\nbrokendoor对浆糊说: 踏冰没时间的话,可能是我来 \r\n \r\n浆糊: 我对code标记单独用了一个CodeParse implements TagParser \r\n \r\nbrokendoor对浆糊说: 可以了么? \r\n \r\n踏冰对浆糊说: 扩展什么时候搞定? \r\n \r\n浆糊: 没有重构,不过测试写好了。没有问题的。 \r\n \r\nbrokendoor对踏冰说: 如果code搞定了,就算搞定了 \r\n \r\n浆糊: 这个星期吧。 \r\n \r\n踏冰对brokendoor说: 那工作流我和 浆糊就应该OK。 \r\n \r\nbrokendoor: 好了,继续 \r\n \r\nbrokendoor: 待办列表需不需要签收? \r\n \r\n踏冰对brokendoor说: 需要, \r\n \r\n浆糊: 靠~又让我编代码阿,呵呵。。踏冰 \r\n \r\n踏冰对brokendoor说: 就一个 电子签名的问题 \r\n \r\nbrokendoor: 我觉得手工签收是必要的 \r\n \r\n踏冰对浆糊说: 怎么会呢,呵,我也要 CODING。 \r\n \r\n浆糊: 恩。是的。签收一定要的。 \r\n \r\nbrokendoor: 然后就转到在办,并自动打开对应的wiki页 \r\n \r\n浆糊: 哦,那就好。我们也试试pair呵呵。。 \r\n \r\n踏冰: 电子签名 我已经OK了。 \r\n \r\n踏冰: 电子签名实现的操作如下:你们看够不够。 \r\n \r\n踏冰: 1、待阅 ----》》》 已阅 。 \r\n \r\n踏冰: 2、登记其 签名时间, \r\n \r\n踏冰: 3、 记录其 批示。 \r\n \r\nbrokendoor: 如果,对wiki页不想做过多的扩展的话。是不是让流程操作全部在待办列表中处理? \r\n \r\n浆糊: 打断一下,关于代码的问题:编码风格好统一 \r\n \r\n踏冰对浆糊说: 到时候发给你,不就得了。 \r\n \r\n踏冰对浆糊说: 你一修改就OK 了。呵:) \r\n \r\n浆糊: 重复劳动。 \r\n \r\nbrokendoor对踏冰说: 还是统一吧,浆糊你的新约定呢? \r\n \r\n浆糊: 没做好呢。这个星期完成那个之后,下个星期写出来。 \r\n \r\n踏冰对浆糊说: 因为 电子签名 我已经OK了,呵,发给你你去统一如何。 \r\n \r\n浆糊: 等我的部分也完成吧。 \r\n \r\n浆糊: 继续工作流 \r\n \r\nbrokendoor对浆糊说: 最好早点出来 \r\n \r\n浆糊: 好 \r\n \r\nbrokendoor对浆糊说: 如果对wiki页不想做过多的扩展的话。是不是让流程操作全部在待办列表中处理? \r\n踏冰对brokendoor说: 你说具体点? \r\n \r\nbrokendoor: 我觉得可能会不方便,但是如果在wiki页中加入流程操作的话会很麻烦。 \r\n \r\n踏冰对brokendoor说: 我想不应该麻烦啊。 \r\n \r\nbrokendoor: 一般流程操作指的是,签收、转发等 \r\n \r\n浆糊: 我的看法。让wiki尽量的简单一点,不要太依靠它。它因该作为一个信息发布 \r\n \r\n踏冰对浆糊说: 老熊很喜欢 WIKI 的。呵。 \r\n \r\nbrokendoor: 没问题的,浆糊你能不能让wiki的接口程序访问文章的信息? \r\n \r\nbrokendoor对踏冰说: 嗯,我喜欢简单明快的东西 \r\n\r\n浆糊: 文章信息是什么意思? \r\n \r\n踏冰对浆糊说: 那我们就多用 WIKI 。 \r\n \r\n踏冰对浆糊说: 全部往 上 靠。。。不过就要麻烦你老兄了。 \r\n \r\nbrokendoor对浆糊说: 比如,存储在文章里的标题、编号等 \r\n \r\n浆糊: 那个人来了,要不要叫他来。 \r\n \r\nbrokendoor对浆糊说: 好啊 \r\n \r\n踏冰: 在引入 标签。 \r\n \r\nbrokendoor对踏冰说: 不会麻烦他的,只要他定义好扩展接口。我们按约定实现功能就行了。 \r\n \r\n踏冰: 用户在输入文章时,在文章 正文内使用此标签表示 关键词。 \r\n \r\n踏冰: 这样就能加快检索了。 \r\n \r\n浆糊: 嗯。可以地,写一个story给我 \r\n \r\n踏冰对浆糊说: 你说什么可以 \r\n \r\n踏冰对brokendoor说: 把会议记录弄好啊。呵:) \r\n \r\n浆糊: 比如,存储在文章里的标题、编号等 \r\n \r\nbrokendoor对踏冰说: 我曾经和浆糊讨论过一个话题,关于流程环境和使用流程业务的关联性。 \r\n \r\n浆糊: 我开会了。走了。 \r\n \r\nbrokendoor对浆糊说: bye \r\n \r\n踏冰对浆糊说: 8 \r\n \r\n踏冰: 你们都有会开,都在上班,我学生,放假了。有时间。 \r\n \r\nbrokendoor对踏冰说: 你在你的文件流传中如何处理的? \r\n \r\nbrokendoor对踏冰说: 也就是文件如何跟流程关联? \r\n \r\n踏冰: 就是 过程定义库 与 业务库 的关系。 \r\n \r\nbrokendoor对踏冰说: 是过程记录库吧 \r\n \r\n聪明鸽子: Ok \r\n \r\nbrokendoor对聪明鸽子说: 你好 \r\n \r\n聪明鸽子: 你们好。 \r\n \r\n踏冰: 你是不是想问我,是如何推进流程 ? \r\n \r\n踏冰: 在 文件流传中,如何控制流程。 \r\n \r\n聪明鸽子: 都是 前辈啊。 :) \r\n \r\nbrokendoor对聪明鸽子说: 不是,是如何从一份文件找到与文件对应的流程。 \r\n\r\nbrokendoor对聪明鸽子说: 你先看看,我们在讨论工作流程的处理。 \r\n \r\n踏冰对brokendoor说: 用户在发送文件时,要指定流程的。 \r\n \r\n聪明鸽子对brokendoor说: 好的。 \r\n \r\nbrokendoor对踏冰说: 嗯,这个流程和文件的关联方式是什么? \r\n \r\n踏冰对brokendoor说: 其流程索引 保存在 文件基本信息表的 一个字段中。 \r\n \r\nbrokendoor对踏冰说: 流程id \r\n \r\n聪明鸽子对浆糊说: 我把代码 给你 \r\n \r\n踏冰对brokendoor说: 恩,流程ID。 \r\n \r\nbrokendoor对聪明鸽子说: 浆糊开会去了 \r\n\r\nbrokendoor对聪明鸽子说: 你发到 webpm@topica.com 吧 \r\n \r\n聪明鸽子: 好的。 \r\n \r\nbrokendoor对踏冰说: 流程的状态和流转记录呢? \r\n \r\n聪明鸽子: 我是 新手。我给 浆糊 我的情况介绍了…… \r\n \r\n踏冰对brokendoor说: 流程的信息,运行情况 保存流程状态表。 \r\n \r\nbrokendoor对踏冰说: 是qzhl? \r\n \r\n聪明鸽子: 是的。 我是 qzhl \r\n \r\n踏冰对brokendoor说: 用外键来索引。 \r\n \r\nbrokendoor对踏冰说: 流程状态如何与文件关联? \r\n \r\nbrokendoor对踏冰说: 把文件id也存入状态表么? \r\n \r\n踏冰对brokendoor说: 流程实例化的 ID号,在文件基本信息表中记录。 \r\n \r\n踏冰对brokendoor说: 这样就 OK了。 \r\n \r\nbrokendoor对踏冰说: 不错 \r\n \r\n聪明鸽子: 我再 看一下哪个代码,然后发到:webpm@topica.com 。 \r\n \r\nbrokendoor对聪明鸽子说: 好的 \r\n \r\n踏冰对聪明鸽子说: 你是搞什么的。呵? \r\n \r\n聪明鸽子: 在 softme.org 上有 我的大概介绍。 \r\n \r\n踏冰对brokendoor说: 这部分结构还可以,更合理一些的。 \r\n \r\nbrokendoor对踏冰说: 待办列表其实是流程任务的实例化信息列表。 \r\n \r\n聪明鸽子: 我以前主要做 asp 现在刚刚 学习 java \r\n \r\nbrokendoor对踏冰说: 按照wfmc的定义,应该是实例化后分配了用户的任务信息列表 \r\n \r\n踏冰对brokendoor说: 我想代办列表,应该和 流程任务表分开吧, \r\n \r\nbrokendoor对踏冰说: 我设计了 ProcessInstance / ActivityInstance表 \r\n \r\n踏冰对brokendoor说: 应该是根据 任务表 来 生成 代办列表吧。 \r\n \r\nbrokendoor对踏冰说: 现在考虑要不要加 WorkItem 表 \r\n \r\n踏冰对brokendoor说: 你有ROSE吗? \r\n \r\n聪明鸽子: 改天再详细说。有事叫我。 \r\n \r\nbrokendoor对踏冰说: 没有 \r\n \r\n踏冰对聪明鸽子说: 聊聊啊。 \r\n \r\n踏冰对brokendoor说: 那惨。 \r\n \r\n踏冰对brokendoor说: 你要是有ROSE可以看一下我的 数据模型。 \r\n\r\n----\r\n破门去嘘嘘,删掉这段踏冰和鸽子的闲聊\r\n----\r\nbrokendoor对踏冰说: Rose 不是可以转成网页么? \r\n \r\n踏冰对brokendoor说: 好的。。等我 晚上发给你。 \r\n\r\n踏冰对brokendoor说: 要不现在给你。 \r\n \r\n踏冰对brokendoor说: 还是晚上吧,ROSE 太慢了。呵。 \r\n \r\n踏冰对brokendoor说: 你在干什么? \r\n \r\nbrokendoor对踏冰说: 刚接了电话,要改一点东西 \r\n \r\nbrokendoor对踏冰说: 我觉得流程环境我们的理解差不多,应该问题不大了。 \r\n \r\n踏冰对brokendoor说: 那你忙去吧,,,代办列表部分,应该不难。 \r\n \r\n踏冰对brokendoor说: 应该很容易搞定 :) \r\n \r\n聪明鸽子对踏冰说: 我 java 刚刚学 以后还请多多 帮助。 \r\n \r\n踏冰对聪明鸽子说: JAVA我不懂什么的。呵 :) \r\n \r\nbrokendoor对踏冰说: 我看第一件事是把用户注册加入到wiki系统。 \r\n \r\n聪明鸽子对踏冰说: 啊???不会把??? \r\n \r\n踏冰对聪明鸽子说: 你要去问 浆糊。 \r\n \r\n踏冰对brokendoor说: 加入 不难啊, \r\n \r\n踏冰对brokendoor说: 你认为有麻烦吗? \r\n \r\nbrokendoor对踏冰说: 没有说难,而是说这是第一件任务 \r\n \r\n踏冰对brokendoor说: 用户注册,要作为独立的 ,不要加里去。 \r\n \r\n踏冰对brokendoor说: 用户注册 已经 可以了。。 \r\n \r\nbrokendoor对踏冰说: 嗯,功能是独立的。但界面标记总是要加的 \r\n \r\nbrokendoor对踏冰说: 要不然怎么在主页显 \r\n \r\n踏冰对brokendoor说: 你是说在 WIKI 中 提供 用户 注册的页面???? \r\n \r\nbrokendoor对踏冰说: 难道不行? \r\n \r\n踏冰对brokendoor说: 主页要 WIKI 的? \r\n \r\nbrokendoor对踏冰说: 很简单的 \r\n \r\n踏冰对brokendoor说: 可以的。。 \r\n \r\nbrokendoor对踏冰说: 昨天不是讨论了半天么 \r\n \r\n踏冰对brokendoor说: 不过我想,在 WIKI页中加一个 用户注册的连接 不是更好吗? \r\n \r\nbrokendoor对踏冰说: 嗯,也没问题 \r\n \r\n踏冰对brokendoor说: 呵 :) \r\n \r\n踏冰对brokendoor说: 你忙去吧。 \r\n \r\n踏冰对聪明鸽子说: 呵。 \r\n\r\n----\r\n分类: [WebPM] | [WebPM 小组会议] ','BrokenDoor','2002-02-05 17:57:56','2002-02-05 17:57:56',0,'61.141.204.2',124),('2002年1月21日 会议记录','----\r\n说明:一起去听海 就是大家都爱的 踏冰 (别吐,要吐去厕所)\r\n----\r\n★欢迎您来到『webpm』房间★ \r\n \r\n浆糊: 我想说,是不是brokendoor负责把wiki的内容建设起来, \r\n\r\n浆糊: 内容建设时间不用太多 \r\n \r\nbrokendoor: 没问题,查找都搞定了么? \r\n \r\n浆糊: 查找没有搞定 \r\n \r\n浆糊: 我的下个任务是开发 最近更新 查找 \r\n \r\n浆糊: 还有锁定 \r\n \r\n浆糊对一起去听海说: 我这里可以得。 \r\n \r\nbrokendoor: 嗯,我改过页面样式。能不能用ftp? \r\n\r\n浆糊对brokendoor说: 我对Linux不熟悉 \r\n \r\nbrokendoor对浆糊说: 反正你用一个方便的用户调试,建一个webpm用户作发布好了。 \r\n \r\n浆糊对brokendoor说: 好的。 \r\n \r\nbrokendoor对浆糊说: 数据库也建两个用户,一个用户发布,另外一个做调试。 \r\n \r\n浆糊对brokendoor说: 页面建设什么时候开始弄? \r\n \r\nbrokendoor对浆糊说: 你弄好用户,发给我,我就可以开始了。wiki作为webpm的下级目录吧。 \r\n \r\nbrokendoor: 下来就是project管理部分的整理了。把注册用户和项目登记连接上来。 \r\n \r\n浆糊对brokendoor说: 嗯? webpm/jwiki对不? \r\n\r\n一起去听海对brokendoor说: 好的。 \r\n \r\n浆糊对brokendoor说: 我估计jwiki的数据库结构还得变 \r\n \r\n一起去听海对brokendoor说: 用户注册那部分,用的是 SERVLET 可是编译不了,我的环境总是出错。 \r\n \r\n一起去听海对浆糊说: 能把库结构发给我一份吗? \r\n \r\n浆糊对一起去听海说: 我把我的代码给你。你试试我的数据库接口,怎么样? \r\n\r\n一起去听海对brokendoor说: 要不就先 简单的把功能实现了。用 JAVABEAN吧。 \r\n \r\n一起去听海对浆糊说: 好。 \r\n \r\nbrokendoor: 你们能够收到topica的邮件么? \r\n \r\n一起去听海对brokendoor说: 能。 \r\n \r\n一起去听海对brokendoor说: 你说,现在是不是只实现 注册功能就行。 \r\n \r\n一起去听海对brokendoor说: 不考虑用 SERVLET \r\n \r\n一起去听海对brokendoor说: 如果那样,我就用 BEAN 了。 \r\n \r\nbrokendoor对一起去听海说: 是的 \r\n \r\n一起去听海对brokendoor说: 我已经把程序发给 JAVANET了,不过他说,数据借口不一样。 \r\n \r\nbrokendoor对一起去听海说: 必须统一数据接口 \r\n\r\nbrokendoor对浆糊说: 我们要好好考虑如何结合wiki的功能,建立主页,用户注册页面和项目主页。 \r\n \r\n浆糊对一起去听海说: 代码有什么问题,和我说 \r\n \r\n一起去听海对浆糊说: 好。 \r\n \r\nbrokendoor对浆糊说: 可能要允许一些特殊的标记,比如 login, project \r\n \r\n一起去听海对brokendoor说: 新键 项目 要增加功能了? \r\n \r\n浆糊对brokendoor说: 嗯,是的。 \r\n \r\n浆糊对brokendoor说: 其实login作为一个关键字就可以了。 \r\n \r\nbrokendoor: 不是,主要是有一些webpm 内定的功能允许在wiki页面调用 \r\n \r\n浆糊对brokendoor说: 在线用户在哪里? \r\n \r\nbrokendoor: 很多东西,我们可以作为标准的页面,允许wiki页面嵌入或连接访问 \r\n \r\nbrokendoor: 可以先单独作了再说。用bean会不会比较好调用? \r\n \r\nbrokendoor: 大家想一下,怎么能结合的更好,更方便? \r\n \r\n一起去听海对brokendoor说: 如果保存 在线用户,就用 BEAN 吧。 \r\n \r\n浆糊对brokendoor说: brokendoor说的那个嵌入标准页面,没有问题。 \r\n \r\n一起去听海对brokendoor说: ANT 真的很好用吗? \r\n \r\n一起去听海对brokendoor说: 你做的??? \r\n\r\nbrokendoor: 哪有那么厉害,tomcat开发组的工具 \r\n \r\n一起去听海对浆糊说: 你的 数据接口,有没有说明? \r\n \r\nbrokendoor对一起去听海说: 好的,我希望项目信息部分可以快点出来。takaka 最近也不见了,所以靠你了 \r\n \r\nbrokendoor: ant 的最好的作用是可以自动完成build和发布工作 \r\n \r\n浆糊对brokendoor说: 暂时没有,不过很简单。 \r\n \r\nbrokendoor: 项目注册 \r\n \r\n浆糊对brokendoor说: 看看我的例子 \r\n \r\n一起去听海对浆糊说: 好的。 \r\n \r\n一起去听海对浆糊说: 我给你的接口,你改动多少??? \r\n \r\n浆糊: 几乎全部。 \r\n \r\n一起去听海对浆糊说: 呵。。。 \r\n \r\nbrokendoor: takaka写了一点代码,你收到么? \r\n \r\n一起去听海对brokendoor说: 没有。 \r\n \r\n浆糊: 收到了。但是也是接口不统一 \r\n \r\nbrokendoor: 可以简单点,就是id, name, status 就行了. \r\n \r\n浆糊: 数据库操作的部分 \r\n \r\nbrokendoor对浆糊说: 交给踏冰改吧,你负责wiki \r\n \r\n浆糊: 好的。wiki还有很多要做。公司的事情也是多的很,咳~~ \r\n \r\nbrokendoor对浆糊说: 我想踏冰负责项目部分,以后是任务管理(流转) \r\n \r\nbrokendoor对浆糊说: chat部分我另外找人做好了。 \r\n \r\n浆糊: 呵呵。。不是说你做阿 :) \r\n \r\n一起去听海对brokendoor说: 好的。。 \r\n \r\n浆糊: 好。 \r\n \r\n浆糊: 其实可以先分开做。然后整合。 \r\n \r\n一起去听海对brokendoor说: 数据库操作部分还需要什么? \r\n \r\n浆糊: 只是在开发的过程中多想一些结合的方式 \r\n \r\n一起去听海对浆糊说: : 数据库操作部分还需要什么? \r\n \r\n浆糊: 你看了我的接口了吗、? \r\n \r\n一起去听海对浆糊说: 没呢? \r\n \r\n一起去听海对浆糊说: 等看了再找你。 \r\n \r\n浆糊: 其实数据库操作没有什么太多要做的 \r\n \r\n一起去听海对浆糊说: 就是。1.login 2.logout 3.select 4.update 够吗? \r\n \r\n浆糊: 我没有作这些。 \r\n \r\n一起去听海对浆糊说: 那你做什么了。 \r\n \r\n浆糊: 我只有一个 newConnection \r\n \r\n一起去听海对浆糊说: 哦。 \r\n \r\n浆糊: 其实那些操作封装起来也可以,不过没有太多的用处。 \r\n \r\n一起去听海对浆糊说: 呵 。。封起来还是方便一些 \r\n \r\n浆糊: 你看了我的那些类,我们再商量,我们不怕修改 \r\n \r\n一起去听海对浆糊说: 好的。。。XP 厉害。 \r\n \r\n浆糊: 呵呵。。。 \r\n \r\n一起去听海对浆糊说: 问 破门还有什么事。 \r\n \r\n浆糊: 你的项目什么时候能做出来? \r\n \r\nbrokendoor对浆糊说: 我同意你的观点,除了连接池必须封装,其他的问题不大。jdbc已经不错了 \r\n \r\n一起去听海对浆糊说: 你是说我的 文件流传吗? \r\n \r\n浆糊: 不是,是webpm的项目管理。 \r\n \r\n一起去听海对brokendoor说: 呵。。JDBC 的 ResultSet 接口 有点不方便啊。 \r\n \r\n一起去听海对浆糊说: 不知道 \r\n \r\n一起去听海对浆糊说: 注册先弄好。。 \r\n \r\n一起去听海对浆糊说: 然后开始那部分。 \r\n \r\n浆糊: 我这个星期把最新更新做上去,还有锁定。 \r\n \r\n浆糊: 注册什么时候? \r\n \r\nbrokendoor对浆糊说: 我们先弄好wiki,我可不希望在erptao讨论webpm,没劲 \r\n \r\n浆糊: 呵呵。。。是啊!!现在可以用了阿 :) \r\n \r\n一起去听海对浆糊说: 我今天下午要给老师干活,明天和他去交项目,明天晚上开始 弄。 \r\n \r\n浆糊: wiki的内容还是由破门来做。 \r\n \r\nbrokendoor对浆糊说: 没问题的。 \r\n\r\n一起去听海对浆糊说: 后天应该差不多。 \r\n \r\nbrokendoor对浆糊说: 那你要把数据库备份做好啊,不然有人捣乱的话,呵呵。:( \r\n \r\n浆糊: 好。 \r\n \r\n浆糊: 呵呵。。好的。就在我的机器上。erptao也没也出现这种可能 \r\n \r\n一起去听海对浆糊说: 你在你自己的机器上发布的吗? \r\n \r\n浆糊: 不是,数据库在我自己的机器上。 \r\n\r\nbrokendoor对浆糊说: 他们有人整过了,不过有备份恢复的 \r\n \r\n浆糊: 大家访问速度如何? \r\n \r\nbrokendoor对浆糊说: 不错 \r\n \r\n浆糊: 哦。 \r\n \r\n一起去听海对浆糊说: 很快。 \r\n \r\n浆糊: ok! \r\n \r\n一起去听海对浆糊说: 你的机器可以做 长期主机吗? \r\n \r\n浆糊: 你们谁做过mysql的备份? \r\n \r\n一起去听海对浆糊说: 第一次用MYSQL。 \r\n \r\n浆糊: 应该在一段时间内没有问题。 \r\n \r\n一起去听海对浆糊说: 好呵。。。你怎么不用 IIS+TOMCAT \r\n\r\n浆糊: use linux \r\n \r\n一起去听海对浆糊说: 哦。。 \r\n \r\n一起去听海对brokendoor说: linux 应该弄一下了???? \r\n \r\nbrokendoor对一起去听海说: 这个没问题的,用用就知道了。资料很多 \r\n \r\n一起去听海对brokendoor说: 哦。在 LINUX上有什么 WEB SERVER \r\n\r\nbrokendoor对浆糊说: 你把 jwiki/index.jsp 重定向到 \"jwiki.jsp?主页\" 吧. \r\n \r\n浆糊: 好的。没有问题。 \r\n \r\nbrokendoor对浆糊说: 我们的jwiki呵 \r\n\r\n一起去听海对brokendoor说: 格式规则》???????? \r\n \r\n一起去听海对brokendoor说: 没弄出来吗???????? \r\n \r\nbrokendoor对浆糊说: 没有 \r\n\r\nbrokendoor对浆糊说: 我明天会开始建内容。:) 下午要出差。 \r\n\r\nbrokendoor: 有问题,e-mail 联系吧。用 webpm@topica.com. \r\n \r\n浆糊: 大家还有问题吗? \r\n\r\nbrokendoor对浆糊说: 吃饭去了 \r\n \r\n---------\r\n分类: [WebPM] | [WebPM 小组会议]','BrokenDoor','2002-02-05 17:59:05','2002-02-05 17:59:05',0,'61.141.204.2',125),('工作流程管理简介','=======================================================================\r\n工作流程管理概论 版本 1.0 - WebPM - v1.0 - 2002-2-6 17:27:05\r\n=======================================================================\r\n\r\nCopyLeft (l) 2001 Softme Studio\r\n\r\nBrokenDoor brokendoor@sina.com\r\n\r\n1. 简介\r\n----\r\n1.1 工作流程(Workflow)管理的提出\r\n80年代随着文字处理、电子表格与其它桌面应用方案的推出及发展,个人生产效率因此而取得极大进展。此后,Lotus、Microsoft等发展商在激烈的市场竞争中,不断在其产品上推出新的功能,最终用户也确实在此种不间断的功能增进中获益,然而群体的协作效率并未因此而有明显的改善。\r\n\r\n上述现象在80年代后期引发了关于\"应再增加些什么,才能大大改善群体效率?\"的探讨。专家们的最终结论是:桌面应用系统对个人的生产效率确有突出的帮助,但对群体的生产效率并无明显的同比效益。在群体协同工作的环境下,需要依仗某种特定技术和方法对业务运作再工程化,由此而提出了工作流程的概念。\r\n\r\n1.2 工作流程的定义\r\n工作流程,英文用Workflow这个单词。简单理解就是 Work 用 Flow 串接起来,中文也就是工作流了。这些是字面的理解,如果要用一种准确的描述说明什么是工作流程?下面有几种解释:\r\n“工作流程是对一整套规则与过程的描述,以便管理在协同工作进程中的信息流通与业务活动。”——来自新世界数码基地(原集高科技)的产品JetFlo for Notes 的白皮书。这个定义明确了工作流程的目标不仅仅是处理过程,也不仅仅是把事物从一个地方流向另一个地方,而是管理那些引导作业环境如何运作的规则与过程。\r\n\r\n1991 年的Forrester Report中提出的定义则更能为大家接受,它将工作流程比喻为\"信息河流\"。该报告列出了评估一套工作流程软件是否合乎规格的3个关键因素:\r\n * \'\'\'流转路径的智能化\'\'\'\r\n * \'\'\'跟踪与监控信息的提供\'\'\'\r\n * \'\'\'与应用结合的能力\'\'\'\r\n\r\nWfMC (Workflow Management Coalition) 的规范中给出的定义则是:\r\n一种商务过程的全部或部分的自动化,在这些文档中,信息或者任务按照一套流转规则从一个参与者传递给另外一个进行处理。\r\n“The automation of a business process, in whole or part, during which documents,\r\ninformation or tasks are passed from one participant to another for action, according\r\nto a set of procedural rules.”\r\n\r\n2. 工作流程技术的分析\r\n----\r\n在实现工作流管理的过程中,往往存在以下的误解。\r\n\r\n2.1 电子邮件\r\n市场上存在着一种误解,以为电子邮件产品即能满足工作流程的需求。实际上,电子邮件仅可作为的一种信息的传输管道,其本身并非工作流程。下面是对电子邮件实现工作流的难点分析:\r\n* 有助于沟通,但是难于协同和协调\r\n电子邮件系统可以很方便地满足信息传递和交流的需求,但是由于邮件信息的不确定性,无法进行有效的协同管理。\r\n* 只利于处理突发和随机的事件\r\n如果是处理一整套规则的过程,电子邮件会有大量的重复操作。并且信息的传递在某种程度上会带来混乱。\r\n* 先天缺乏运营规则和过程的机制\r\n邮件系统在设计上就让信息只能采用直接发送的方式,信息的传递依赖于发送人的选择,而没有办法直接应用过程的管理规则。\r\n\r\n* 无法有效跟踪和监控流程\r\n私人邮箱的安全机制使得系统无妨有效的跟踪信息或者任务的状态。收到信息的人是否及时地执行了需要的处理无法跟踪和监控。\r\n\r\n2.2 WWW \r\n全球网的普及使得大家认为这个东西可能是万能钥匙。但是,全球网的机制本身也难于胜任工作流管理的要求:\r\n* 有助于沟通和协同, 但是难于协调\r\n* 无法直接建立流程自动化所需的“PUSH”模式\r\n* 无法有效跟踪和监控流程\r\n\r\n2.4 E-Form 和 EDMS 软件\r\n市场上很早就出现了电子表单管理和电子文档管理软件,这些软件用于工作流程管理还有什么缺陷呢?\r\n* 有助于沟通和协同, 但是难于协调\r\n* 需要大量编程以体现运行规则和过程\r\n* 缺乏有效跟踪和监控流程的机制\r\n\r\n2.5 群件系统\r\nLotus Notes的出现改变了群组协作的工作方式,群件系统这一广阔的应用天地使得微软也不惜巨资打造\r\nExchange 系统来抢占系统份额。那么用群件系统实现工作流管理有如何呢?\r\n* 应该看到群件系统是从邮件系统发展而来\r\nNotes 和 Exchage 系统的前期目标都是实现企业级电子邮件系统,目前他们最广泛的应用仍然是架构邮件系统。在系统的底层过多地依赖于邮件系统,则受到邮件系统缺陷的限制。\r\n* 文档型数据库的效率不能满足流程系统的需要\r\n群件系统数据库为了支持复合文档作出了巨大的牺牲,而工作流程对于关系数据的严谨性和状态控制的需要都使得群件系统在实现流程控制上具有先天的不足。\r\n* 需要大量编程以体现运行规则和过程\r\n即便是群件系统提供了群组通讯录管理等方便地功能以及某种程度上的工作流环境,但是无论是实现机制和功能都远远不能满足工作流管理的需要。需要通过大量的编程来弥补这个不足。\r\n\r\n\r\n(待续)\r\n. 相关资源\r\n----\r\n [WfMC] http://www.wfmc.org\r\n Jetflo for Notes 白皮书 \r\n Softme Studio(WebPM) http://softme.org\r\n\r\n======================== End Of File ==================================','202.105.103.52','2002-02-06 18:26:15','2002-02-06 18:26:15',0,'202.105.103.52',132),('testtopic','aaa\r\n[no]\r\nffddddddddfsdfsdf[]\r\n\r\n[ssssssss][aaaaaaaaa]\r\n[/no]\r\nddd\r\nTTTTTTTTTTTTTTT[no]sdfsdfds[sdfsd][/no]\r\n[no]test1\r\n[/no]\r\n[no]\r\ntest2[/no]\r\n[no]test23[/no]\r\n[code]sfdf\r\n[/code]\r\n','testauthor','2002-02-06 09:55:39','2002-02-06 09:55:39',0,'127.0.0.1',126),('2002年2月6日 会议纪要','=======================================================================\r\nWebPM - v1.0 - 会议纪要 - 2002-2-6 2:04\r\n=======================================================================\r\n\r\nCopyLeft (l) 2001 Softme Studio\r\n\r\n熊刚 Boon Xiong \r\n(brokendoor) brokendoor@sina.com\r\n=======================================================================\r\n\r\n1. 说明\r\n----\r\n主题: WebPM v1.0 Java版 第一阶段发布计划\r\n时间: 2002-2-5 上午 9:40 - 10:40\r\n参加人员: 全体WebPM开发小组成员\r\n实到人员: 浆糊,踏冰,brokendoor\r\n\r\n2. 实际讨论的主题\r\n----\r\n2.1 关于项目计划 {注1}\r\n由于项目人员力量分散,同时启动的子项目和任务过多,会影响到项目进度,因此\r\n我们要集中力量,一个个突破!鉴于除开 [webpm_wiki] 子项目以外的其他子项目实\r\n际上处于暂停的现状,WebPM小组决定正式暂停其他子项目的开发。本次计划的主题\r\n内容将集中在 [webpm_wiki] 子项目。\r\n\r\n2.2 关于Wiki的现阶段故事\r\n主要确定以下几个故事: {注2}\r\n1、多语言支持\r\n2、用户注册\r\n3、code 标记的扩展支持\r\n4、wiki 文章保存前的预览\r\n5、wiki 文章保存冲突的保护\r\n6、wiki 页面的皮肤支持\r\n7、最近浏览页面统计\r\n8、页面点击数统计\r\n\r\n2.3 第二阶段的分工和时间计划\r\n[code]\r\nbrokendoor: 文章预览 时间点 0.5 估计完成时间: 2001年2月8日\r\n 整合用户注册 时间点 0.5 估计完成时间: 2001年2月8日\r\n 编辑保护 时间点 0.5 估计完成时间: 2001年2月8日\r\n 页面皮肤 时间点 3 估计完成时间: 2001年2月18日\r\n 最近浏览页面 时间点 1 估计完成时间: 2001年2月18日\r\n 页面点击数 时间点 1 估计完成时间: 2001年2月18日\r\n\r\n踏冰: 用户注册修改 时间点 0.5 估计完成时间: 2002年2月8日\r\n\r\n浆糊: 多语言支持 时间点 1 估计完成时间: 2001年2月8日\r\n code标记 时间点 3 估计完成时间: 2001年2月9日\r\n[/code]\r\n3. 备注\r\n----\r\n{注1} 请参阅 [2002年2月6日 会议记录]\r\n{注2} 请参阅 [webpm_wiki.用户故事.第二阶段]\r\n\r\n----\r\n分类: [WebPM] | [WebPM 小组会议] ','202.105.102.62','2002-02-06 03:42:12','2002-02-06 03:42:12',0,'202.105.102.62',127),('webpm_wiki.用户故事.第二阶段','webpm_wiki.用户故事.第二阶段\r\n----\r\n1、多语言支持\r\nWiki页面中没有使用数据库存储的信息需要支持不同的语言,支持动态切换或者配置文件定义切换。\r\n\r\n2、用户注册\r\n允许用户自己注册个人帐号,并使用帐号名发表或者修改文章。要求记录文章的作者和最近修改者。\r\n\r\n3、code 标记的扩展支持\r\ncode标记支持用户输入的各种代码,并保留代码的缩进格式。允许使用[code=\'\'langauge\'\']...[/code]的格式设置代码属性,代码内容不进行wiki标记自动转换。可以根据\'\'langauge\'\'的设置进行相应的语法加亮显示。可以通过配置文件设置默认的\'\'language\'\'代码类型。\r\n\r\n4、wiki 文章保存前的预览\r\n在保存wiki文章前,允许用户设置进入预览模式,预览文章经过wiki标记转换后的格式和内容,再次提交后才真正保存到数据库。\r\n\r\n5、wiki 文章保存冲突的保护\r\n在两个用户同时修改同一篇wiki文章的时候提供编辑冲突保护,提示用户手工修订冲突。\r\n\r\n6、wiki 页面的皮肤支持\r\n允许通过配置文件设定wiki正文区使用的样式,以及标题区、导航区、页脚区的内容和样式。\r\n\r\n7、最近浏览页面统计\r\n对最近浏览的页面进行统计,按照时间顺序逆序排列最近被浏览过的20篇文章。\r\n\r\n8、页面点击数统计\r\n对所有wiki文章进行点击计数统计,按照点击数逆序排列最受欢迎的20篇文章。\r\n\r\n----\r\n分类: [WebPM] | [webpm_wiki]','202.105.102.62','2002-02-06 03:42:41','2002-02-06 03:42:41',0,'202.105.102.62',128),('licence','webpm使用[GNU通用公共许可证(GPL)]发布。\r\n\r\n----\r\n为什么使用GPL,而不是用LGPL?\r\n----\r\n\r\n----\r\nGPL和LGPL的区别是什么?告诉偶,呵呵\r\n----\r\n分类:[WebPM] | [webpm_wiki]\r\n','202.105.101.159','2002-02-22 00:42:03','2002-02-27 09:37:20',0,'ymruan',129),('我们还需要哪些新的群件应用?','\'\'\'我们还需要哪些新的群件应用?\'\'\'\r\n\r\n\'\'上海交通大学 丁军\'\'\r\n \r\n  计算机网络技术的发展使人们可以突破时空限制,通过计算机更自由、更有效地交换观点,协调工作。互联网的出现代表着计算机开始渗透入普通人的生活,标志着人类进入信息时代。它具有不同于以往任何技术的特征,它的对象是人类自身信息的共享和交流。理论上它可以构建一个人类共有的信息库,而且信息不会因复制和传播而消亡。它有可能会改变人们思考和生活的方式,甚至可能会改变整个人类进化的模式。其中,计算机协作技术(CSCW)和群件技术(GW)将扮演十分重要的角色。我很赞赏有一种群件的定义:一个共同进化的人类工具系统。然而现实和理想的差距还很大:个人能使用的带宽还很窄,信息的交流还远不是双向的,还不存在一种机制帮助个人通过互联网进化他的知识系统,并将他个人的创新加入到人类知识库中去。技术的发展正是由需求支撑和驱动的。基础层面上,面向多点,多速率,多媒体的宽带服务得到了很大的关注,但是它的发展受到资金缺乏的约束。应用层面上,各种应用系统得到开发,最终要达到无论何时何地都能交流信息的理想。可是,人力资源和资金都是有限的,对哪一种技术的投入符合我们的实际而又有最广阔的应用前景?我们还需要哪些新的群件应用?显然基于互联网的应用最有可能获得优先发展权,得到最广泛的支持。但在现在的种种应用中,哪方面有最大的潜力呢?新的群件应用的硬件基础不能脱离现在的互联网连接带宽太远,过于超前将使它不能得到迅速推广。新的群件应用应具有很大的通用性,应面向现在的数千万网民,使他们可以迅速成为它的庞大的用户群。我认为互联网上的新的群件应用最有可能出现在如何促进有效地进行双向信息交流方面。回顾互联网上的典型应用的发展,可以让我们得到启迪。\r\n  互联网上最有影响力的第一代应用应算是WEB浏览器的出现。借助超文本语言和图形界面,浏览器的出现迅速推广了WEB应用。我们现在已十分习惯于NETSCAPE NAVIGATOR的导航,尽管要常常迷路;习惯于INTERNET EXPLORE的探索,尽管所得往往并非所求。总之,浏览器的出现应算作WEB应用的第一次飞跃。\r\n  WEB上的第二代应用首推YAHOO等搜索引擎。无数的网页和网址需要便于归类查找,便利的搜索引擎便成了上网者的起始页。YAHOO的成功还因为它充分考虑了当时计算机的连接速度很低,其页面以文本为主实现,减少了本身传输的数据量。YAHOO 现在每月已有了几千万人次的访问率。但是这个现象并未引起国内技术人士的充分注意,第一个专业中文搜索引擎SOHOO迟至年初才由张朝阳博士的爱特信公司推出,并迅速成为国内最热门的网站。SOHOO实际沿用了YAHOO的思路并有所改进,它的起家资本也不过是22万美圆,但它切入了一个很有前途的领域因而迅速得以壮大,INTEL已向爱特信追加了200万美圆的投资。这从另一个侧面说明,在CYBER空间里眼光是多么重要。\r\n  但是,这个领域的竞争还只是刚刚开始,谁能坐上头把交椅就看他能不能创新。是否能有效地促进双向信息交流应是一个衡量准则。YAHOO导航的还仅是网址,网址上究竟有哪些内容还只有过于简单的介绍。哪些恰是查询者想要的?哪些仅是些商业广告?这里我们看到一个巨大的反差:一方面所有的信息都可以数字化上网,另一方面,非网络高手而不能迅速找到其需要的信息。早就有信息爆炸之说,信息太多了人们无所侍从。但实际上不是信息太多了,而是信息太少了:所想要的特定信息被淹没在信息海洋中。设想一下极端情况,假若每条信息都为等概出现,恐怕一生一世都不会等到所想要的信息。我想这大概就是网络焦虑症出现的原因吧。这在当今惜时如金的时代真是一个怪圈。因此,只能把我们所处的时代称为前信息时代,这是我们的悲哀,也是我们的机遇。这一切都能够改变,如果我们有信息代理。这里的信息代理有两层意思。第一,它代理你去查询信息;第二,它代理你去发表信息。前者指当面对查询时不仅定位到某个具体网址,而且定位到那个网址上所想要的具体内容上,如文本,图片,音频或视频。就是说,代理方有一个详细的多媒体分类数据库的索引,信息源则依旧分布在互联网上。这个索引必须是能够自动搜寻,动态刷新。后者象一个巨大的分类公告板,QUESTION和ANSWER的作者则是任何想发言的人,但是又必须有别于一般的BBS站,其难点是如何将信息过滤和储存,这些都是通过信息代理来完成。它架设了一座从此岸到达彼岸的桥梁,从技术上来说这是可以办得到的;它将会是下列技术的综合:多媒体数据库技术,如何检索,如何统计归类;地址和目录信息的综合技术;资源定位技术;公告板和协同写作技术;自动机器翻译;数字签名、用户标识等安全技术。\r\n  信息代理不仅仅是技术的综合,它的背后还意味着提供一种全新的信息服务。这要组织人力资源去提供这种服务。由此将衍生一系列的应用,开发者将得到巨大的回报。不过首先要发展其核心技术。有些已是有现成模式的适用技术,但是放到互联网上去,就是不同的挑战和机遇。这种新的群件应用最后会是什么样的,现在还很难说;但是以互联网为载体,去研究如何促进双向信息交流的可能性和有效性,是一个非常有意思的课题。也许,下一个全世界最著名的网点就在我们的眼前。我愿意和各位同仁一起去努力实现它。\r\n \r\n----\r\n分类:[工作流] | GroupWare\r\n','202.105.101.159','2002-02-06 04:41:57','2002-02-06 04:41:57',0,'202.105.101.159',130),('JWIKI最新公告','2002-10-3 21:1:42 [test1]\nddsfg\n----\n2002-8-29 14:3:55 [BrokenDoor]\r\n增加了简化标题标记:\r\n[no]==标题2==\r\n===标题3===[/no]\r\n----\r\n2002-8-26 22:52:20 [BrokenDoor]\r\n\'\'\'[color=red]开始JWiki v1.2.3版本开发[/color]\'\'\'\r\n已经完成了“评论”和“彩色标记”,有什么好建议请提出。\r\n----\r\n*2002/8/26 BrokenDoor\r\nCVS已经更新,请需要参加开发的人员与我联系获取CVS密码。\r\n mailto:brokendoor@sina.com \r\n----\r\n* 2002/08/20 BrokenDoor\r\n搞定了[JWiki v1.2.2]版本,请大家测试!\r\n----\r\n* \'\'\'文件上传功能已经开通,欢迎大家测试\'\'\' - BrokenDoor 2002/3/5\r\n----\r\n\'\'\'WebPM 开发组重要会议通知\r\n\r\n现阶段 WebPM 项目小组的开发工作主要集中在 JWiki 的开发上,事实上的开发人员只有 [浆糊] 和 BrokenDoor 两人。但是也取得了不少了成果,获得了更多的朋友们的关注。但是为了下一步项目开发能够更好地继续,WebPM 开发组决定于本周三(2002年2月27日)晚7:30于 \"QQ聊天室 => 自建六 => webpm\" 召开小组重要会议,邀请目前的WebPM 开发组成员,以及所有关注WebPM项目和希望加入WebPM项目的朋友参加。共同讨论下一步的开发战略以及开发组管理章程。\r\n希望能够在战略上以及组织和制度上保障WebPM项目开发的顺利进行!\r\n敬请大家留意!\r\n\r\nWebPM 开发小组\r\n2002年2月25日\'\'\'\r\n----\r\n几点钟开始?\r\n\'\'\'本周三(2002年2月27日)晚7:30于 \"QQ聊天室 => 自建六 => webpm\"\'\'\'\r\n----\r\njwiki已经支持[no][user][/no]标签,具体用法见[文件格式化规则] --2002/02/21[浆糊]\r\n\r\nwebpm_wiki1.1故事已经完成,webpm_wiki1.2 的故事已经发布,见[webpm_wiki] --[浆糊] 2002/02/20\r\n\r\n[cvs on cosoft|http://cosoft.org.cn/cvs/?group_id=17]已经更新为最新代码,请开发人员在进行工作前先checkout最新的代码。 -- 2002/2/14 BrokenDoor\r\n已经完成了修改预览的功能,用户注册结合比较麻烦,还要等 -- 2002/2/13 BrokenDoor\r\n----\r\n','浆糊','2002-02-21 23:48:29','2002-10-03 21:01:42',0,'test1',131),('notyy','好久不见了,你最近是不是失踪了阿?很高兴再次见到你。 -2002/02/06 浆糊\r\n----\r\nnotyy,好久不见了,最近有什么大作发表? 2002/02/06 [takaka]\r\n','浆糊','2002-02-06 23:27:03','2002-02-06 23:27:03',0,'202.103.233.73',133),('webPM开发成员相册','----\r\n大家把相片贴过来吧。:)(反正我脸大我先贴)\r\n----\r\n孤冰寒月 [踏冰]\r\n----\r\n[img]http://www.tabing.8u8.com/30005a.jpg[/img]\r\n----\r\n----\r\n[浆糊] \r\n----\r\n[img]http://www.16885.com/wader/image/han4.jpg[/img]\r\n----\r\n----\r\nBrokenDoor and his wife - 破门和破门的老婆\r\n----\r\n[img]/webpm/brokendoor/ourtwo.jpg[/img]\r\n----\r\n----\r\n[takaka] \r\n----\r\n[img]http://210.192.109.59:8080/webpm/doc/users/takaka/1.jpg[/img]\r\n----','61.167.164.5','2002-02-10 21:53:06','2002-03-06 17:01:07',0,'takaka',134),('设计模式','[Observer模式]\r\n\r\n[Singleton模式]\r\n\r\n[Command模式]\r\n\r\n[Bridge模式]\r\n\r\n[MVC模式]\r\n----\r\n参考资料:\r\n* [使用 Translator 模式构建更好的网站]\r\n* [与大虾对话 - 领悟设计模式] - 关于Template Method / Visitor 设计模式的介绍\r\n----\r\n参考站点:\r\n * Java 中的设计模式 http://61.144.28.245/hjc/web/doc/dp/dp.html\r\n----\r\n[主题分类]','浆糊','2002-02-09 21:56:03','2002-03-04 11:23:30',0,'BrokenDoor',135),('Observer模式','转:developerWorks 中国网站 \r\n\r\n软件模式的概念现在比较的广泛,涉及到分析,设计,体系结构,编码,测试,重构等软件构造生命期中的各个部分。这儿主要讨论的是设计模式,指的是在软件设计过程中反复出现的一些问题的解决方法了。不过我们一般在提到设计模式的时候,一般都是指GOF的经典书《Design Pattern--Elements of Reusable Object-Oriented Software》出现的23个模式,因而,它是具体的针对于面向对象软件设计过程的。\r\n\r\n从全局上看来,模式代表了一种语言,一种被文档化的经验,甚至是一种文化。往往很多不方便描叙,或者描叙起来很复杂的问题,用模式语言来叙说,会让听者产生心领神会的感觉。当然,这需要交流双方都能够很好地把握模式语言的含义。然而,这并不是一件容易的事情。模式在各个人的理解上往往存在差异,这篇文章旨在从一个具体的应用角度:Java类库,来阐叙设计模式。并结合具体的例子,希望能够加深大家对设计模式的理解。\r\n\r\n这儿说的Java类库,其实并没有局限于JDK本身,还包括了一些其他的类库中的例子,比如JAXP等(当然,下一个版本的JDK中也会包含JAXP了)。其实设计模式的思想现在应用的如此广泛,无论在什么样的设计中,只要稍微大一点的设计,都可以找到很多很多设计模式的踪迹,或者说都不可避免的用到设计模式。下面所讲的设计模式,大部分都是GOF的那部经典中出现过的23个模式,然而,还有一些,比如MVC,并不属于那里。一般的来讲,我们认为GOF的23个模式是一些中级的模式,在它下面还可以抽象出一些更为一般的低层的模式,在其上也可以通过组合来得到一些高级的模式。当然,这儿的低中高的区别,如同区别不同的语言一样,并没有优劣之分,仅仅是在应用层面上的区别。\r\n\r\nObserver模式 \r\nObserver模式的功用,是希望两个(或多个)对象,我们称之为Subject和Observer,当一方的状态发生改变的时候,另一方能够得到通知。也就是说,作为Observer的一方,能够监视到Subject的某个特定的状态变化,并为之做出反应。一个简单的例子就是:当一个用户视图中的数据被用户改变后,后端的数据库能够得到更新,而当数据库被其他方式更新后,用户视图中的数据显示也会随之改变\r\n[img]http://www-900.ibm.com/developerWorks/java/l-jdkdp/part1/fig1.gif[/img]\r\n在JDK中实际上有一个对Observer模式的简单的实现:就是类java.util.Observerable和接口java.util.Observer。java.util.Observerable类对应于Subject,而java.util.Observer就是观察者了。JDK中并没有把这两个部分都设计为接口,而是让类java.util.Observerable提供了部分的实现,简化了许多编程的工作。当然,这也减少了一定的灵活性。\r\n\r\n下面列出了Observer和Observeral的函数列表,及其简单的功能说明 \r\n\r\njava.util.Observer:\r\npublic void update(Observable obs, Object obj) \r\njava.util.Observer 接口很简单,只定义了这一个方法,狭义的按照Observer模式的说法,Observer应该在这个方法中调用Subject的getXXX()方法来取得最新的状态,而实际上,你可以只是在其中对Subject的某些事件进行响应。这便是Java中的代理事件模型的一个雏形--对事件进行响应。只不过,在Observer模式中将事件特定化为某个状态/数据的改变了。 \r\n\r\njava.util.Observable \r\n\r\npublic void addObserver(Observer obs) \r\n\r\n向Subject注册一个Observer。也就是把这个Observer对象添加到了一个java.util.Observable内部的列表中。在JDK中对于这个列表是简单的通过一个java.util.Vector类来实现的,而实际上,在一些复杂的Observer模式的应用中,需要把这个部分单另出来形成一个Manager类,来管理Subject和Observer之间的映射。这样,Subject和Observer进一步的被解藕,程序也会具有更大的灵活性。\r\n\r\npublic void deleteObserver(Observer obs) \r\n从Subject中删除一个已注册了Observer的引用。\r\n\r\npublic void deleteObservers() \r\n从Subjec中删除所有注册的Observer的引用。 \r\n\r\npublic int countObservers() \r\n返回注册在Subject中的Observer个数。\r\n\r\nprotected void setChanged() \r\n设置一个内部的标志以指明这个Ovserver的状态已经发生改变。注意这是一个protected方法,也就是说只能在Observer类和其子类中被调用,而在其它的类中是看不到这个方法的。\r\n\r\nprotected void clearChanged() \r\n清除上叙的内部标志。它在notifyObservers()方法内部被自动的调用,以指明Subject的状态的改变已经传递到Ovserver中了。\r\n\r\npublic boolean hasChanged() \r\n确定Subject的状态是否发生了改变。\r\n\r\npublic void notifyObservers(Object obj) \r\n它首先检查那个内部的标志,以判断状态是否改变,如果是的话,它会调用注册在Subject中的每个Observer的update()方法。在JDK中这个方法内部是作为synchronized来实现的,也就是如果发生多个线程同时争用一个java.util.Observerable的notifyObservers()方法的话,他们必须按调度的等待着顺序执行。在某些特殊的情况下,这会有一些潜在的问题:可能在等待的过程中,一个刚刚被加入的Observer会被遗漏没有被通知到,而一个刚刚被删除了的Observer会仍然收到它已经不想要了的通知。\r\n\r\npublic void notifyObservers() \r\n等价于调用了notifyObservers(null)。\r\n\r\n因而在Java中应用Observer就很简单了,需要做的是:让需要被观察的Subject对象继承java.util.Observerable,让需要观察的对象实现java.util.Observer接口,然后用java.util.Observerable的addObserver(Observer obj)方法把Observer注册到Subject对象中。这已经完成了大部分的工作了。然后调用java.util.Observerable的notifyObservers(Object arg)等方法,就可以实现Observer模式的机理。我们来看一个简单使用了这个模式的例子。这个例子有三个类:FrameSubject,DateSubject,FrameObject和EntryClass,FrameSubject中用户可以设置被观察的值,然后自动的会在FrameObject中显示出来,DateSubject封装被观察的值,并且充当Observer模式中的Subject。 \r\n[code]\r\npublic class FrameSubject extends JFrame {\r\n…………..\r\n //因为无法使用多重继承,这儿就只能使用对象组合的方式来引入一个\r\n//java.util.Observerable对象了。\r\n DateSubject subject=new DateSubject();\r\n\r\n //这个方法转发添加Observer消息到DateSubject。\r\n public void registerObserver(java.util.Observer o){\r\n subject.addObserver(o);\r\n }\r\n\r\n //数据改变,事件被触发后调用notifyObservers()来通知Observer。\r\nvoid jButton1_actionPerformed(ActionEvent e) {\r\n subject.setWidthInfo(Integer.parseInt(jTextField1.getText()));\r\n subject.setHeightInfo(Integer.parseInt(jTextField2.getText()));\r\n subject.notifyObservers();\r\n }\r\n……………\r\n}\r\n\r\npublic class DateSubject extends Observable {\r\n\r\n //封装被观察的数据\r\n private int widthInfo;\r\n private int heightInfo;\r\n\r\n public int getWidthInfo() {\r\n return widthInfo;\r\n }\r\n\r\n public void setWidthInfo(int widthInfo) {\r\nthis.widthInfo = widthInfo;\r\n//数据改变后,setChanged()必须被调用,否则notifyObservers()方法会不起作用\r\nthis.setChanged();\r\n }\r\n public void setHeightInfo(int heightInfo) {\r\n this.heightInfo = heightInfo;\r\n this.setChanged();\r\n }\r\n public int getHeightInfo() {\r\n return heightInfo;\r\n }\r\n}\r\n\r\npublic class FrameObserver extends JFrame implements java.util.Observer {\r\n…………..\r\n //观察的数据\r\n int widthInfo=0;\r\n int heightInfo=0;\r\n\r\n//在update()方法中实现对数据的更新和其它必要的反应。\r\n public void update(Observable o, Object arg) {\r\n DateSubject subject=(DateSubject) o;\r\n widthInfo=subject.getWidthInfo();\r\n heightInfo=subject.getHeightInfo();\r\n jLabel1.setText(\"The heightInfo from subject is: \");\r\n jLabel3.setText(String.valueOf(heightInfo));\r\n jLabel2.setText(\"The widthInfo from subject is: \");\r\n jLabel4.setText(String.valueOf(widthInfo));\r\n }\r\n…………….\r\n}\r\n\r\npublic class EntryClass {\r\n public static void main(String[] args) {\r\n ……………..\r\n FrameSubject frame = new FrameSubject();\r\nFrameObserver frame2=new FrameObserver();\r\n//在Subject中注册Observer,将两者联系在一起\r\nframe.registerObserver(frame2);\r\n…………..\r\nframe.setVisible(true);\r\nframe2.setVisible(true);\r\n\r\n ……………..\r\n }\r\n}\r\n[/code]\r\n我认为在JDK中这个Observer模式的实现,对于一般的Observer模式的应用,已经是非常的足够了的。但是一方面它用一个类来实现了Subject,另一方面它使用Vector来保存Subject对于Observer的引用,这虽然简化了编程的过程,但会限制它在一些需要更为灵活,复杂的设计中的应用,有时候(虽然这种情况不多),我们还不得不重新编写新的Subject对象和额外的Manager对象来实现更为复杂的Observer模式的应用。\r\n\r\n\r\n','浆糊','2002-02-07 01:36:47','2002-02-07 01:36:47',0,'192.168.1.228',136),('Singleton模式','Singleton模式要解决的是对象的唯一性问题。由Singleton模式创建的对象在整个的应用程序的范围内,只允许有一个对象的实例存在。这样的情况在Java程序设计的过程中其实并不少见,比如处理JDBC请求的连接池(Connection Pool),再比如一个全局的注册表(Register),等等,这都需要使用到Singleton,单件模式。\r\n\r\n在Java中,最简单的实现Singleton模式的方法是使用static修饰符,static可以用在内部类上,也可以用在方法和属性上,当一个类需要被创建成Singleton时,可以把它所有的成员都定义成static,然后再用final和private来修饰其构造函数,使其不能够被创建和重载。这在程序语法上保证了只会有一个对象实例被创建。比如java.util.Math就是这样的一个类。\r\n\r\n而Singleton模式所作的显然要比上面介绍的解决方法要复杂一些,也更为安全一些。它基本的思路也还是使用static变量,但是它用一个类来封装这个static变量,并拦截对象创建方法,保证只有一个对象实例被创建,这儿的关键在于使用一个private或者protected的构造函数,而且你必须提供这样的一个构造函数,否则编译器会自动的为你创建一个public的构造函数,这就达不到我们想要的目的了。\r\n[code]\r\npublic class Singleton {\r\n\r\n //保存唯一实例的static变量\r\n static private Singleton _instance = null;\r\n\r\n/*为了防止对象被创建,可以为构造函数加上private修饰符,但是这同样也防止了子类的对象被创建,因而,可以选用protected修饰符来替代private。*/\r\n protected Singleton() {\r\n // ...\r\n }\r\n\r\n //static方法用来创建/访问唯一的对象实例,这儿可以对对象的创建进行控制,使得可//以很容易的实现只允许指定个数的对象存在的泛化的Singleton模式。\r\n static public Singleton instance() {\r\n if(null == _instance) {\r\n _instance = new Singleton();\r\n }\r\n return _instance;\r\n }\r\n// ...\r\n}\r\n[/code]\r\n对象创建的方法,除了使用构造函数之外,还可以使用Object对象的clone()方法,因而在Singleton中也要注意这一点。如果Singleton类直接继承于Object,因为继承于Object的clone()方法仍保留有其protected修饰,因而不能够被其他外部类所调用,所以可以不用管它,但是如果Singleton继承于一个其他的类,而这个类又有重载clone()方法,这时就需要在Singleton中再重载clone()方法,并在其中抛出CloneNotSupportedException,这样就可以避免多个Singleton的实例被创建了。\r\n\r\n在JDK1.2以前的版本中使用Singleton模式的时候有一些需要额外注意的地方,因为Singleton类并没有被任何其他的对象所引用,所以这个类在创建后一段时间会被unload,Singleton类的静态方法就会出现问题,这是由于Java中垃圾收集机制造成的。解决的方法也很容易,只需要为其创建一个引用就行了。而在JDK1.2以后的版本中,Sun重新定义了Java规范,改正了其垃圾收集机制中的一些问题,这个问题也就不复存在了,这儿指出只是为了提起大家的主意。\r\n','浆糊','2002-02-07 09:55:29','2002-02-07 09:55:29',0,'192.168.1.228',137),('Command模式','在设计一般用途的软件的时候,在C或者C++语言中,用的很多的一个技巧就是回调函数(Callback),所谓的回调函数,意指先在系统的某个地方对函数进行注册,让系统知道这个函数的存在,然后在以后,当某个事件发生时,再调用这个函数对事件进行响应。在C或者C++中,实现的回调函数方法是使用函数指针。但是在Java中,并不支持指针,因而就有了Command模式,这一回调机制的面向对象版本。\r\n\r\nCommand模式用来封装一个命令/请求,简单的说,一个Command对象中包含了待执行的一个动作(语句)序列,以执行特定的任务。当然,并不是随便怎么样的语句序列都可以构成一个Command对象的,按照Command模式的设计,Command对象和它的调用者Incvoker之间应该具有接口约定的。也就是说,Invoker得到Command对象的引用,并调用其中定义好的方法,而当Command对象改变(或者是对象本身代码改变,或者干脆完全另外的一个Command对象)之后,Invoker中的代码可以不用更改。这样,通过封装请求,可以把任务和任务的实现加以分离。\r\n[img]http://www-900.ibm.com/developerWorks/java/l-jdkdp/part2/fig2.gif[/img]\r\n图二:Command模式的类图\r\n而对于请求的处理又有两种不同的方法,一种是Command只充当代理,将请求转发给某个接受者对象,还有一种是Command对象自己处理完所有的请求操作。当然,这只是两个极端,更多的情况是Command完成一部分的工作,而另外的一部分这则交给接受者对象来处理。\r\n\r\n在新的JDK的代理事件模型中,就可以看作是这样的一个Command模式。在那个模型中,一个事件监听者类EventListener监听某个事件,并根据接口定义,实现特定的操作。比如,当用Document对象的addDocumentListener(DocumentListener listener) 方法注册了一个DocumentListener后,以后如果在Document对象中发生文本插入的事件,DocumentListener中实现的insertUpdate(DocumentEvent e)方法就会被调用,如果发生文本删除事件,removeUpdate(DocumentEvent e)方法就会被调用。怎么样,想想看,这是不是一个Command模式的应用呢?\r\n\r\n然而,最经典的Command模式的应用,莫过于Swing中的Action接口。Action实际上继承的是ActionListener,也就是说,它也是一个事件监听者(EventListener)。但是Action作为一种ActionListener的扩展机制,提供了更多的功能。它可以在其中包含对这个Action动作的一个或者多个文字的或图标的描叙,它提供了Enable/Disable的功能许可性标志。并且,一个Action对象可以被多个Invoker,比如实现相同功能的按钮,菜单,快捷方式所共享。而这些Invoker都知道如何加入一个Action,并充分利用它所提供的扩展机制。可以说,在这儿Action更像一个对象了,因为它不仅仅提供了对方法的实现,更提供了对方法的描叙和控制。可以方便的描叙任何的事务,这更是面向对象方法的威力所在。\r\n\r\n下面我们看一个Command模式的应用的例子。假设要实现这样的一个任务:Task Schedule。也就是说,我想对多个任务进行安排,比如扫描磁盘,我希望它每1个小时进行一次,而备份数据,我希望它半个小时进行一次,等等等等。但是,我并不希望作为TaskSchedule的类知道各个任务的细节内容,TaskSchedule应该只是知道Task本身,而对具体的实现任务的细节并不理会。因而在这儿,我们就需要对TaskSchedule和Task进行解耦,将任务和具体的实现分离出来,这不正是Command模式的用武之地吗?\r\n[img]http://www-900.ibm.com/developerWorks/java/l-jdkdp/part2/fig3.gif[/img]\r\n图三:Command模式的应用例子\r\n程序清单: \r\n[code]\r\n//抽象的Task接口,作为回调的Command模式的主体\r\npublic interface Task {\r\n public void taskPerform();\r\n}\r\n\r\n//具体的实现了Task接口的子类,实现特定的操作。\r\npublic class BackupTask implements Task{\r\n public void taskPerform(){\r\n System.out.println(\"Backup Task has been performed\");\r\n }\r\n}\r\n\r\n//具体的实现了Task接口的子类,实现特定的操作。\r\npublic class ScanDiskTask implements Task{\r\n public void taskPerform(){\r\n System.out.println(\"ScanDisk Task has been performed\");\r\n }\r\n}\r\n\r\n//一个封装了Task的一个封装类,提供了一些与Task相关的内容,也可以把这些内容\r\n//这儿不过为了突出Command模式而把它单另出来,实际上可以和Task合并。\r\npublic class TaskEntry {\r\n private Task task;\r\n private long timeInterval;\r\n private long timeLastDone;\r\n public Task getTask() {\r\n return task;\r\n }\r\n public void setTask(Task task) {\r\n this.task = task;\r\n }\r\n public void setTimeInterval(long timeInterval) {\r\n this.timeInterval = timeInterval;\r\n }\r\n public long getTimeInterval() {\r\n return timeInterval;\r\n }\r\n public long getTimeLastDone() {\r\n return timeLastDone;\r\n }\r\n public void setTimeLastDone(long timeLastDone) {\r\n this.timeLastDone = timeLastDone;\r\n }\r\n\r\n public TaskEntry(Task task,long timeInteral){\r\n this.task=task;\r\n this.timeInterval =timeInteral;\r\n }\r\n\r\n}\r\n\r\n//调度管理Task的类,继承Thread只是为了调用其sleep()方法,\r\n//实际上,如果真的作Task调度的话,每个Task显然应该用单独的Thread来实现。\r\npublic class TaskSchedule extends java.lang.Thread {\r\n\r\n private java.util.Vector taskList=new java.util.Vector();\r\n private long sleeptime=10000000000l;//最短睡眠时间\r\n\r\n public void addTask(TaskEntry taskEntry){\r\n taskList.add(taskEntry);\r\n taskEntry.setTimeLastDone(System.currentTimeMillis());\r\n if (sleeptime>taskEntry.getTimeInterval()) \r\n sleeptime=taskEntry.getTimeInterval();\r\n }\r\n\r\n //执行任务调度\r\n public void schedulePermorm(){\r\n try{\r\n sleep(sleeptime);\r\n Enumeration e = taskList.elements();\r\n while (e.hasMoreElements()) {\r\n TaskEntry te = (TaskEntry) e.nextElement();\r\n if (te.getTimeInterval() + te.getTimeLastDone() < \r\n System.currentTimeMillis()) {\r\n te.getTask().taskPerform();\r\n te.setTimeLastDone(System.currentTimeMillis());\r\n }\r\n }\r\n }catch (Exception e1){\r\n e1.printStackTrace();\r\n }\r\n }\r\n\r\n public static void main (String args[]){\r\n TaskSchedule schedule=new TaskSchedule();\r\n TaskEntry taks1=new TaskEntry(new ScanDiskTask(),10000);\r\n TaskEntry taks2=new TaskEntry(new BackupTask(),3000);\r\n schedule.addTask(taks1);\r\n schedule.addTask(taks2);\r\n while (true){\r\n schedule.schedulePermorm();\r\n }\r\n }\r\n\r\n}\r\n\r\n[/code]\r\n程序本身其实没有多大的意义,因而,程序在编码的时候也只是用的最简单的方法来实现的,如果要做一个真正的TaskSchedule的话,这个程序除了结构上的,其它没有什么好值得参考的了。\r\n\r\n','浆糊','2002-02-07 09:59:18','2002-02-07 09:59:18',0,'192.168.1.228',138),('Bridge模式','当初Java刚刚推出来的时候,AWT可是一个比较热的话题,虽然现在有被Swing取代的趋势。但是我一直都觉得AWT也有其优势,至少它使用的本地代码就要比Swing快上许多,而且,可以为用户提供熟悉的本地操作系统界面。如果在Windows XP中运行基于AWT的程序的话,XP中绚烂多变的界面Theme可以轻易应用到AWT程序中,而Swing就不行了,因为AWT所调用的是本带代码,使用的是本地的窗体控件。当然,Swing也有其好处,不可一概而论。\r\n\r\n简单来讲,AWT提供对程序员的是对窗体界面系统的抽象,而在内部实现中,针对每一种操作系统,分别有不同实现,这就是同位体(Peer)的概念。当程序员调用AWT对象时,调用被转发到对象所对应的一个Peer上,在由Peer调用本地对象方法,完成对象的显示。例如,如果你使用AWT创建了一个Menu类的实例,那么在程序运行时会创建一个菜单同位体的实例,而由创建的同位体的来实际执行菜单的现实和管理。不同的系统,有不同的同位体实现,Solaris JDK将产生一个Motif菜单的同位体,Windows下的JDK将产生一个Windows的菜单的同位体,等等。同位体的使用,使得交叉平台窗口工具的开发变得极为迅速,因为同位体的使用可以避免重新实现本地窗口控件中已经包含的方法。\r\n[img]http://www-900.ibm.com/developerWorks/java/l-jdkdp/part3/fig1.gif[/img]\r\n图九:AWT中的组件和其对等体\r\n际上,从设计的角度来看,这是一个抽象和实现分离的过程--AWT是抽象,同位体是实现,抽象和实现各自成为一个对象体系,它们由一个桥连接起来,可以各自发展各自的对象层次,而不必顾虑另一方面。这就是Bridge模式所提供的思想。Bridge模式更可以提供在各个不同的实现中动态的进行切换,而不必从新编译程序。\r\n\r\n通常,Bridge模式和AbstractFactory模式一起工作,由AbstractFactory来创建一个具体实现的对象体系。特殊的,当只有一个实现的时候,可以将Implementor抽象类去掉。这样,在抽象和实现之间建立起了一一对应的关系,但这并不损害Bridge模式的内涵。这被称为退化了的Bridge模式。\r\n\r\n很多时候,Abstraction层次和Implementor层次之间的方法都不是一一对应的,也就是说,在Abstraction和Implementor之不是简单的的消息转发。通常,我们会将Abstraction作为一个抽象类(而不是接口)来实现。在Implementor层次中定义底层的,或者称之为原子方法,而在Abstraction层次中定义一些中高层的基于原子方法的抽象方法。这样,就能更为清晰的划分Abstraction和Implementor,类的结构也更为清晰。\r\n[img]http://www-900.ibm.com/developerWorks/java/l-jdkdp/part3/fig2.gif[/img]\r\n图十:Bridge模式对系统的划分\r\n面,我们来看一个Bridge模式的具体应用。考虑这样的一个问题,需要生成一份报告,但是报告的格式并没有确定,可能是HTML文件,也可能是纯ASCII文本。报告本身也可能分为很多种,财务报表,货物报表,等等问题很简单,用继承也较容易实现,因为相互之间的组合关系并不是很多。但是,我们现在需要用Bridge的观点来看问题。\r\n\r\n在Bridge模式中,使用一个Report类来描叙一个报告的抽象,用一个Reporter类来描叙Report的实现,它的子类有HTMLReporter和ASCIIReporter,用来分别实现HTML格式和ASCII格式的报告。在Report层次下面,有具体的一个StockListReport子类,用来表示货物清单报告。\r\n[code]\r\npublic abstract class Report\r\n{\r\n Reporter reporter;\r\n public Report(Reporter reporter) {\r\n this.reporter = reporter;\r\n}\r\n//抽象类使用桥接对象的方法来实现一个任务\r\n public void addReportItem(Object item){\r\n reporter.addLine(item.toString());\r\n }\r\n public void addReportItems(List items){\r\n Iterator iterator = items.iterator();\r\n while ( iterator.hasNext() )\r\n {\r\n reporter.addLine(iterator.next().toString());\r\n }\r\n }\r\n public String report(){\r\n return reporter.getReport();\r\n }\r\n}\r\n\r\npublic class StockListReport extends Report{\r\n ArrayList stock=new ArrayList();\r\n public StockListReport(Reporter reporter){\r\n super(reporter);\r\n }\r\n public void addStockItem(StockItem stockItem){\r\n stock.add(stockItem);\r\n addReportItem(stockItem);\r\n }\r\n}\r\n\r\n//实现层次的抽象父类定义原子方法,供抽象层次的类调用\r\npublic abstract class Reporter{\r\n String header = \"\";\r\n String trailer = \"\";\r\n String report = \"\";\r\n public abstract void addLine(String line);\r\n public void setHeader(String header){\r\n this.header = header;\r\n }\r\n public void setTrailer(String trailer){\r\n this.trailer = trailer;\r\n }\r\n public String getReport(){\r\n return header+report+trailer;\r\n }\r\n}\r\n\r\npublic class HTMLReporter extends Reporter{ \r\n public HTMLReporter(){\r\n setHeader(\"\\n\\n\\n\");\r\n setTrailer(\"\\n\");\r\n }\r\n public void addLine(String line){\r\n report += line + \"
\\n\";\r\n }\r\n}\r\n\r\npublic class ASCIIReporter extends Reporter{\r\n public void addLine(String line) {\r\n report += line + \"\\n\";\r\n }\r\n}\r\n\r\n[/code]\r\n实际上,Bridge模式是一个很强大的模式,可以应用在很多方面。其基本思想:分离抽象和实现,是设计模式的基础之一。正如GOF所提到的:\"找到变化的部分,并将其封装起来\";\"更多的考虑用对象组合机制,而不是用对象继承机制\"。Bridge模式很好的体现了这几点。\r\n','浆糊','2002-02-07 10:30:48','2002-02-07 10:30:48',0,'192.168.1.228',139),('MVC模式','MVC模式比较的特别,它含义比较的广,涉及的层面也不仅仅是设计这一块,不好简单的把它归为设计模式。当然,它主要还是作为一个设计的概念被提到的,而且在Java体系中,MVC有着至关重要的作用。这儿提的是Java中的设计模式,当然不好拉了它不讲了。\r\n\r\n关于MVC的来龙去脉,这儿就不再讲了。这里主s要讲两个方面的:作为设计模式的MVC和作为体系结构模式的MVC。\r\n\r\n所谓MVC,指的是一种划分系统功能的方法,它将一个系统划分为三个部分:\r\n\r\n\'\'\'模型(Model):\'\'\'封装的是数据源和所有基于对这些数据的操作。在一个组件中,Model往往表示组件的状态和操作状态的方法。 \r\n\r\n\'\'\'视图(View):\'\'\'封装的是对数据源Model的一种显示。一个模型可以由多个视图,而一个视图理论上也可以同不同的模型关联起来。\r\n\r\n\'\'\'控制器(Control):\'\'\'封装的是外界作用于模型的操作。通常,这些操作会转发到模型上,并调用模型中相应的一个或者多个方法。一般Controller在Model和View之间起到了沟通的作用,处理用户在View上的输入,并转发给Model。这样Model和View两者之间可以做到松散耦合,甚至可以彼此不知道对方,而由Controller连接起这两个部分。\r\n\r\n有了前面介绍的诸多模式之后,就可以很容易的通过模式来解释MVC的内在行为了。前面说过,在设计模式中,MVC实际上是一个比较高层的模式,它由多个更基本的设计模式组合而成,Model-View的关系实际上是Observer模式,模型的状态和试图的显示相互响应,而View-Controller则是由Strategy模式所描叙的,View用一个特定的Controller的实例来实现一个特定的响应策略,更换不同的Controller,可以改变View对用户输入的响应。而其它的一些设计模式也很容易组合到这个体系中。比如,通过Composite模式,可以将多个View嵌套组合起来;通过FactoryMethod模式来指定View的Controller,等等。\r\n\r\n使用MVC的好处,一方面,分离数据和其表示,使得添加或者删除一个用户视图变得很容易,甚至可以在程序执行时动态的进行。Model和View能够单独的开发,增加了程序了可维护性,可扩展性,并使测试变得更为容易。 另一方面,将控制逻辑和表现界面分离,允许程序能够在运行时根据工作流,用户习惯或者模型状态来动态选择不同的用户界面。\r\n\r\nSwing号称是完全按照MVC的思路来进行设计的。在设计开始前,Swing的希望能够达到的目标就包括: \r\n\r\n模型驱动(Model-Driven)的编程方式。 \r\n提供一套单一的API,但是能够支持多种视感(look-and-feel),为用户提供不同的界面。 \r\n\r\n很自然的可以发现,使用MVC模式能够有助于实现上面的这两个目标。\r\n\r\n严格的说,Swing中的MVC实际上是MVC的一个变体:M-VC。 Swing中只显示的定义了Model接口,而在一个UI对象中集成了视图和控制器的部分机制。View和Control比较松散的交叉组合在一起,而更多的控制逻辑是在事件监听者部分引入的。\r\n\r\n但是,这并没有妨碍在Swing中体现MVC的精髓。事实上,在Swing的开发初期,Swing确实是按照标准的MVC模式来设计的,但是很快的问题就出现了:View和Controller实际上是紧密耦合的,很难作出一个能够适应不同View的一般化的Controller来,而且,一般也没有很大的必要。\r\n\r\n在Swing中基本上每一个组件都会有对应的Model对象。但其并不是一一对应的,一个Model接口可以为多个Swing对向服务,例如:JProgressBar,JScrollBar,JSlider这三个组件使用的都是BoundedRangeModel接口。这种模型的共享更能够从分的体现MVC的内涵。除了Model接口外,为了实现多个视感间的自由切换,每个Swing组件还包含一个UI接口--也就是View-Controller,负责对组件的绘制和接受用户输入。\r\n\r\nModel-View是Subject和Obverser的关系,因而,模型的改变必须要在UI对象中体现出来。Swing使用了JavaBeans的事件模型来实现这种通知机制。具体而言,有两种实现办法,一是仅仅通知事件监听者状态改变了,然后由事件监听者向模型提取必要的状态信息。这种机制对于事件频繁的组件很有效。另外的一种办法是模型向监听者发送包含了已改变的状态信息的通知给UI。这两种方法根据其优劣被分别是现在不同的组件中。比如在JScollBar中使用的是第一种方法,在JTable中使用的是第二种方法。而对Model而言,为了能够支持多个View,它并不知道具体的每一个View。它维护一个对其数据感兴趣的Obverser的列表,使得当数据改变的时候, 能够通知到每一个Swing组件对象。\r\n\r\n上面讲到的是作为设计模式的MVC。而在J2EE中,Sun更是将MVC提升到了一个体系结构模式的高度,这儿的MVC的含义就更为广泛了。与Swing中不同的是,在这儿MVC的各个部件不再是单纯的类或者接口,而是应用程序的一个组成部分!\r\n\r\n在J2EE Blueprint中,Sun推荐了一种基于MVC的J2EE程序的模式。对于企业级的分布式应用程序而言,它更需要支持多种形式的用户接口。比如,网上商店需要一个HTML的界面来同网上的客户打交道,WML的界面可以提供给无线用户,管理者可能需要传统的基于Swing的应用程序来进行管理,而对对商业伙伴,基于XML的Web服务可能对他们更为方便。\r\n\r\nMVC无疑是这样一个问题的有效的解决方法,通过在控制和显示逻辑分离出核心的数据存取功能,形成一个Model模块,能够让多种视图来共享这个Model。\r\n\r\n在J2EE中有几个核心的技术,JSP,JavaBean,Servlet,EJB,SessionBean,EntityBean构成了J2EE构架的基石。JSP能够生成HTML,WML甚至XML,它对应于Web应用程序中的View部分。EJB作为数据库与应用程序的中介,提供了对数据的封装。一般EntityBean封装的是数据,SessionBean是封装的是对数据的操作。这两个部分合起来,对应于Web应用程序的Model部分。在技术上,JSP能够直接对EJB进行存取,但这并不是好办法,那样会混淆程序中的显示逻辑和控制逻辑,使得JSP的重用性能降低。这时候有两种解决方法,通过JavaBean或者Servlet作为中介的控制逻辑,对EJB所封装的数据进行存取。这时,JavaBean或者Servlet对应于Web引用程序中的Controller部分。两种类型的Controller各有其优缺点:JSP同Servlet的交互不容易规范化,使得交互的过程变得复杂,但是Servlet可以单独同用户交互,实际上JSP的运行时状态就是Servlet;而由于JavaBean的规范性,JSP同JavaBean的交互很容易,利用JavaBean的get/set方法,JSP不需要过多的语句就可以完成数据的存取,这能够让JSP最大限度的集中在其视图功能上,而且,在桌面应用程序中使用JavaBean也很容易,而用Servlet就相对麻烦许多。根据不同的问题背景,可以选取不同的Controller,有时候也可以两者混合使用,或者直接在Servlet中调用JavaBean。\r\n\r\n在J2EE中,MVC是一个大的框架,这时我们往往把它不再看作为设计模式,而是作为体系结构模式的一个应用了。\r\n\r\n总结 \r\n在这篇文章中,从设计的角度,对Java的类库进行了一些分析,并着重于设计模式在其中的使用问题。相信大家看了之后,不论对Java类库本身,还是设计模式,都应该有了一个更深层次的了解。当然,Java类库是一个非常庞大的东西,还有着许多设计精良的结构。因而,对Java源代码的研究,不论对于编码还是设计,都是很有裨益的。本人接触设计模式的时间并不很长,对其的理解可能会有一些偏差,如有谬误的地方,还请能够提出,大家能够共同的探讨。\r\n\r\n需要说明的是,对模式的描叙实际上是有一套完整的规格(或者语言)来进行的,涉及到模式的意图(Intent),问题描叙(Problem),背景(Context),约束(Force),解决方案(Solution),结果(Resulting Context)等等。但这儿为了叙述的方便,并没有将它们一一列举。如果需要对模式有详细系统的研究,就应该对这些规格叙述有更深入的了解。\r\n----\r\n资源:\r\n[http://www-900.ibm.com/developerWorks/java/l-mvc/index.shtml|http://www-900.ibm.com/developerWorks/java/l-mvc/index.shtml]','浆糊','2002-02-07 10:48:28','2002-03-05 08:39:18',0,'浆糊',140),('源码下载','\'\'\'版本 1.2\'\'\'\r\n源代码:\r\n - 当前开发版本 [webpm_wiki.1.2.dev.src|/webpm/downloads/webpm_wiki.1.2.dev.src.zip]\r\n----\r\n\'\'\'版本 1.1\'\'\'\r\n源代码:webpm_wiki.1.1.dist-src [tar.gz|/webpm/downloads/webpm_wiki.1.1.dist-src.tar.gz] | [zip|/webpm/downloads/webpm_wiki.1.1.dist-src.zip]\r\n支持库:webpm_wiki.1.1.lib [zip|/webpm/downloads/webpm_wiki-lib-1.1.zip]\r\n\r\n解开到src/lib目录下。编译源代码需要[Ant|http://jakarta.apache.org/ant/index.html]的支持。\r\n----\r\n分类:[WebPM] | [webpm_wiki]','浆糊','2002-02-21 09:27:14','2002-02-28 10:21:47',0,'BrokenDoor',141),('业务分析指南','近来发现大家很少谈及业务分析的问题,不知道是什么原因。业务分析是系统成功的基石,为此将我在公司内使用的业务分析指南抽取其中要点组成下文,希望能抛砖引玉。 \r\n\r\n业务分析指南 \r\n说明: \r\n本指南是进行业务分析的大致工作步骤,没有谈及业务分析小组分工的问题。 \r\n工作步骤在实际工作中会有所变动,请大家自己辨别这些变化。 \r\n如果要引用这个业务分析指南,或其中部分文字,请注明出处,并且不要用于商业目的。 \r\n有任何不妥的地方,请大家多多指教。 \r\nCai \r\n1. 首先确定业务系统边界,做什么,不做什么。现在系统是一个黑匣子。 \r\n2. 然后寻找业务系统涉及的所有人/系统等等,从外到内依次展开。先将整个业务系统看成黑匣子,分析此业务系统相关的人、其它业务系统有哪些,得到一个外部用户清单。再依次展开系统,看内部有哪些人/系统。得到一个内部用户清单。 \r\n3. 然后确定这些用户地理上的分布情况,作出用户分布图。对内部用户还需要根据组织结构分布情况,分清楚这些用户在组织结构上的分布(这里重点是用户的分布情况而不是组织结构,因此不要做出像类似层次结构的组织结构图,主要考虑在一张图上可以清楚的说明,或者只是简单的说明位置,然后再另外一张图上说明用户之间地理位置/层次结构等等) \r\n4. 确定外部用户,系统相对于本系统的角度来说的目的,列出目的清单 \r\n5. 确定内部用户,在系统内的职责,列出职责清单。 \r\n6. 分析如何从外到内满足外部用户的目的。引起一系列的交互,暂时将每一个这样的一系列的交互作为一个业务流程,得到一个业务流程清单(主要不要涉及太细节的内容,如一个表单的内容,只需要知道这个表单大致的内容就可以了)。 \r\n7. 检查每一个人的职责时候都已经包含在上述业务流程中了,对于有遗漏的,对这个如何完成这个职责进行分析,获得一个新的交互过程,将这些交互过程也加入到这个业务流程清单中。 \r\n8. 此时可以对这些业务流程进行价值流分析、业务流重组等等,对业务将来可能对业务流产生的影响进行分析。 \r\n9. 也可以通过对别的企业进行分析后,进行比较等等,以获得最佳的业务工作效果。 \r\n10. 确定应用系统的边界(只支持某些业务、或者要支持决策支持等等。) \r\n11. 分析在此边界下,应用系统的限制条件如:系统的硬件环境/软件环境/系统经济上/社会要求/法律上/系统的生命周期等等的一些限制。 \r\n12. 重新组织业务流程,必要时对业务进行:合并/重组/取消等等重新得到系统能够(必须)实现的业务。重新获得在应用系统支持下的业务流程。得到业务流程清单,用户的职责清单、用户新的位置分布图等等,最好是能够作出业务流程与用户结合的二维业务流程图。 \r\n13. 到此业务分析结束,下面就直接进行需求分析(用例、非功能性需求等等,也可以对用例分析作出适当的调整,以免和前面的业务分析重合,这里的用例主要是寻找应用系统中的新出现的角色,从这些角色来寻找用例)。注意有关领域模型,包括业务类、及其交互完成某个业务等的情况没有做分析,我认为这一部分可以作为需求分析的一部分,在做完用例分析后,对每一个业务流程做这个工作,然后将部分领域类过渡到系统类,这样更加自然一些。所有这些我会在需求分析指南中重点给出。 ','浆糊','2002-02-26 23:33:37','2002-02-26 23:33:37',0,'浆糊',169),('2002年2月20日 聊天记录','[no]\r\n浆糊 (09:33:12): 什么时候开个会吧,等你有空\r\n熊刚 (09:32:33): 今天上午可以,踏冰在么?\r\n浆糊 (09:33:47): 他宾没有看到\r\n熊刚 (09:35:30): 我问一下看\r\n浆糊 (09:37:08): 嗯.我在看1.2得故事\r\n熊刚 (09:36:38): 版本列表我快改完了\r\n浆糊 (09:48:27): \r\n辛苦 :)\r\n4、查阅用户信息 \r\n点击用户名,查看用户相关的信息。(使用同步的用户文章)。用户信息标记[UserInfo] \r\n\r\n\r\n什么意思?\r\n熊刚 (09:48:33): 我这里考虑为注册用户自动创建一个文章,用这个标记来读取用户表的信息,作为文章的内容。\r\n浆糊 (09:49:53): 哦,呵呵..不错.\r\n熊刚 (09:49:29): 这样,其他的wiki的内容和用户表修改互不矛盾了!\r\n浆糊 (09:51:44): \r\n嗯,是的.因为用不同的页面处理了,呵呵..\r\n\r\n1.2地故事不错啊.\r\n熊刚 (09:51:53): 嗯,我觉得1.2之后我们可以休息一下。考虑一下白板或者工作流的开发了。\r\n浆糊 (09:53:09): \r\n还有一个就是我们的代码发布要跟上,每一个稳定的版本都要推出.\r\n\r\n浆糊 (09:53:23): \r\n嗯,是的.\r\n\r\n熊刚 (09:52:37): 嗯,花点时间搞定cvs\r\n浆糊 (09:54:01): 现在地cvs不是挺好的马?\r\n熊刚 (09:53:32): 我指的是使用,我不能每次都删库啊:)\r\n浆糊 (09:55:20): 可以更新的阿,我试过阿\r\n熊刚 (09:54:55): 我知道,主要是这两次改动的范围太大。\r\n浆糊 (09:55:57): 或者我们先提供打包下载.\r\n浆糊 (09:56:16): 嗯,是的.\r\n熊刚 (09:55:21): 嗯。数据库安装的问题要不要加到故事里?\r\n浆糊 (09:57:22): \r\n可以,\r\n我想可以做一个wiki的安装程序,我来吧,\r\n不过时间晚点.\r\n熊刚 (09:57:09): 嗯,考虑一下故事描述\r\n浆糊 (09:58:38): 嗯,我来加进去吧.\r\n浆糊 (11:11:06): 哇~,你做的excle表格真不错啊 :)\r\n熊刚 (11:11:15): 现在出了点问题,jwiki.jsp页 ,重定向的\r\n浆糊 (11:12:51): 没有问题啊,什么情况\r\n浆糊 (11:13:04): 看到了\r\n熊刚 (11:12:05): 最近变化\r\n熊刚 (11:12:32): 我在改,应该很快就行了\r\n浆糊 (11:13:47): \r\n没有的话,就不显示就是是了.\r\n\r\n浆糊 (11:14:04): 你用的是Iterator吧?\r\n熊刚 (11:15:33): 不是这个,是最近变化页。我已经改好了\r\n浆糊 (11:17:12): 嗯.好.\r\n浆糊 (11:17:30): 没有上传阿好像\r\n熊刚 (11:16:53): 没有更新,jwiki.jsp\r\n浆糊 (11:20:40): 呵呵..啥也没有了\r\n熊刚 (11:19:52): 没传完呢\r\n浆糊 (11:21:16): \r\n:)\r\n我太急了.\r\n1.1的故事全完了吧\r\n熊刚 (11:20:32): 还有skin\r\n浆糊 (11:22:00): 哦,那是否继续完成?\r\n熊刚 (11:21:22): 我放到v1.2里了\r\n浆糊 (11:22:34): 嗯.好.\r\n熊刚 (11:21:41): 搞定了\r\n浆糊 (11:22:48): 看到了.\r\n浆糊 (11:23:14): 如何恢复备份?\r\n熊刚 (11:22:28): 你那张相片哪里照的?\r\n熊刚 (11:22:35): http://210.192.109.59:8080/webpm/jwiki/admin/wiki_admin.jsp\r\n浆糊 (11:24:11): \r\n黄山,怎么了?\r\n是拍卧虎藏龙的地方\r\n熊刚 (11:24:07): 没什么,比较精干。风景不错,不过看不出是哪里。\r\n浆糊 (11:26:51): \r\n\"比较精干\" 说我啊? :)\r\n\r\ntomcat的安装那个连接怎么用?它能把本地机的文件传到服务器上?\r\n熊刚 (11:26:43): 不能。要指定War文件的URL\r\n熊刚 (11:27:14): 或者服务器上的绝对路径\r\n浆糊 (11:28:34): 哦,我看到的地址是g盘,呵呵..\r\n熊刚 (11:27:46): 那是我机器上的\r\n浆糊 (11:29:05): 那你也不能用吧\r\n熊刚 (11:28:12): 暂时不要用删除和安装着两个功能,我在本地都搞不定。\r\n浆糊 (11:29:39): 嗯.好的.\r\n熊刚 (11:28:51): 一般情况下,更新了classes目录后点“重新加载\" 就行了\r\n浆糊 (11:30:10): 最好是使用这个来管理,一直启动tomcat有时候会起不来\r\n浆糊 (11:30:39): 嗯.好?.\r\n熊刚 (11:29:44): 是啊,挺方便的。我刚才就这样用的\r\n熊刚 (11:31:10): 故事1和2已经搞定了\r\n浆糊 (11:32:58): 呵呵..是啊.\r\n熊刚 (11:32:51): 好了,我们抓紧时间讨论一下吧。踏冰那个家伙来了一下又不见了。估计他只对workflow感兴趣。\r\n浆糊 (11:34:32): \r\n嗯,是啊.\r\n到聊天室 吧.或者两人世界\r\n熊刚 (11:33:48): 用对话模式就行了\r\n浆糊 (11:35:14): \r\n嗯.是啊\r\n\r\n浆糊 (11:35:48): \r\n故事1.2怎么来分?\r\n\r\n熊刚 (11:35:15): 你先挑吧\r\n浆糊 (11:36:54): \r\n安装\r\nUserINfo标签\r\n\r\n熊刚 (11:36:13): 4、6、7、11 你做合适\r\n熊刚 (11:36:41): 6 有点麻烦\r\n浆糊 (11:37:41): 好的.\r\n浆糊 (11:38:16): 是的.主要是对数据库的要求比较高\r\n熊刚 (11:37:21): 3、5、8、9、10 归我\r\n浆糊 (11:38:33): \r\n项目的话,你是不是要提供标签?\r\n\r\n浆糊 (11:38:53): \r\nOk\r\n\r\n熊刚 (11:38:16): 跟user 一样,我想了一下用你以前说得好一点[user=BrokenDoor]\r\n熊刚 (11:38:26): [project=WebPM]\r\n浆糊 (11:40:09): 嗯.好的.那么project,user两个标签我来吧,或者你来,随便熟悉一下标签的那个部分.\r\n熊刚 (11:39:42): 该谁的谁作。我做project的\r\n浆糊 (11:40:59): 呵呵..好的.\r\n浆糊 (11:41:28): \r\n要多扫时间?\r\n\r\n熊刚 (11:41:16): 一个个来讨论吧。3 应该很快。3个工作日吧,主要是美化的问题。\r\n熊刚 (11:41:39): 4 呢?\r\n浆糊 (11:43:03): \r\n2个吧,时间宽余点\r\n\r\n熊刚 (11:42:05): 根据用户名查找文章,如果不存在则自动创建用户名的文章。\r\n熊刚 (11:42:25): 内容就是 [user] 标记,呵呵\r\n浆糊 (11:44:31): 嗯.好的.自动创建用户名的文章是什么意思?\r\n浆糊 (11:45:10): 用户专辑你想怎么做?\r\n熊刚 (11:44:26): 比如:建个用户 “破门”, 但是没有建wiki文章,那么就自动创建topic=破门 的文章。\r\n熊刚 (11:45:02): 按时间逆序列出来就行了\r\n熊刚 (11:45:28): 我这里想到一个问题,要不要做wiki分页?\r\n浆糊 (11:47:15): 嗯.我想 是点击[user=破门]然后到破门的个人信息,其中有一个 发表的文章,一个 更新的文章 两个连接\r\n浆糊 (11:47:31): wiki分页是什么意思?\r\n熊刚 (11:48:18): 不是这样的,应该是点击[破门]到破门的wiki文章,里面[user=破门]被wiki翻译成三个部分,一是用户破门的信息,二是专集,三是更新过的文章\r\n熊刚 (11:48:45): 其他部分不变\r\n浆糊 (11:49:53): 全部显示?是不是太长了阿.前20个吧.\r\n熊刚 (11:49:38): 分页就是考虑文章可能太长这个问题。\r\n浆糊 (11:50:52): 嗯.这个我想一下.\r\n熊刚 (11:50:15): 二和三不用显示,做个连接就行了\r\n浆糊 (11:51:26): 分页我们要想想如何统一处理\r\n熊刚 (11:50:38): 放到1.3吧\r\n浆糊 (11:51:40): 我刚才就是这个意思\r\n浆糊 (11:51:44): 好的.\r\n熊刚 (11:51:22): [user=破门]主要是为了读取用户表的信息,其他作为连接扩展\r\n浆糊 (11:52:29): 嗯.好\r\n熊刚 (11:51:44): 要多长时间做?\r\n浆糊 (11:52:45): 4 2个工作日\r\n熊刚 (11:51:51): ok\r\n浆糊 (11:53:14): 我最近比较忙,所以时间长点\r\n浆糊 (11:53:28): 5多少时间?\r\n熊刚 (11:52:34): 5 比较简单 不分页的话 0.5 工作日\r\n浆糊 (11:53:50): 嗯.好 .\r\n熊刚 (11:52:51): 我们先算标准工作日,然后折算\r\n浆糊 (11:54:04): 怎么折算?\r\n熊刚 (11:53:15): 比如我这个星期能提供2个标准工作日\r\n浆糊 (11:54:26): 嗯.好的.\r\n熊刚 (11:53:43): 该 6 了\r\n浆糊 (11:54:45): 那4地化就 1个 行了.\r\n熊刚 (11:54:07): 好的\r\n浆糊 (11:55:09): 6 1个\r\n浆糊 (11:55:34): 7 一个\r\n熊刚 (11:54:42): 嗯,7 要加上修改的文章列表\r\n浆糊 (11:55:50): 嗯.好.\r\n熊刚 (11:54:59): 2 个工作日吧\r\n浆糊 (11:56:04): 好.\r\n熊刚 (11:55:25): 修改的挺麻烦,我发现现在的wiki没有修改列表\r\n浆糊 (11:56:46): 是的.不过有备份表阿.\r\n熊刚 (11:56:22): 如果我们把备份表导出了呢?\r\n浆糊 (11:57:30): 那就完.\r\n熊刚 (11:57:17): 可以考虑用 visitor 表的方法,加一个修改日志表。这样版本列表可以完整了\r\n浆糊 (11:59:05): 这是在更新一个文章的时候要更新三个表,性能是不是有些差?\r\n熊刚 (11:58:14): 嗯,我们把修改文章列表单列一个故事吧\r\n浆糊 (11:59:25): 好的.\r\n熊刚 (11:58:35): mysql有没有触发器?\r\n浆糊 (11:59:59): 没有吧好像.\r\n熊刚 (11:59:24): 算了,性能以后考虑。功能是第一位的,先简单点吧。\r\n浆糊 (12:00:31): 好的.\r\n\r\n浆糊 (13:47:38): \r\n来了.\r\n\r\n浆糊 (13:47:45): 继续吧\r\n熊刚 (13:46:53): 好的\r\n浆糊 (13:48:25): 8.项目注册\r\n熊刚 (13:48:13): 这个跟用户注册一样,2d 吧\r\n浆糊 (13:49:39): 嗯.注册之后的页面生成呢,也就是9\r\n熊刚 (13:48:42): 东西还挺多,我改踏冰的代码时,累得半死\r\n浆糊 (13:49:57): 呵呵..那个家伙\r\n熊刚 (13:49:16): 页面模板很麻烦,关键是如何跟项目绑定\r\n浆糊 (13:50:58): 是啊.想想\r\n浆糊 (13:51:52): 生成一个 项目:XXXX 的关键字怎么样?\r\n熊刚 (13:50:58): 首先是模板保存在哪?\r\n熊刚 (13:51:28): 我们上次讨论过,我觉得需要用数据库\r\n浆糊 (13:52:30): 想到一个好东西 xslt\r\n浆糊 (13:52:39): xml==>html\r\n熊刚 (13:52:06): 应该是可以,这个不太熟\r\n熊刚 (13:52:12): 需要spike\r\n浆糊 (13:53:26): 好像也 不太好和wiki结合.\r\n熊刚 (13:52:57): 结合到可以等下阶段考虑,关键是现在的故事如何实现!\r\n浆糊 (13:54:33): 如果要用wiki来管理项目的话,用xslt好像不是太好.\r\n熊刚 (13:53:37): 我觉得可以简单点,把模板用类似wiki的表达式引擎处理一下\r\n浆糊 (13:55:05): 关键字用什么?\r\n熊刚 (13:54:06): 比如:[project.getName()]\r\n熊刚 (13:54:36): 呵呵,想多了。但是用表达式不方便,还是脚本好些\r\n浆糊 (13:56:47): \r\n我的想法:\r\n注册新项目==>自动生成一个特殊的关键字,合文章内容,文章内容就是项目的内容.\r\n\r\n熊刚 (13:55:48): 我以前在公司里的项目做过。把页面转换成函数,然后执行,类似JSP/ASP的处理\r\n浆糊 (13:57:13): 页面转化成函数是什么意思?\r\n熊刚 (13:56:40): 你的想法跟User是一样的,但是项目是一组页面。会复杂一些\r\n浆糊 (13:57:52): 项目的数据表和wiki的数据表是不是用同一个?\r\n浆糊 (13:58:10): 嗯.是的.\r\n熊刚 (13:57:11): 项目基本信息的表是单独的\r\n浆糊 (13:58:49): 那就比较麻烦了.如果要用wiki来管理.\r\n熊刚 (13:57:51): 其他的则需要用wiki页面。项目主页可以使用[project=name]的标记读取项目基本信息表\r\n浆糊 (13:59:30): 哦,也就是说,项目管理,脱离wiki ?\r\n熊刚 (13:58:53): 可以让项目管理员按要求生成项目主页的其他相关内容,比如项目文档等\r\n熊刚 (13:59:56): 我设想项目的下级信息,使用 WebPM.用户故事 这种命名\r\n浆糊 (14:01:29): \r\n项目文档存在wiki表里,对巴.\r\n这样也有问题: x1的文档叫 [文档] ,x2的文档也叫[文档],用起来不好.\r\n浆糊 (14:01:58): 嗯.这个好像可以. WebPM.文档\r\n熊刚 (14:01:06): 如果不能自动化,就要求手工指定前缀,x1的文档应该是[x1.文档]\r\n浆糊 (14:02:29): 嗯.是啊.有点烦\r\n浆糊 (14:02:59): 而且也不能保证在wiki里原先就不存在[x1.文档]\r\n熊刚 (14:03:08): \r\n所以,项目主页模板可能的内容如下:\r\n[project=${project.name}]\r\n----\r\n[${project.name}.文档]\r\n\r\n熊刚 (14:03:32): 如果已经存在,应该自动并入项目文档\r\n熊刚 (14:03:58): 这里可能要考虑wiki的自动分类功能\r\n熊刚 (14:05:04): 通常不可能重复的,因为project.name 唯一。如果重复就不管它了,或者自动合并。\r\n浆糊 (14:06:05): \r\n自动并入不好吧.不过也没有什么好的办法.\r\n${project.name} 是不是像ant?那我们又如何去得到真真的值呢?\r\n熊刚 (14:05:30): 这里是个模板,在写入wiki的时候进行替换\r\n熊刚 (14:06:09): 利用 Project 和 WikiTemplate 对象就可以处理了\r\n浆糊 (14:07:56): 那以后这个主页就不能自己编辑了?\r\n熊刚 (14:07:44): 可以,主页里面的${project.name}已经被替换为WebPM之类的了\r\n熊刚 (14:08:07): 你觉得这样如何?\r\n浆糊 (14:09:11): 嗯.那这些内容一定要存在wiki表里.\r\n熊刚 (14:09:23): 本来就是存在wiki里。只不过在注册项目的时候,根据模板自动生成一堆项目相关的 wiki文章\r\n浆糊 (14:10:54): 那这wiki文章的topic叫什么?\r\n熊刚 (14:10:36): WebPM / WebPM.文档 / WebPM.论坛 之类的\r\n浆糊 (14:12:37): 嗯.可以.项目主页就叫 WebPM.项目\r\n熊刚 (14:12:00): 不用吧,就叫 WebPM 就行了\r\n浆糊 (14:14:04): \r\n由于文章的数很多,关键字也多.\r\n很多关键字会被占用.\r\n熊刚 (14:13:59): 一般不会有矛盾的,或者可以考虑 项目.WebPM\r\n浆糊 (14:15:26): \r\n哦,不会的,呵呵..标记不同.\r\n[project=WebPM]\r\n熊刚 (14:15:41): 其实我认为[project=WebPM]的主页应该是[WebPM]或者[项目.WebPM]\r\n熊刚 (14:15:59): [project=WebPM]会被替换成项目信息\r\n浆糊 (14:17:47): \r\n嗯,对的.我自己有点晕了,呵呵..\r\n[项目.WebPm]比较好.\r\n\r\n熊刚 (14:17:08): 嗯,那就暂时这么定\r\n浆糊 (14:18:24): 嗯.好.\r\n熊刚 (14:17:37): 看来这个故事要拆\r\n浆糊 (14:18:52): 这个艰苦的工作就叫给你了,呵呵..\r\n浆糊 (14:19:03): 要拆\r\n熊刚 (14:18:08): 分成 Wiki 模板 和 项目主页\r\n浆糊 (14:19:34): 嗯.\r\n熊刚 (14:19:05): \r\n我作也没问题,只是一上班就乱了。\r\n8.1 Wiki模板\r\n8.2 项目主页\r\n熊刚 (14:19:28): \r\n错了,应该是9.1/9.2. 晕了\r\n\r\n浆糊 (14:20:50): 呵呵..彼此\r\n浆糊 (14:21:40): 10.项目成员\r\n熊刚 (14:21:01): 时间还没有标\r\n熊刚 (14:21:24): 9.1 2d / 9.2 2d\r\n浆糊 (14:22:37): Ok.\r\n浆糊 (14:23:00): 等一下把故事列表也更新一下\r\n熊刚 (14:22:09): 10. 1d 就可以了\r\n熊刚 (14:22:40): 以后加权限才麻烦\r\n浆糊 (14:24:08): 权限我来,加一个proxy\r\n浆糊 (14:24:17): \r\n等以后的故事中\r\n\r\n熊刚 (14:23:37): \r\n嗯,老规矩,难的往后放。\r\n11.安装程序\r\n浆糊 (14:24:47): 2D\r\n熊刚 (14:24:03): OK\r\n浆糊 (13:47:38): \r\n来了.\r\n\r\n浆糊 (13:47:45): 继续吧\r\n熊刚 (13:46:53): 好的\r\n浆糊 (13:48:25): 8.项目注册\r\n熊刚 (13:48:13): 这个跟用户注册一样,2d 吧\r\n浆糊 (13:49:39): 嗯.注册之后的页面生成呢,也就是9\r\n熊刚 (13:48:42): 东西还挺多,我改踏冰的代码时,累得半死\r\n浆糊 (13:49:57): 呵呵..那个家伙\r\n熊刚 (13:49:16): 页面模板很麻烦,关键是如何跟项目绑定\r\n浆糊 (13:50:58): 是啊.想想\r\n浆糊 (13:51:52): 生成一个 项目:XXXX 的关键字怎么样?\r\n熊刚 (13:50:58): 首先是模板保存在哪?\r\n熊刚 (13:51:28): 我们上次讨论过,我觉得需要用数据库\r\n浆糊 (13:52:30): 想到一个好东西 xslt\r\n浆糊 (13:52:39): xml==>html\r\n熊刚 (13:52:06): 应该是可以,这个不太熟\r\n熊刚 (13:52:12): 需要spike\r\n浆糊 (13:53:26): 好像也 不太好和wiki结合.\r\n熊刚 (13:52:57): 结合到可以等下阶段考虑,关键是现在的故事如何实现!\r\n浆糊 (13:54:33): 如果要用wiki来管理项目的话,用xslt好像不是太好.\r\n熊刚 (13:53:37): 我觉得可以简单点,把模板用类似wiki的表达式引擎处理一下\r\n浆糊 (13:55:05): 关键字用什么?\r\n熊刚 (13:54:06): 比如:[project.getName()]\r\n熊刚 (13:54:36): 呵呵,想多了。但是用表达式不方便,还是脚本好些\r\n浆糊 (13:56:47): \r\n我的想法:\r\n注册新项目==>自动生成一个特殊的关键字,合文章内容,文章内容就是项目的内容.\r\n\r\n熊刚 (13:55:48): 我以前在公司里的项目做过。把页面转换成函数,然后执行,类似JSP/ASP的处理\r\n浆糊 (13:57:13): 页面转化成函数是什么意思?\r\n熊刚 (13:56:40): 你的想法跟User是一样的,但是项目是一组页面。会复杂一些\r\n浆糊 (13:57:52): 项目的数据表和wiki的数据表是不是用同一个?\r\n浆糊 (13:58:10): 嗯.是的.\r\n熊刚 (13:57:11): 项目基本信息的表是单独的\r\n浆糊 (13:58:49): 那就比较麻烦了.如果要用wiki来管理.\r\n熊刚 (13:57:51): 其他的则需要用wiki页面。项目主页可以使用[project=name]的标记读取项目基本信息表\r\n浆糊 (13:59:30): 哦,也就是说,项目管理,脱离wiki ?\r\n熊刚 (13:58:53): 可以让项目管理员按要求生成项目主页的其他相关内容,比如项目文档等\r\n熊刚 (13:59:56): 我设想项目的下级信息,使用 WebPM.用户故事 这种命名\r\n浆糊 (14:01:29): \r\n项目文档存在wiki表里,对巴.\r\n这样也有问题: x1的文档叫 [文档] ,x2的文档也叫[文档],用起来不好.\r\n浆糊 (14:01:58): 嗯.这个好像可以. WebPM.文档\r\n熊刚 (14:01:06): 如果不能自动化,就要求手工指定前缀,x1的文档应该是[x1.文档]\r\n浆糊 (14:02:29): 嗯.是啊.有点烦\r\n浆糊 (14:02:59): 而且也不能保证在wiki里原先就不存在[x1.文档]\r\n熊刚 (14:03:08): \r\n所以,项目主页模板可能的内容如下:\r\n[project=${project.name}]\r\n----\r\n[${project.name}.文档]\r\n\r\n熊刚 (14:03:32): 如果已经存在,应该自动并入项目文档\r\n熊刚 (14:03:58): 这里可能要考虑wiki的自动分类功能\r\n熊刚 (14:05:04): 通常不可能重复的,因为project.name 唯一。如果重复就不管它了,或者自动合并。\r\n浆糊 (14:06:05): \r\n自动并入不好吧.不过也没有什么好的办法.\r\n${project.name} 是不是像ant?那我们又如何去得到真真的值呢?\r\n熊刚 (14:05:30): 这里是个模板,在写入wiki的时候进行替换\r\n熊刚 (14:06:09): 利用 Project 和 WikiTemplate 对象就可以处理了\r\n浆糊 (14:07:56): 那以后这个主页就不能自己编辑了?\r\n熊刚 (14:07:44): 可以,主页里面的${project.name}已经被替换为WebPM之类的了\r\n熊刚 (14:08:07): 你觉得这样如何?\r\n浆糊 (14:09:11): 嗯.那这些内容一定要存在wiki表里.\r\n熊刚 (14:09:23): 本来就是存在wiki里。只不过在注册项目的时候,根据模板自动生成一堆项目相关的 wiki文章\r\n浆糊 (14:10:54): 那这wiki文章的topic叫什么?\r\n熊刚 (14:10:36): WebPM / WebPM.文档 / WebPM.论坛 之类的\r\n浆糊 (14:12:37): 嗯.可以.项目主页就叫 WebPM.项目\r\n熊刚 (14:12:00): 不用吧,就叫 WebPM 就行了\r\n浆糊 (14:14:04): \r\n由于文章的数很多,关键字也多.\r\n很多关键字会被占用.\r\n熊刚 (14:13:59): 一般不会有矛盾的,或者可以考虑 项目.WebPM\r\n浆糊 (14:15:26): \r\n哦,不会的,呵呵..标记不同.\r\n[project=WebPM]\r\n熊刚 (14:15:41): 其实我认为[project=WebPM]的主页应该是[WebPM]或者[项目.WebPM]\r\n熊刚 (14:15:59): [project=WebPM]会被替换成项目信息\r\n浆糊 (14:17:47): \r\n嗯,对的.我自己有点晕了,呵呵..\r\n[项目.WebPm]比较好.\r\n\r\n熊刚 (14:17:08): 嗯,那就暂时这么定\r\n浆糊 (14:18:24): 嗯.好.\r\n熊刚 (14:17:37): 看来这个故事要拆\r\n浆糊 (14:18:52): 这个艰苦的工作就叫给你了,呵呵..\r\n浆糊 (14:19:03): 要拆\r\n熊刚 (14:18:08): 分成 Wiki 模板 和 项目主页\r\n浆糊 (14:19:34): 嗯.\r\n熊刚 (14:19:05): \r\n我作也没问题,只是一上班就乱了。\r\n8.1 Wiki模板\r\n8.2 项目主页\r\n熊刚 (14:19:28): \r\n错了,应该是9.1/9.2. 晕了\r\n\r\n浆糊 (14:20:50): 呵呵..彼此\r\n浆糊 (14:21:40): 10.项目成员\r\n熊刚 (14:21:01): 时间还没有标\r\n熊刚 (14:21:24): 9.1 2d / 9.2 2d\r\n浆糊 (14:22:37): Ok.\r\n浆糊 (14:23:00): 等一下把故事列表也更新一下\r\n熊刚 (14:22:09): 10. 1d 就可以了\r\n熊刚 (14:22:40): 以后加权限才麻烦\r\n浆糊 (14:24:08): 权限我来,加一个proxy\r\n浆糊 (14:24:17): \r\n等以后的故事中\r\n\r\n熊刚 (14:23:37): \r\n嗯,老规矩,难的往后放。\r\n11.安装程序\r\n浆糊 (14:24:47): 2D\r\n熊刚 (14:24:03): OK\r\n浆糊 (14:26:02): 现在有个问题,就是文章的创建日期没有\r\n熊刚 (14:25:44): 有影响么?算个bug,fix了就完了\r\n浆糊 (14:27:11): \r\n是啊.这个信息最好是要有\r\n\r\n熊刚 (14:26:45): 你改吧,我正把代码update到cvs\r\n浆糊 (14:28:10): 嗯.好的.\r\n熊刚 (14:27:27): 下面算时间了:\r\n熊刚 (14:29:28): \r\n3 - 3d\r\n4 - 1d\r\n5 - 0.5\r\n6 - 1\r\n7 - 2 7.1 - 1/7.2 - 1\r\n8 - 2\r\n9 - 4 9.1 - 2/ 9.2 - 2\r\n10 - 1\r\n11 - 2\r\n浆糊 (14:31:05): 嗯.\r\n熊刚 (14:30:17): 一共 16.5 d\r\n熊刚 (14:30:29): 天啊\r\n浆糊 (14:32:10): 我是6D\r\n熊刚 (14:31:17): 3 个工作周! 我们把任务发布出去找支援吧\r\n浆糊 (14:32:35): 咳~,很难找到.\r\n熊刚 (14:32:35): 先整理一下,把我们自己在作的标上,其他的看有没有志愿者。一直没有我们就慢慢做了。\r\n浆糊 (14:34:00): 嗯.好的.\r\n浆糊 (14:34:53): 我们好像少一个公开发布我们项目信息的地方.人多的地方.\r\n熊刚 (14:34:25): 我看发布时间暂时没有办法定了。因为这个月我的时间很难说\r\n浆糊 (14:35:49): 好的.作的差不多了再说吧.\r\n熊刚 (14:35:37): 是的,国内没有真正好的自由开发人员聚集地\r\n熊刚 (14:36:00): 我希望将来的webpm可能提供这么一个基地\r\n浆糊 (14:37:20): 嗯.是啊.\r\n熊刚 (14:36:26): 我们还是以wiki为基地吧。\r\n熊刚 (14:36:45): 给其他人一个真正参与的机会\r\n浆糊 (14:38:14): 嗯.好的.aka好像人也不多\r\n浆糊 (14:39:57): 不知道有没有自由开发者,在国内\r\n熊刚 (14:39:08): 全中国都一样,热情很容易过去,如果不能参与的话。\r\n浆糊 (14:40:20): \r\n是啊\r\n\r\n熊刚 (14:39:48): 所以还是必须坚持,才能一步一步走下去!\r\n浆糊 (14:41:13): 嗯.我们到现在做了多少时间了?\r\n熊刚 (14:41:20): 你看了那个帖子么?我们是去年12月5日正式合作。做wiki可能还晚一点\r\n浆糊 (14:42:52): 看了.也有2个多月了.\r\n熊刚 (14:43:05): 嗯,我觉得进度还是很快的,现在开始有点雏形了。而且我们越继续就越会清楚WebPM应该做成什么样,才能真正有用。\r\n浆糊 (14:44:52): 嗯.需求随着开发的深入而越来越清楚\r\n熊刚 (14:44:08): 如果我们能够把WebPM开发中遇到的问题一个一个解决,也就找到了给互联网软件开发者提供有效帮助的最佳途径。\r\n浆糊 (14:46:28): 嗯.最好人再多点,才能暴露出更过的问题\r\n熊刚 (14:47:23): 人少是一个大问题,但是我们也没有更好的办法.\r\n浆糊 (14:48:42): 我们的宣传好像有问题\r\n熊刚 (14:48:04): 如果我们的webpm能够真正的起作用,就可以好好的宣传了。\r\n浆糊 (14:49:23): 没有好的途径,而且我们现在论坛去的也少了,所以和别人交流也少了.\r\n浆糊 (14:49:53): \r\n1.2版本完成知道,雏形就出来了.\r\n\r\n熊刚 (14:49:05): 一定要有一个自由开发者的基地,所以v1.2完成后下一步我们要进行大范围宣传\r\n熊刚 (14:50:01): cosoft的cvs每次都要输密码,真的很烦\r\n浆糊 (14:52:07): \r\n呵呵..是啊.\r\n\r\n代码问题还是不好解决.不可能说让别人在我们这里进行项目管理,而用别人的cvs\r\n熊刚 (14:52:16): 只能一步一步来,我们先解决交流和信息发布的问题\r\n浆糊 (14:53:33): \r\nen ,似的.\r\n\r\n熊刚 (14:54:34): 我觉得白板和会议室应该是v1.2完成后的主要任务。wiki的扩充可以让其他人来做,没人的话就暂停。\r\n熊刚 (14:54:44): 我们只进行必要的维护\r\n浆糊 (14:56:14): \r\n嗯.好的.\r\n时候考虑用现有的open source?\r\n熊刚 (14:55:58): 嗯,先作一个servlet+applet的聊天室,然后再扩充。\r\n熊刚 (14:56:14): 以后再讨论吧\r\n浆糊 (14:57:32): 嗯,好的.这个我可以开个头\r\n熊刚 (14:56:53): 嗯,我对java编程还不是很熟\r\n浆糊 (14:58:10): 呵呵..我看很熟阿 :)\r\n熊刚 (14:57:32): 错了,我对编程很熟,但是对java不熟\r\n熊刚 (14:57:55): 我3点钟有个会,等会儿见\r\n浆糊 (14:59:00): 很快能熟悉的,java简单.\r\n浆糊 (14:59:04): 好.\r\n熊刚 (14:58:29): 我把聊天记录上传,你来整理?\r\n浆糊 (15:00:17): 如何整理?\r\n熊刚 (15:00:21): 我记录了一些txt 文件,传到 downloads下。你根据记录整理故事和第三次(v1.2版本)计划。\r\n浆糊 (15:01:42): 嗯.好的.\r\n[/no]','浆糊','2002-02-20 18:54:22','2002-02-20 18:54:22',0,'浆糊',154),('','Nothing','61.174.136.1','2002-02-08 15:32:15','2002-02-08 15:32:15',0,'61.174.136.1',142),('SVG','SVG 是可伸缩矢量图形。其是基于XML的。\r\nSMIL 是用于和SVG结合生成动画的语言(synchronized multimedia integration language)\r\n----\r\n[什么是SVG]\r\n[基于XML的可升级矢量图像(SVG)浅析]\r\n[将 XML 转换成 SVG]\r\n----\r\n相关站点\r\n----\r\n开放源码项目[Batik SVG Toolkit|http://xml.apache.org/batik/index.html]\r\n一些SVG实例,中文站点[VR技术应用-SVG|http://www.86vr.net/plugs/svg/svg.htm]\r\n一个全部用SVG做的网站[http://www.svgspider.com/|http://www.svgspider.com/]\r\n[W3C的SMIL主页|http://www.w3.org/TR/smil20/]\r\n----\r\n分类:[webpm_net]|[SVG]\r\n','61.138.52.102','2002-02-08 18:36:13','2002-03-15 23:30:21',0,'takaka',143),('test<>','test','浆糊','2002-02-08 21:34:36','2002-02-08 21:34:36',0,'192.168.1.228',144),('','Nothingsfsdfsdfasf','127.0.0.1','2002-02-09 00:27:21','2002-02-09 00:27:21',0,'127.0.0.1',147),('测试','在这里编辑文章内容...','浆糊','2002-02-22 11:38:23','2002-02-22 11:46:06',0,'浆糊',151),('更新时发生错误','Jwiki不能保存你的更改,因为另一个用户在你刚才编辑过程中修改了该页面并且已经保存. 如果现在保存你的修改,那么它的修改就会丢失. \r\n\r\n你可以这样来处理: \r\n\r\n1.使用你浏览器的回退键回到编辑页. \r\n2.把你的变化拷到粘贴板或一个临时的地方(如文本编辑器). \r\n3.刷新页. 你应当能够看到页面的最新版本.你的改变没有生效. \r\n4.再次对文件进行修改. 从粘贴板或文本编辑器中复制过来. \r\n5.按保存','127.0.0.1','2002-02-08 23:38:25','2002-02-08 23:38:25',1,'127.0.0.1',146),('陈超','设计人士','浆糊','2002-02-09 21:54:46','2002-02-09 21:54:46',0,'192.168.1.228',148),('letdo','有意思 :)','211.98.105.76','2002-02-14 02:05:44','2002-02-14 02:05:44',0,'211.98.105.76',150),('设计模式与XP','模式与XP \r\nJoshua Kerievsky 著,Gigix 译 \r\n概述 \r\n模式和极端编程(XP )都为软件设计、开发者提供了无法用金钱衡量的帮助。但是迄今为止XP 大量 \r\n关注于重构(refactoring ),而对模式只字不提。在这篇文章中,我问“为什么”,并且最终描述出模式怎样 \r\n以XP 的方式更好地实现、以及XP 怎样因为包含对模式的使用而变得更好。 \r\n致谢 \r\n非常感谢Kent Beck 、Martin Fowler 和Ward Cunningham ,他们为这篇文章提出了友善的评论。 \r\n仍在所知不多的时候我们就开始了自己的程序设计生涯,生产出的软件也反映出了我们的缺乏经验: \r\n我们创建的代码臃肿、错误百出、脆弱、难以维护、难以扩展。随着时间的流逝,我们成为了更好的软件 \r\n设计者:我们从技术作家、专家那里学习,我们从自己的错误中学习。现在我们编写具有高度灵活性的软 \r\n件,它适应广泛而且坚固。当被请求编写一个新的系统时,我们知道查明当前和将来的需求,这样我们可 \r\n以设计软件来处理当前和将来的需要。 \r\n在软件开发生涯的这个阶段,极端编程告诉我们,我们经常对软件过分设计(over-engineer )了。我 \r\n们从自己的错误中学到了太多,我们不希望重复这些错误,所以我们在系统生命周期的早期做了大量的努 \r\n力来创造灵活而坚固的设计。不幸的是,我们没有认识到:如果这个系统永远不需要这个程度的灵活性和 \r\n坚固性,那么我们所有的工作就都没有意义了。我们过分设计了。 \r\n\r\n我也曾经过分设计过。说实话,与其他设计者坐在一间房间里考虑如何设计软件来适应许多当前和将 \r\n来的需求,这的确是一种乐趣。我们把自己学到的所有东西——尤其是那些最好的经验——应用在设计中。 \r\n我们常常知道需求的列表会改变,但用户或客户总是改变需求。不过,我们认为我们可以足够聪明地设计 \r\n软件,使软件足够灵活,使它能应付所有的需求变化。 \r\n典型的过分设计。 \r\n今天,极端编程将告诉你这是多么愚蠢的做法。XP 说,我们必须让设计自己显现出来,而不是去预 \r\n测设计将是什么样子。XP 说,“做可能起作用的最简单的事”,因为“你将不再需要它你将不再需要它你将不再需要它你将不再需要它”。另外,Kent Beck \r\n说: \r\n你需要在一个强调沟通、简单、反馈和勇气的价值系统中选择最好的工作方法,这样你才能你需要在一个强调沟通、简单、反馈和勇气的价值系统中选择最好的工作方法,这样你才能你需要在一个强调沟通、简单、反馈和勇气的价值系统中选择最好的工作方法,这样你才能你需要在一个强调沟通、简单、反馈和勇气的价值系统中选择最好的工作方法,这样你才能 \r\n勇敢的脱离过分设计。勇敢的脱离过分设计。勇敢的脱离过分设计。勇敢的脱离过分设计。[Beck1 00] \r\n同意。但是,现在我必须提到我的朋友Norm Kerth 。Norm 在软件开发领域有丰富的经验和见识。一年 \r\n以前我问他“对XP 有什么想法”。他说: \r\n我喜欢我喜欢我喜欢我喜欢XP 里的每样东西。我关心的是:还有什么不在里的每样东西。[Kerth 99] \r\n当时,我只认为Norm 是一个保守派。但现在我不能确定了。XP 明显缺少的就是使用模式的经验。尽 \r\n管一些XP 的创始人帮助建设了模式社团,但没有哪一个坚定清楚的说明模式如何适应XP 。 \r\n一开始,这还没有让我感到迷惑。但现在,我的确感到迷惑。 \r\n我感到迷惑,因为我在XP 和模式上的经验让我相信:在XP 的场景中模式会工作得更好;并且当XP 包 \r\n含模式时,XP 也会工作得更好。 \r\n这需要一些解释。我将从描述我自己使用模式和XP 的一些经验开始。 \r\n从1995 年开始,我开始沉浸入模式之中。我学习模式文献、主办了一个每周一次的模式学习组、使用 \r\n模式设计和开发软件、并进行UP (一个关于使用模式的国际学术会议)的组织和运转工作。说我“热衷于 \r\n模式”实在是一种保守的说法。 \r\n当时,就象很多第一次学习模式的人一样,我有一点过分渴望使用它们。这不是一件好事,因为它会 \r\n让你的设计比需要的更复杂。但我没有意识到这一点,直到我开始学习重构。 \r\n大概在1996 年,我第一次接触到了重构。我开始实证它并很快观察到重构带我离开了我在模式学习中 \r\n学到的某些原则。 \r\n举个例子,那本里程碑式的书——《设计模式:可复用面向对象软件的基础》中的一个原则是: \r\n针对接口编程,而不是针对实现编程。针对接口编程,而不是针对实现编程。[GHJV1 95] \r\n《设计模式》的作者们做了相当精彩的工作来解释为什么我们需要遵循这条建议。几乎在所有的模式 \r\n中,都讨论了当你针对某个特定实现编程时你的软件如何变得缺少灵活性和可修改性。几乎每一次都是接 \r\n口过来帮忙。 \r\n但如果我们不需要灵活性和可修改性,情况又是怎样?为什么我们要在开始设计时预料一些可能永远 \r\n不会出现的需要?这是我的一次觉悟。所以随后我记录下了下面这个J AVA 技巧: \r\n不要分离类和接口不要分离类和接口不要分离类和接口不要分离类和接口 \r\n我曾经习惯于在我的接口名字后面加上一个“I ”。但当我继续学习更多的重构技术时,我开始看到一 \r\n种明智的做法:把类名和接口名设计成一样。下面是原因:在开发过程中,你知道你可以使用一个接口来 \r\n让某些东西变得灵活(使实现多样化),但可能你现在根本不需要让实现多样化。所以,放下预测太多的 \r\n“过分设计”吧,你仍然保持简单,仍然把东西放在一个类中。在某个地方你会写一个方法语句来使用这 \r\n个类的对象。然后,几天、几星期、几个月之后,你明确“需要”一个接口。因此你就将原来的类转换成 \r\n一个接口,再创建一个实现类(实现新的接口),并且让你原来的语句保持不变。[Kerievsky 96] \r\n我继续学习类似于重构的课程,逐渐的,我使用模式的方式开始改变了。我不再预先考虑使用模式。 \r\n现在,我更加明智了:如果某个模式可以解决某个设计问题,如果它提供一种方法来实现一个需求,我就 \r\n会使用它,但我将从可以编码出的模式的最简单实现开始。晚些时候,当我需要增加或修改时,我将让这 \r\n个实现更加灵活、稳固。 \r\n这种使用模式的新方法是一种更好的方法。它节约了我的时间,并让我的设计更简单。 \r\n由于我继续学到更多关于XP 的知识,我很快开始考虑这样一个事实:那些清楚介绍“XP 是什么”和 \r\n“XP 如何工作”的人毫不提及模式。看起来,焦点已经全部从开发转向了重构。构造一点,测试一点,重 \r\n构一点,然后再重复。 \r\n那么,模式怎么了? \r\n我收到的一般的答案是:模式鼓励过分设计,而重构保持事情简单、轻量级。 \r\n现在,我和其他任何人一样喜欢重构——我回顾了Martin Fowler 的书的关于这个主题的两份手稿,然 \r\n后知道重构将成为一个标准。但我仍然喜欢模式,我发现模式在“帮助人们学会如何设计更好的软件”方 \r\n面是无价之宝。所以,XP 怎么能不包括模式呢?! \r\n我小心的在Portland Pattern Repository 上写下了我的不安。我问:是否完美的XP 模式应该由完全不知 \r\n道模式的程序员和指导者组成,是否他们应该完全依赖重构来“让代码去它该去的地方”。Ron Jeffries ,世 \r\n界上最有经验的XP 实践者,与我争论了这个主题,并且这样写: \r\n一个初学者不能倾听代码所说的话。他需要学习代码质量的模式(在一般意义上)。他需要一个初学者不能倾听代码所说的话。他需要学习代码质量的模式(在一般意义上)。他需要一个初学者不能倾听代码所说的话。他需要学习代码质量的模式(在一般意义上)。他需要一个初学者不能倾听代码所说的话。他需要学习代码质量的模式(在一般意义上)。他需要 \r\n看好的代码(以及,我猜,差的代码),这样他才能学会写出好的代码。\r\n一个问题,我的意思是一个可能的问题是,现在的模式是否被用于帮助提高代码的质。我想Beck 的Smalltalk Best Practice Patterns 会有帮助,因为那些都是非常小型的模式。我想会有帮助,因为那些都是非常小型的模式。设计模式都更值得怀疑,因为模式和讨论有时变得相当大,而且它们可能造成看起来合理的庞大设计模式都更值得怀疑解决方案。Martin Fowler 的精彩的分析模式也有同样的危险:在可以选择的精彩的分析模式也有同样的危险:在可以选择一个小规模解决方案的时候选择了大规模的解决方案。[Jeffries 99] \r\n一个非常有趣的关于模式的观点。尽管我已经看到模式可以被明智的实现、使用,但Ron 看起来却认 \r\n为它们是危险的,因为它们“让庞大的解决方案看起来合理”。在其他地方,Ron 观察了一件经常发生的事 \r\n情:第一次学习模式的人们如何过分渴望使用它们。 \r\n我无法不同意后面这个观察结果。就象任何新事物——甚至是XP ——一样,人们可能会过分渴望使 \r\n用它们。但模式真的鼓励在可以使用小规模解决方案时使用大规模解决方案吗? \r\n我想这主要取决于你如何定义、使用模式。举个例子,我观察了许多模式的初级使用者,他们认为一 \r\n个模式与它的结构图(或类图)是完全相同的。只有在我向他们指出“模式可以根据需要以不同的方式实 \r\n现”之后,他们才开始发现这些图只是表示实现模式的一种方式。 \r\n模式的实现有简单的也有复杂的。诀窍是:发现模式针对的问题,将这个问题与你当前的问题进行比 \r\n较,然后将这个模式最简单的实现(解决方案)与你的问题进行比较。当你这样做时,你就不会在可以使 \r\n用小规模解决方案的时候使用大规模解决方案。你获得了解决问题最好的平衡。 \r\n当人们没有受过模式的良好训练时,困难就可能出现。Ron 提到人们使用模式的方式是“现在构成的” \r\n——这就是说,他们如何与现在的作者沟通。我同意模式文献有一些缺点。关于模式的书很多,你可以花 \r\n一些时间来理解模式解决的问题,这样你就可以聪明的根据自己的特定需要选择模式。 \r\n这种选择是极其重要的。如果你选择了错误的模式,你可能过分设计或仅仅把你的设计揉在一起。有 \r\n经验的模式使用者也会犯错误,并且经常看到这样的结果。但这些专家有其他的模式作为装备,这些模式 \r\n可以帮助他们面对自己的错误。所以他们最终经常把自己真正需要的模式换成了不那么理想的模式。 \r\n那么,你将怎样成为一个有经验的模式使用者呢?我发现除非人们投身于大量模式的学习中,否则他 \r\n们就有可能陷入误解它们、过分使用它们以及用它们过分设计的危险之中。 \r\n但这是避免使用模式的一个原因吗? \r\n我想,不。我发现模式在如此多的项目中如此有用,以至于我无法想象不使用它们来进行软件设计和 \r\n开发。我相信对模式的彻底的学习是非常值得的。 \r\n那么,XP 对模式保持沉默是因为感觉到它们将被误用吗? \r\n如果情况是这样,也许问题已经变成:我们怎样使用模式中的智慧,而避免模式在我们怎样使用模式中的智慧,而避免模式在我们怎样使用模式中的智慧,而避免模式在我们怎样使用模式中的智慧,而避免模式在XP 开发场景中的开发场景中的开发场景中的开发场景中的 \r\n误用呢?误用呢?误用呢?误用呢? \r\n在这里,我想我必须回到《设计模式》。在“结论”一章、“设计模式将带来什么”一节、“重构的目 \r\n标”小节中,作者写道: \r\n我们的设计模式记录了许多重构产生的设计结构。在设计初期使用这些模式可以防止以我们的设计模式记录了许多重构产生的设计结构。不过即使是在系统建成之后才了解如何使用这些模式,它们仍可以教你如何修改你的后的重构。不过即使是在系统建成之后才了解如何使用这些模式,它们仍可以教你如何修改你的后的重构。设计模式为你的重构提供了目标。[GHJV2 95] \r\n这就是我们需要的观点:重构的目标。这就是重构和模式之间的桥梁。它完美的描述了我自己在如何 \r\n使用模式方面的进步:从简单开始,考虑模式但将它们保持在次要地位,小规模重构,只有在真正需要模 \r\n式的时候才把重构转移为模式。 \r\n这个需要训练和仔细判断的过程将很好的适应XP 所包含的最好的习惯。 \r\n而且这个途径很明显与“故意不知道或不使用模式而只依赖重构来改善设计”的方法非常不同。 \r\n只依赖重构的危险是:没有目标,人们可能使设计小小进步,但他们的全面设计将最终受损害,因为 \r\n这种方法缺乏顺序、简单性和效力,而聪明的使用模式则可以让开发者拥有这些。 \r\n引用Kent Beck 自己的话:模式生成体系结构模式生成体系结构模式生成体系结构模式生成体系结构。[Beck2 94] \r\n但模式不保证有纪律的使用。如果我们在设计中过多、过早的使用它们,我们就又回到了过分设计的 \r\n问题。因此,我们必须回答这个问题:“在设计的生命周期中,何时引入模式是安全的?”请回忆上面对 \r\n《设计模式》的引用: \r\n在设计初期使用这些模式可以防止以后的重构。在设计初期使用这些模式可以防止以后的重构。在设计初期使用这些模式可以防止以后的重构。在设计初期使用这些模式可以防止以后的重构。 \r\n这是一个聪明的主张。如果我们不知道“何时配置一个模式”的基本规则,那么我们就很容易在设计 \r\n周期的早期就陷入过分设计。 \r\n再一次,问题又全部集中在一起:如何将项目中的问题与一个合适的模式相匹配。 \r\n在这里,我必须讲述我为不同行业开发软件得到的经验。 \r\n有一家客户要求我和我的团队用J AVA 为他们的网站构造软件,这将是一个很酷的交互式版本。这个 \r\n客户没有任何J AVA 程序员,但仍然要求能在他们需要的任何时候、任何地方修改软件的行为,而不必做程 \r\n序的修改。多么高的要求! \r\n在对他们的需要做了一些分析之后,我们发现Command 模式将在这个设计中扮演一个非常重要的角 \r\n色。我们将编写命令对象,并让这些命令对象控制软件的整个行为。用户将可以参数化这些命令、将它们 \r\n排序、并选择命令运行的时间和地点。 \r\n这个解决方案工作得很完美,Command 模式正是成功的关键。所以在这里,我们不会等到重构的时候 \r\n才使用Command 模式。相反,我们预先看到了使用它的需要,并从一开始就用Command 模式来设计软件。 \r\n在另一个项目中,系统需要作为独立应用程序和WEB 应用程序运行。Builder 模式在这个系统中发挥了 \r\n巨大的作用。如果没有它,我不敢想象我们会拼凑出一个多么臃肿的设计。Builder 模式的作用就是解决“多 \r\n平台、多环境运行”这样的问题。所以在设计早期就选择它是正确的。 \r\n现在,我必须声明:即使在设计的早期引入了模式,但一开始仍然应该按照它们最原始的样子来实现 \r\n它们。只有在晚些时候,当需要附加的功能时,模式的实现才能被替换或升级。 \r\n一个例子会让你更清楚这一点。 \r\n上面提到的由命令对象控制的软件是用多线程的代码实现的。有时候两个线程会使用同一个宏命令来 \r\n运行一系列命令。但一开始我们并没有被宏命令的线程安全问题困扰。所以,当我们开始遇到线程安全造 \r\n成的莫名其妙的问题时,我们必须重新考虑我们的实现。问题是,我们应该花时间构造宏命令的线程安全 \r\n吗?或者有没有更简单的方法来解决这个问题? \r\n我们用更简单的方法解决了这个问题,并且避免了过分设计:为每个线程提供一个独立的宏命令实例。 \r\n我们可以在30 秒内实现这个解决方案。请把这个时间与设计一个线程安全的宏命令所需的时间做一下比 \r\n较。 \r\n这个例子描述了XP 的哲学怎样在使用模式的情况下保持事情简单。没有这种简单化的驱动,过分设 \r\n计的解决方案——就象线程安全的宏命令——很容易出现。 \r\n因此,简单化和模式之间的关联是很重要的。 \r\n当程序员需要做出设计决策时,很重要的一件事就是:他们应该试图保持设计简单,因为简单的设计 \r\n通常比庞大而复杂的设计更容易维护和扩展。我们已经知道,重构意味着将我们保持在简单的路上:它鼓 \r\n励我们以小而简单步骤逐渐改进我们的设计,并避免过分设计。 \r\n但是模式呢?难道它们不是帮助我们保持简单吗? \r\n有些人会说“不”。他们认为模式尽管有用,但容易造成复杂的设计。他们认为模式会造成对象快速 \r\n增加,并导致过分依赖对象组合。 \r\n这种观点是由于对使用模式的方法的错误理解。有经验的模式使用者会避免复杂的设计、对象的快速 \r\n增长和过多的对象组合。 \r\n实际上,在使用模式的时候,有经验的模式使用者会让他们的设计更简单。我将再用一个例子来说明 \r\n我的观点。 \r\nJUnit 是一个简单而有用的J AVA 测试框架,它的作者是Kent Beck 和Erich Gamma 。这是一个精彩的软 \r\n件,其中满是精心选择的简单的模式。 \r\n最近一些人要求我对JUnit 进行DeGoF ,也就是说,将JUnit 中的设计模式移除掉,以观察没有模式的 \r\nJUnit 是什么样子。这是一次非常有趣的练习,因为它让参与者认真考虑应该在什么时候在系统中引入模式。 \r\n为了描述他们学到的东西,我们将对JUnit 2.1 版中的一些扩展进行DeGoF 。 \r\nJUnit 中有一个叫做Test Case 的抽象类,所有的具体测试类都派生自它。TestCase 类没有提供任何多次 \r\n运行的方法,也没有提供在自己的线程中运行测试的方法。Erich 和Kent 用Decorator 模式很优雅的实现了可 \r\n重复测试和基于线程的测试。但是如果设计团队不知道Decorator 模式呢?让我们看看他们会开发出什么, \r\n并评估一下他们的设计有多简单。 \r\n这是Test Case 在JUnit 框架1.0 版本中的样子(为了简化,我们忽略了注释和很多方法): \r\n[code]\r\npublic abstract class TestCase implements Test { \r\nprivate String fName; \r\npublic TestCase(String name) { \r\nfName= name; \r\n} \r\npublic void run(TestResult result) { \r\nresult.startTest(this); \r\nsetUp(); \r\ntry { \r\nrunTest(); \r\n} \r\ncatch (AssertionFailedError e) { \r\nresult.addFailure(this, e); \r\n} \r\ncatch (Throwable e) { \r\nresult.addError(this, e); \r\n} tearDown(); \r\nresult.endTest(this); \r\n} \r\npublic TestResult run() { \r\nTestResult result= defaultResult(); \r\nrun(result); \r\nreturn result; \r\n} \r\nprotected void runTest() throws Throwable { \r\nMethod runMethod= null; \r\ntry { \r\nrunMethod= getClass().getMethod(fName, new Class[0]); \r\n} catch (NoSuchMethodException e) { \r\ne.fillInStackTrace(); \r\nthrow e; \r\n} \r\ntry { \r\nrunMethod.invoke(this, new Class[0]); \r\n} \r\ncatch (InvocationTargetException e) { \r\ne.fillInStackTrace(); \r\nthrow e.getTargetException(); \r\n} \r\ncatch (IllegalAccessException e) { \r\ne.fillInStackTrace(); \r\nthrow e; \r\n} \r\n} \r\npublic int countTestCases() { \r\nreturn 1; \r\n} \r\n} \r\n[/code]\r\n新的需求要求允许测试重复进行、或在它们各自的线程中进行、或以上两者。 \r\n没有经验的程序员通常在遇到这样的新需求时进行子类型化。但是在这里,因为知道TestCase 对象将 \r\n需要能够在同一个线程中重复运行、或在各自独立的线程中重复运行,所以程序员知道:他们需要考虑得 \r\n更多。 \r\n一种实现方法是:将所有的功能都添加给TestCase 本身。许多开发者——尤其是那些不了解设计模式 \r\n的开发者——将会这样做,而不考虑这会使他们的类变得臃肿。他们必须添加功能,所以他们将功能添加 \r\n到任何可以添加的地方。下面的代码可能就是他们的实现: \r\n[code]\r\npublic abstract class TestCase implements Test { \r\nprivate String fName; \r\nprivate int fRepeatTimes; \r\npublic TestCase(String name) { \r\nthis(name, 0); \r\n} \r\npublic TestCase(String name, int repeatTimes) { \r\nfName = name; \r\nfRepeatTimes = repeatTimes; \r\n} \r\npublic void run(TestResult result) { \r\nfor (int i=0; i < fRepeatTimes; i++) { \r\nresult.startTest(this); \r\nsetUp(); \r\ntry { \r\nrunTest(); \r\n} \r\ncatch (AssertionFailedError e) { \r\nresult.addFailure(this, e); \r\n} \r\ncatch (Throwable e) { \r\nresult.addError(this, e); \r\n} \r\ntearDown(); \r\nresult.endTest(this); \r\n} \r\n} \r\npublic int countTestCases() { \r\nreturn fRepeatTimes; \r\n} \r\n} \r\n[/code]\r\n请注意run (TestResult result )方法变大了一些。他们还为TestCase 类添加了另外的构造子。到目前为 \r\n止,这还不算什么大事。并且,我们可以说:如果这就是所有必须做的事情,那么使用Decorator 模式就是 \r\n多余的。 \r\n现在,如果要让每个TestCase 对象在其自己的线程中运行又怎样呢?这里也有一个可能的实现: \r\n[code]\r\npublic abstract class TestCase implements Test { \r\nprivate String fName; \r\nprivate int fRepeatTimes; \r\nprivate boolean fThreaded; \r\npublic TestCase(String name) { \r\nthis(name, 0, false); \r\n} \r\npublic TestCase(String name, int repeatTimes) { \r\nthis(name, repeatTimes, false); \r\n} \r\npublic TestCase(String name, int repeatTimes, boolean threaded) { \r\nfName = name; \r\nfRepeatTimes = repeatTimes; \r\nfThreaded = threaded; \r\n} \r\npublic void run(TestResult result) { \r\nif (fThreaded) { \r\nfinal TestResult finalResult= result; \r\nfinal Test thisTest = this; \r\nThread t= new Thread() { \r\npublic void run() { \r\nfor (int i=0; i < fRepeatTimes; i++) { \r\nfinalResult.startTest(thisTest); \r\nsetUp(); \r\ntry { \r\nrunTest(); \r\n} \r\ncatch (AssertionFailedError e) { \r\nfinalResult.addFailure(thisTest, e); \r\n} \r\ncatch (Throwable e) { \r\nfinalResult.addError(thisTest, e); \r\n} tearDown(); \r\nfinalResult.endTest(thisTest); \r\n} \r\n} \r\n}; \r\nt.start(); \r\nresult = finalResult; \r\n} else { \r\nfor (int i=0; i < fRepeatTimes; i++) { \r\nresult.startTest(this); \r\nsetUp(); \r\ntry { \r\nrunTest(); \r\n} \r\ncatch (AssertionFailedError e) { \r\nresult.addFailure(this, e); \r\n} \r\ncatch (Throwable e) { \r\nresult.addError(this, e); \r\n} tearDown(); \r\nresult.endTest(this); \r\n} \r\n} \r\n} \r\npublic int countTestCases() { \r\nreturn fRepeatTimes; \r\n} \r\n} \r\n[/code]\r\n唔,这看起来开始变得更坏了。为了支持两个新的特征,我们现在拥有了三个构造子,而且run \r\n(TestResult result )方法的大小迅速的膨胀起来。 \r\n即使不管所有这些新代码,我们这些程序员还没有满足这些需求:我们仍然不能在各自的线程中重复 \r\n运行测试。为了这个目的,我们必须添加更多的代码。算了,我就放过你吧。 \r\n重构可以帮助这些代码减小尺寸。但是只需要稍做思考:如果再接到一个新的需求,我们要怎么办? \r\n现在JUnit 3.1 支持四种不同的TestCase 修饰器,它们可以轻松的随意组合以获取所需的功能。同时,JUnit \r\n的实现仍然简单——没有混乱的代码。这种设计保持Test Case 类的简单、轻量级,用户只需要在需要的时 \r\n候对TestCase 对象进行装饰即可,而且可以选择任何组合顺序。 \r\n很清楚,这是一个模式帮助简化设计的例子。这个例子也说明了缺乏经验的开发者怎样改善他们的设 \r\n计——如果他们知道模式指出的重构目标。 \r\n使用模式来开发软件是聪明之举,但如果你缺乏使用模式的经验,它也可能是危险的。出于这个原因, \r\n我极力提倡模式学习组。这些学习组让人们在同伴的帮助下稳步前进而精通模式。 \r\n当人们了解模式并以受过训练的方式使用它们时,模式是最有用的——这种受过训练的方式就是XP \r\n的方式。以XP 的方式使用模式鼓励开发者保持设计的简单、并完全根据需要对模式进行重构。它鼓励在设 \r\n计早期使用关键的模式。它鼓励将问题与能帮助解决问题的模式相匹配。最后,它鼓励开发者编写模式的 \r\n简单实现,然后根据需要发展它们。 \r\n在XP 的场景中,模式的确更有用;而在包含对模式的使用时,XP 开发则更有可能成功。 \r\n参考书目参考书目参考书目参考书目 \r\n[no]\r\n[Beck1 00] Beck, Kent. Email on extremeprogramming@egroups.com, January 2000. \r\n[Beck2 94] Patterns Generate Architectures, Kent Beck and Ralph Johnson, ECOOP 94 \r\n[GHJV1 95] Design Patterns: Elements of Reusable Object-Oriented Software, by Erich Gamma, Richard \r\nHelm, Ralph Johnson and John Vlissides. 中译本:《设计模式:可复用面向对象软件的基础》,李英军等译。 \r\n[GHJV2 95] Design Patterns: Elements of Reusable Object-Oriented Software, by Erich Gamma, Richard \r\nHelm, Ralph Johnson and John Vlissides. Pages 353-354 中译本:《设计模式:可复用面向对象软件的基础》, \r\n李英军等译,第6 章。 \r\n\r\n[Jeffries 99] Jeffries, Ron. Patterns And Extreme Programming. Portland Pattern Repository. December, \r\n1999 \r\n[Kerth 99] Kerth, Norm. Conversation, circa March, 1999. \r\n[Kerievsky 96] Kerievsky, Joshua. Don’t Distinguish Between Classes And Interfaces. Portland Pattern \r\n[/no]\r\nRepository. Circa 1996 ','浆糊','2002-02-20 21:12:25','2002-02-20 21:12:25',0,'192.168.1.228',155),('webpm_wiki.用户故事.v1.2','\'\'\'webpm_wiki.用户故事.v1.2\'\'\'\r\n\'\'说明: 1d 表示为1个标准工作日,(1) 表示故事的优先级。\'\'\r\n----\r\n1、查阅备份文章 \'\'已完成\'\'\r\n可以查看备份的文章版本的内容。\r\n \r\n2、恢复备份的文章 \'\'已完成\'\'\r\n在管理程序界面指定要恢复的文章号。覆盖当前文章库的内容。\r\n\r\n3、wiki 页面的皮肤支持 3d (2) \'\'此故事暂停,等待MVC模式的Spike完成后继续。\'\'\r\n允许通过配置设定wiki正文区使用的样式,以及标题区、导航区、页脚区的内容和样式。\r\n\r\n4、查阅用户信息 1d (1) \'\'已完成\'\'\r\n点击用户名,查看用户相关的信息。(使用同步的用户文章)。用户信息标记[no][user=BrokenDoor][/no]\r\n\r\n5、注册用户列表 0.5d (1) \'\'已完成\'\'\r\n显示已注册的用户列表,点击列表项查看相应的用户文章。\r\n\r\n6、用户发帖排行榜 1d (2) \'\'已完成\'\'\r\n显示前20位发帖数最多的用户的列表\r\n\r\n7、用户专集 \'\'已完成\'\'\r\n7.1 显示由指定用户创建的文章列表 1d (1) \'\'已完成\'\'\r\n7.2 显示由指定用户修改过的文章列表 1d (2) \'\'此故事取消\'\'\r\n\r\n8、注册项目 2d (1) \'\'已完成\'\'\r\n已登录的用户可以注册新的项目,输入项目相关的信息。(名称、描述等)\r\n\r\n9、项目主页 \r\n根据项目信息创建项目相关的wiki页,可以使用预定义模板。\r\n9.1 Wiki 预定义模板 2d (1)\r\n 在数据库中保存供生成wiki页使用的模板。 使用类似于{project.name}标记获取项目信息的实际内容。\r\n\r\n9.2 自动创建项目主页 2d (2)\r\n 根据模板和项目注册信息自动生成项目主页。项目信息标记[no][project=WebPM][/no]\r\n\r\n10、项目成员 1d (1) \'\'已完成\'\'\r\n项目管理员添加用户到项目成员列表。\r\n\r\n11、安装程序 2d (1) \'\'此故事取消\'\'\r\n提供web界面的安装程序,可以设置数据库配置,以及平台中文编码.\r\n\r\n----\r\n分类: [WebPM] | [webpm_wiki]','BrokenDoor','2002-02-21 20:19:01','2002-03-03 20:31:45',0,'BrokenDoor',152),('蓝星','[user=bluestar]\r\n\r\n原来以为自己很聪明了,结果现在感觉自己... ...\r\n我这么帅,怎么把自己的照片放上了... ...','202.106.162.162','2002-02-21 23:30:33','2002-02-25 11:32:53',0,'202.106.162.162',156),('帮助','Q: \'\'\'我安装之后出现了中文乱码,怎么处理?\'\'\'\r\nA: 在不同的平台需要设置不同的中文编码,可以在config.xml中设置. [浆糊]','浆糊','2002-02-22 08:26:26','2002-02-22 08:26:26',0,'BrokenDoor',157),('WebService java实现','教学文章:\r\nSOAP的全称是Simple Object Access Protocol,不是洗手用的 :) .传统的RPC的不足之处就是传输过程中的数据编码问题,xml的出现解决了这个问题.用XML封装,通过Http,调用远程对象的方法,可以实现平台无关、语言无关。\r\n关于这个方面的介绍很多,我就不多说了,让我们开始吧,第一块肥皂...\r\n实现平台 win2000p+Apache SOAP+resin\r\n\r\n\'\'\'(1)服务端\'\'\'\r\n[code]\r\npackage demo;\r\n\r\n/**\r\n* Title:SOAP\r\n* Description: 浆糊作品\r\n* Copyright: Copyright (c) 2001\r\n* Company:\r\n* @author 一桶浆糊\r\n* @version 1.0\r\n*/\r\n/**\r\n* 为其它的客户提供服务\r\n*/\r\npublic class Hello {\r\n\r\n public Hello() {\r\n }\r\n /**\r\n * 返回一个问候字符串\r\n * @param name 问候人名字\r\n */\r\n public String getHello(String name){\r\n return \"Hello ,\"+name;\r\n }\r\n}\r\n[/code]\r\n编译,然后放到SOAP目录下(见安装文章).好了,这就完成了我们的服务端了.提供了一个getHello的方法,可供客户调用,接下来我们就开始享受这块肥皂吧..\r\n\r\n[code]\r\n\'\'\'(2)客户端\'\'\'\r\n程序中做了很多的注释,看起来应该不会太困难,我就不多说了.\r\npackage demo;\r\n\r\n/**\r\n* Title:SOAP\r\n* Description: 浆糊作品\r\n* Copyright: Copyright (c) 2001\r\n* Company:\r\n* @author 一桶浆糊\r\n* @version 1.0\r\n*/\r\nimport org.apache.soap.*;\r\nimport org.apache.soap.rpc.*;\r\nimport java.util.*;\r\nimport java.net.URL;\r\npublic class HelloClient {\r\n\r\n public HelloClient() {\r\n }\r\n public static void main( String[] args ) throws Exception\r\n {\r\n URL url = new URL( \"http://localhost:8080/soap/servlet/rpcrouter\" );\r\n String urn = \"urn:demo:helloworld\"; //服务器名称,在部署的时候自己定义\r\n\r\n Call call = new Call(); // 准备调用web service\r\n call.setTargetObjectURI( urn );\r\n call.setMethodName( \"getHello\" );\r\n call.setEncodingStyleURI( Constants.NS_URI_SOAP_ENC );\r\n Vector params = new Vector();\r\n //设置接口参数\r\n params.addElement( new Parameter(\"aUserName\", String.class, \"浆糊\", null ) );\r\n call.setParams( params );\r\n\r\n try\r\n {\r\n System.out.println( \"invoke service\\n\" + \" URL= \" + url + \"\\n URN =\" + urn );\r\n Response response = call.invoke( url, \"\" ); // 进行调用\r\n\r\n if( !response.generatedFault() ) //是否产生错误\r\n {\r\n Parameter result = response.getReturnValue(); // 取得返回值\r\n \r\n System.out.println( \"Result= \" + result.getValue() );//哇!,成功了\r\n }\r\n else\r\n {\r\n Fault f = response.getFault(); // 得到一个错误\r\n System.err.println( \"Fault= \" + f.getFaultCode() + \", \" + f.getFaultString() );\r\n }\r\n }\r\n catch( SOAPException e ) // 捕获异常\r\n {\r\n System.err.println( \"SOAPException= \" + e.getFaultCode() + \", \" + e.getMessage() );\r\n }\r\n }\r\n}\r\n\r\n\r\n[/code]\r\n\r\n\'\'\'(3)Web Service的部署\'\'\'\r\n/**\r\n* Title:SOAP\r\n* Description: 浆糊作品\r\n* Copyright: Copyright (c) 2001\r\n* Company:\r\n* @author 一桶浆糊\r\n* @version 1.0\r\n*/\r\n启动resin( tomcat一样),进入http://localhost:8080/soap/admin/==>Deploy\r\n具体的参数如下:\r\nID=urn:demo:helloworld \r\nScope=Request \r\nProvider Type=java \r\nProvider Class=demo.Hello \r\nUse Static Class=false \r\nMethods=getHello \r\n然后确定就可以,你可以看到发布成功的反馈信息.运行 java demo.HelloClient ,如果看到hello,xxx,恭喜你,你已经完成了第一个soap.确保所有的类在classpath中.\r\n教学(-)完','浆糊','2002-02-26 23:43:17','2002-02-26 23:43:17',0,'浆糊',170),('WabiSabi','测试测试\r\n\r\n页面可以开放给任何用户修改?\r\n\r\nwho knows!\r\n\r\nWabiSabi','61.152.125.82','2002-02-22 11:24:03','2002-07-26 14:12:57',0,'172.16.1.215',159),('扫地的癞蛤蟆','[user=ymruan]\r\n哈哈,这个名字是我当初在学校的bbs\"笑书亭\"上的nickname.\r\n\r\n硬件:C51编程,FPGA编程(精通HDL)etc. 熟悉液晶模块。etc\r\n\r\n软件:java,basic,c,asp,jsp,Flash(actionscript),director. etc\r\n\r\n爱好:摇滚乐\r\n\r\n在学校的寝室\r\n[img]http://www.loveproxy.com/photo/421710/morephoto/60553.jpg[/img]\r\n\r\n和现在的同事去苏州乐园玩\r\n\r\n[img]http://www.loveproxy.com/photo/421710/morephoto/148546.jpg[/img]\r\n\r\n\r\n','ymruan','2002-02-22 11:40:30','2002-02-26 17:29:48',1,'ymruan',160),('搜索','在这里编辑文章内容...斯蒂芬\r\n斯多夫斯蒂芬','浆糊','2002-02-25 09:36:48','2002-02-25 09:38:15',0,'浆糊',161),('速度','在这里编辑文章内容...斯多夫死的','浆糊','2002-02-25 09:38:37','2002-02-25 09:38:37',0,'浆糊',162),('webpm源码分析','有什么问题?\r\n\r\n-----\r\n可以讲一下jwiki中整体的设计思路吗?\r\n-----\r\n','浆糊','2002-02-25 12:49:25','2002-03-11 17:17:28',0,'takaka',163),('WebpmWhiteBoard','我做过一个电子白板,用的是集中式的结构,因为是做为论文写的,所以自己感觉其中的[并发控制算法]还是写的不错的。而且对于通信方面也参考了不少的IEEE的论文,[实时性]也不错。能嘿嘿,有空贡献出来给大家把:)\r\n如果要做,下阶段主要想作成是[p2p]的方式,用[xml]来做通信。呵呵\r\n----\r\n贴出来大家娱乐一下!\r\n----\r\n非常感谢,期待下文! BrokenDoor - 2002/2/27\r\n\r\n\r\n----\r\n分类: [WebPM] | [webpm_net]\r\n\r\n-----\r\n贴什么出来?文章还是代码?代码比较大,没整理,有10mb多,在家里的电脑上,用猫的,吃不消上载啊,至少要整理整理再说啊.有20000多行的样子.\r\n----\r\n\'\'20000多行怎么会有10mb多呢?\'\'\r\n\'\'\'图片\'\'\'\r\n-----\r\n当然是文章!\r\n\r\n-----------------\r\n好的,不过现在不行,我在公司\r\n-----------------\r\n\r\n','ymruan','2002-02-26 17:58:44','2002-02-28 20:11:12',0,'61.171.86.207',165),('test','空的用户、空的密码\r\n[project=test]','takaka','2002-02-25 23:10:48','2002-02-28 10:17:55',0,'BrokenDoor',164),('并发控制算法','最土的一种是用令牌环拉,哈哈。','ymruan','2002-02-26 17:59:34','2002-02-26 17:59:34',0,'ymruan',166),('Open Source 的开发模式探讨','现有的成功的Open Source 开发模式可以从两个方面来分析,首先我们来看 \r\n看单个软件的开发模式,再分析Linux 发行版本的开发模式。 \r\n\r\n现有的单个软件的 Open Source开发模式: \r\n1. 小型OpenSource软件开发模式 \r\n\r\n典型实例:Linux Virtual Server Project(www.linuxvirtualserver.org) \r\n其特点为项目的核心开发人员很少,一般为1-2 名,核心开发人员承担主要 \r\n的开发工作和维护相应的网站,用户会提出错误报告和提供少量的错误修正。 \r\n\r\n一般很少采用CVS 来进行代码管理,而是定期发布新版本。一般没有明确的 \r\n开发计划和日程安排,其软件更新速度和质量取决于核心开发人员的投入程度和 \r\n水平。目前采用这种开发模式的GNU 软件最多。而SourceForge.net 的出现又简 \r\n化了这部分开发人员的重复工作。 \r\n\r\n2. 中型Open Source软件开发模式 \r\n\r\n典型实例:GTK (www.gtk.org ) \r\n\r\n其特点为拥有3-5 名核心维护人员,参与开发的人员10人-40 人之间,采用 \r\nCVS 进行代码管理,通过maillist/irc进行开发交流,有明确的开发计划和日程。 \r\n\r\n用户提出的错误报告和修正数量很多,并且有一些分支产生。 \r\n\r\n3. 完全封闭的商业Open Source软件 \r\n典型实例:QT(www.trolltech.com ) \r\n\r\n其特点为软件完全由商业公司内部开发,用户一般只能提供错误报告,不提 \r\n供修复补丁,公司定期发布新版本的源代码。其好处是软件质量水平较高,其缺 \r\n点是如果公司开发力量不足,软件发展容易停滞不前。 \r\n\r\n4. 比较封闭的大型Open Source软件的开发 \r\n\r\n典型实例:XFree86 (www.xfree86.org ) \r\n\r\n其特点为拥有数十名核心开发人员(一般不超过100 名),其中包括3-5 位 \r\n核心开发人员,只有这些核心开发人员有权提交代码,代码使用CVS 管理,但是 \r\n对外界不开放只有在发布新版本时外界才可以得到,开发计划和日程明确,发布 \r\n日期一般准确,但是软件版本升级速度一般比较缓慢。这样开发的好处是代码质 \r\n量比较平均,所受干扰小,缺点是由于用户不能积极参与开发过程中的测试工作, \r\n增加新功能后稳定期较长。 \r\n\r\n5. 由商业软件转化过来的大型Open Source软件开发. \r\n\r\n典型实例:OpenOffice(www.openoffice.org) \r\n\r\nMozilla (www.mozilla.org ) \r\n\r\n其特点为其软件计划开始时是基于一个被 Open Source的商业软件,一般都 \r\n受到原商业公司的控制,一般都不采用GPL/BSD 形式的License ,一般都采用类 \r\n似于MPL (Mozilla Public License)的版权,其特点是公司可以享有使用这些 \r\n源代码的权利,他们的开发工作一般由公司的员工为核心开发人员和领导者,通 \r\n过CVS 和Bugzilla进行代码和错误管理。拥有正式的QA体系,这种模式一般都进 \r\n展不是很快,例如mozilla 三年多仍然不能发布1.0 版。主要原因是这种由于这 \r\n些大型软件开发的起点比较高,因此自由软件程序员加入的数量都不是很多,还 \r\n有就是由于商业软件公司的背景,使得部分自由程序员不太愿意加入。但是参与 \r\n测试的最终用户比较多。 Mozilla的下载量一般都在数十万左右。而修复的错误 \r\n数目也同比增长 \r\n\r\n6. \"独裁\"式的大型Open Source软件的开发. \r\n\r\n典型实例:Kernel(www.kernel.org) \r\n\r\n其特点为软件开发人员非常多,一般都在百人以上,任何自由程序员都可以 \r\n提交自己的修改工作,但是只有领导者(在Linux 核心上是Linus 和Alan Cox) \r\n才能够合并这些工作到正式的核心发布版本中。而且他们一般不采用CVS ,只是 \r\n通过maillist来进行项目管理,交流,错误报告。经常发布新的版本,其好处是 \r\n软件更新速度和发展速度很快,计划的开放性好,由于最终裁决人只有少数非常 \r\n有经验的程序员,正式发布的代码质量非常优秀,由于用户数目非常庞大,最终 \r\n发布版的错误一般都非常稀少。这种方式的缺点是计划的发展方向主要由核心开 \r\n发人员决定,体现他们的设计思想。不过这个缺点从另外一个角度来说这些核心 \r\n领导者的远见决定了工程的技术领先性。 \r\n\r\n7. \"民主\"式的大型Open Source 软件的开发. \r\n\r\n典型实例:Gnome (www.gnome.org ) \r\n\r\nKDE (www.kde.org ) \r\n\r\n其特点为核心开发人员数目较多,子软件计划非常多,利用CVS 进行代码管 \r\n理,核心开发小组一般在百人以上,分成若干个小组,每个小组有1-2 个领导者, \r\n权限比较分明,有明确的开发进度管理和日程安排,有严密的Alpha ,Beta,RC1 \r\n,RC2测试阶段。主要开发者定期召开开发者大会,讨论开发中的问题和新版本的 \r\n设计。拥有自己的开发文档库和编码/ 测试标准。 \r\n\r\n同商业软件公司一样,一般每隔半年左右推出一个正式版本。这种方式是目 \r\n前效率最高的一种方式,也只有这种开发模式能够承担利用Internet协作开发KDE/Gnome \r\n这种超大型套装软件的开发工作。 \r\n\r\n现有的Linux 发行版本的开发模式: \r\n\r\n1. 完全封闭式 \r\n\r\n典型实例:Caldera (www.caldera.com ) \r\n\r\n其特点为完全由公司内部程序员封闭开发,在正式产品前不发布任何测试版 \r\n本,其缺点式显而易见的,主要体现在产品开发周期长,用户参与不足。质量完 \r\n全取决于公司内部的开发管理水平和实力。 \r\n\r\n2. 半封闭式 \r\n\r\n典型实例RedHat(www.redhat.com) \r\n\r\n其特点为产品在Beta阶段推出1-2 个测试版本,然后推出正式版本。 RedHat \r\n内部的开发制度是目前把Open Source 开发模式和传统软件的开发模式结合得比 \r\n较好的一种,其特点是:公司将技术研发部门和生产部门交叉组合起来,技术研 \r\n发部门的管理比较松散,其下拥有一批技术上非常领先的自由程序员,主要负责 \r\n进行技术研发和前瞻性研究,而生产部门采用企业化的项目管理制度,这样的好 \r\n处是既保持了产品的质量,又保持了技术上的领先地位。而且能够保守一部分技 \r\n术秘密。缺点是没有强大的研发实力,是没有办法承担这种开发模式的。 \r\n\r\n3. 全开放式. \r\n典型实例Mandrake(www.mandrake.com) \r\n\r\nDebian(www.debian.org) \r\n\r\n其特点是其开发阶段完全向用户开放,随时接受用户的错误报告,内部只维 \r\n持一支相对较少的开发队伍进行管理和重点程序的攻关工作。其特点是开发速度 \r\n快,质量稳定,能够最大限度地利用Open Source 社区的力量。缺点是不容易控 \r\n制开发周期。 \r\n\r\n\r\n* 如何将Open Source 开发模式同传统开发模式结合起来 \r\n\r\nOpen Source 的开发模式的优点是在向Open Source 社区贡献代码的同时, \r\n得到了大批的免费开发人员和测试人员,这是一般的Close-Source公司无法得到 \r\n的。 \r\n\r\n但是由于Open Source 开发模式基于Internet和松散的自由程序员而造成不 \r\n便管理的缺点,需要这些公司建立起完善的项目管理,质量测试,进度控制等传 \r\n统开发模式中行之有效的管理模式,同Open Source 社区相合作,才有可能建立 \r\n起一个良性的发展制度。 \r\n\r\n* 在中国Open Source 开发模式的现状和前景。 \r\n\r\n\r\n目前在中国,Open-Source 越来越受到大家的重视,也开始有第一批基于Open-Source \r\n的公司出现,如红旗Linux ,TurboLinux,深圳Pocketix公司等。但是可以说, \r\n目前OpenSource在中国的发展还处于早期阶段,其特征在于: \r\n\r\n1.没有形成一个自由程序员阶层. \r\n\r\n目前中国的程序员数量并不少,看看在www.csdn.net上的文章和大量涌现的 \r\n共享软件的数目就可以估计出来,而自由程序员却寥寥无几,目前在国际上有影 \r\n响的自由软件计划中由中国人带队的只有LVS (Linux Virtual Server,章文嵩) \r\nLIDS(Linux Intrusion Detection System谢华刚)还有 MiniGUI ( MiniGUI, \r\n蓝点公司魏永明),SBM(Smart Boot Manager,苏哲)四个,其原因可以归结为下 \r\n面几条: \r\n\r\n* 中国程序员目前的经济情况还处于温饱状态,还必须为自己的生计奔波, \r\n因此不能投注更多精力在自由软件的开发。 \r\n\r\n* 中国程序员不熟悉自由软件开发的通行模式。一般表现为受传统开发的手 \r\n工作坊模式影响,不习惯合作开发,对管理一个项目的经验不足。 \r\n\r\n* 基于Unix系统的程序员不多,由于自由软件大多数是基于Linux/Unix系统, \r\n而在中国由于种种原因,Windows 程序员占绝大多数。 \r\n\r\n\r\n2.没有形成完整的自由软件社区 \r\n\r\n国外的自由软件社区包括slashdot.org这样的论坛,freshmeat.net 这样的 \r\n软件下载基地,sourceforge.net 这样的软件计划基地,而且有自己的Linux 杂 \r\n志,如Linux Journal 等等。而目前,在国内,已经有了freesof.cei.gov.cn, \r\nLinuxforum, Linuxaid 等论坛和下载基地,也有一些刚刚创办的Linux 杂志, \r\n但是总体而言,社区的力量和影响还是很小,表现在对媒体和大众的影响不大。 \r\n\r\n3.Open Source的公司对如何利用和回馈自由软件社区的力量了解不足 \r\n\r\n这基本表现在国内Open Source 公司的开发过程基本还遵循传统软件公司的 \r\n封闭开发,内部测试步骤,不能利用自由软件的开放式的开发过程。 \r\n\r\n此外中国的盗版软件横行,知识产权法的推广不力,个人版权意识淡漠也造 \r\n成了在中国单纯模仿外国的Open Source 公司的模式是完全行不通的,目前在中 \r\n国做单纯的Open Source 的公司是非常困难的,但是制作Linux 发行版的厂商和 \r\n硬件产商以及一部分嵌入式厂商是可以尝试使用 Open Source同传统开发模式相 \r\n结合的方式来进行开发工作的,因为对这部分厂商来说,软件盗版对他们的伤害 \r\n不像普通软件公司那么大,而利用Open Source 的开发模式,他们可以起到占领 \r\n市场份额,扩大公司影响力,提高软件开发速度和质量,了解用户需求的作用。 \r\n\r\n但是从实际中看,国内的Open Source 公司都还处在比较初级的阶段,利用 \r\nCVS 进行代码管理,maillist进行用户和开发者交流,bugzilla进行错误追踪的 \r\n公司基本没有。 \r\n\r\n更不用说领导Open Source 软件计划。 \r\n\r\n但实际上不足也正是机会,国内率先同国际接轨,采用Open Source 开发模 \r\n式的公司一定能从这种先进的开发模式中获得很大的帮助,但是千万要结合自身 \r\n情况,不要搞面子工程,要把工作做到实处,这样才有可能获得进步。\r\n\r\n----\r\n\'\'作者是浆糊?\'\'\r\nA:不是,转载而已 [浆糊]','浆糊','2002-02-26 19:11:48','2002-02-26 23:14:35',0,'浆糊',167),('cscw','cscw就是计算机协同工作,workflow,groupware和电子白板什么的都是属于cscw的范畴,哈哈,灌水一篇,有力气的帮忙补充','ymruan','2002-02-26 20:11:42','2002-02-26 20:11:42',0,'ymruan',168),('随便聊聊','大家可以在这里随便聊聊,不过请以新建页面形式组织讨论!\r\n----\r\n[Kert的胡言乱语]\r\n----','kert','2002-02-27 08:59:24','2002-02-27 09:00:26',0,'kert',171),('Kert的胡言乱语','破门,这个东西真的很不错,不过你是否考虑过怎样使用它?\r\n我觉得人气不够!\r\n内容太单一!\r\n在我看来Wiki更多是一个行为上的新事物,而不是技术!\r\n它展现了一个很有趣的应用,人们可以很自由的合作。无论是形式还是内容!(Web Wiki在形式上有所限制)。\r\n如何真正发挥Wiki的威力呢?\r\n我有一个建议不知是否可行?\r\n就是在我们的(你们的)的WebWiki上开辟一个栏目,用来翻译外文的资料,就像在potion的网站上一起翻译xp的文章一样。\r\n不知如何?\r\n第一个对象可以使波兰模式库!:)\r\n[浆糊]:好啊,不过还是需要有人参加和进行有效的组织.用wiki进行这样的工作再合适不过了 :)\r\n----\r\njust do it \r\n[资料翻译]\r\n----','kert','2002-02-27 09:06:04','2002-03-01 15:38:42',0,'panhwa',172),('jdo','见:[JDO]','takaka','2002-02-27 22:31:32','2002-03-05 23:25:43',0,'浆糊',173),('有你可思','我对UNIX很有兴趣,愿意为她,鞠躬尽瘁,呵呵,现在搞路由器,水平有待提高,数据库什么的,以前搞过,不是很精通,只是有点概念。','61.174.215.53','2002-03-06 10:49:22','2002-03-06 10:49:22',0,'61.174.215.53',208),('castor','Castor is an \'\'\'open source\'\'\' data binding framework for Java. It\'s basically the shortest path between Java objects, XML documents, SQL tables and LDAP directories. Castor provides Java to XML binding, Java to SQL/LDAP persistence, and then some more. \r\n\r\n','takaka','2002-02-27 22:42:04','2002-03-01 10:45:14',0,'takaka',174),('2002年2月27日 会议记录','[no]\r\n□ 欢迎光临『QQ聊天中心』的【自建聊天室(六)】□ \r\n \r\n★欢迎您来到『webpm』房间★ \r\n \r\n★这间房间的主人是『 OICQ_16048561 』★ \r\n \r\n破门: 其他人还没有来么? \r\n \r\n扫地的癞蛤: 不知道啊,我看见糨糊了 \r\n \r\n浆糊: 看来没人了,呵呵.. \r\n \r\n扫地的癞蛤: 呵呵:) \r\n \r\n扫地的癞蛤: 想讨论什么呢? \r\n \r\n破门: 好吧,现在可以开始了。 \r\n \r\n扫地的癞蛤: 讨论些什么? \r\n \r\n破门: 第一个议题,webpm的下一步发展战略。 \r\n \r\n扫地的癞蛤: 哦~~ \r\n \r\n破门: 目前的思路依然不够清晰,我们需要探讨一下,webpm需要提供什么样的服务? \r\n \r\n扫地的癞蛤: 哦,webpm?还是wiki/.? \r\n \r\n破门: 一样的,如何才能够真正为促进协作开发发挥作用。 \r\n \r\n扫地的癞蛤: 哦~~我原来在学校看过些cscw的资料:) \r\n \r\n破门: 就像wiki的介绍一样,它能够提供异步通讯的有效和有趣的方式 \r\n \r\n破门对扫地的癞蛤说: 能稍微介绍一下么? \r\n \r\n扫地的癞蛤: 呵呵,要哪方面的? \r\n \r\n扫地的癞蛤: 理论? \r\n \r\n扫地的癞蛤: 还是实际? \r\n \r\n破门对扫地的癞蛤说: cscw 的目标和基本思路 \r\n \r\n扫地的癞蛤: 其实cscw 是很广的一个话题 \r\n \r\n扫地的癞蛤: 就是计算机系统工作啊 \r\n \r\n破门对扫地的癞蛤说: 那先说目标吧 \r\n \r\n扫地的癞蛤: 呵呵,怎么定义的,我现在可不知道怎么说了,说不了了严谨 \r\n \r\n破门对扫地的癞蛤说: 大概就行了,我们只是想参考一下 \r\n \r\n扫地的癞蛤: 哦,我中午给wiki加了个上载的功能 \r\n \r\n扫地的癞蛤: 就是将分布的用户联合起来啊 \r\n \r\n破门: 你连的上cosoft的cvs么? \r\n \r\n扫地的癞蛤: 不能,所以我会email给糨糊 \r\n \r\n破门: 好吧 \r\n \r\n扫地的癞蛤: 呵呵 \r\n \r\n浆糊: 我会集成上去的. \r\n \r\n扫地的癞蛤: 异步的cscw很多是workflow based \r\n \r\n扫地的癞蛤: 不需要考虑并发控制和协作感知等问题 \r\n \r\n破门: 我觉得我们还是别研究理论吧,实际考虑一下协作的需要 \r\n \r\n浆糊: 是不是下一步先考虑引入工作流? \r\n \r\n扫地的癞蛤: 不过wiki里为什么要workflow呢? \r\n \r\n破门: ,我想我们应该讨论一下互联网开发真正需要什么?webpm怎样才能更好的发挥作用? \r\n \r\n浆糊对破门说: 原先考虑引入的想法说一下吧 \r\n \r\n \r\n扫地的癞蛤: 有哪些关于这个方面的需求? \r\n \r\n浆糊对破门说: 其实我们缺少用户 \r\n \r\n破门: 我想应该把精力集中在交流上面,我和浆糊两个人的沟通都成问题 \r\n \r\n扫地的癞蛤: 呵呵:) \r\n \r\n破门: 所以我考虑了三个方面的需求: \r\n \r\n浆糊对破门说: 这个倒也是.呵呵...很多事情说不清楚. \r\n \r\n扫地的癞蛤: 哦,洗耳共听 \r\n \r\n破门: 1、信息管理 - 目前我们找到了wiki这个好东西 \r\n \r\n破门: 也就是异步模式 \r\n \r\n扫地的癞蛤: 恩! \r\n \r\n破门: 2、实时交流 \r\n \r\n扫地的癞蛤: whiteboard? \r\n \r\n破门: 目前我们主要依赖于QQ(Instance Message)和chat \r\n \r\n扫地的癞蛤: chatroom? \r\n \r\n破门: 是的 \r\n \r\n扫地的癞蛤: chat room我也做过一个 \r\n \r\n扫地的癞蛤: 是基于xml socket的 \r\n \r\n破门: 我想在webpm中提供一个Meeting Room. \r\n \r\n扫地的癞蛤: 用falsh做的client,java写的server,速度很快 \r\n \r\n浆糊: 现在考虑的方式是applet \r\n \r\n \r\n扫地的癞蛤: swf为什么不好? \r\n \r\n破门: 或者像以前和浆糊讨论的,一个协作开发的 WorkShop \r\n \r\n浆糊: 你说道flash,能不能画图? \r\n \r\n扫地的癞蛤: 可以啊! \r\n \r\n扫地的癞蛤: 而且你说的到底是chatroom还是whiteboard? \r\n \r\n浆糊: 结合,最好是这样. \r\n \r\n扫地的癞蛤: 如果需要做whiteboard,那么就有用java把 \r\n \r\n破门: 对,我们考虑用SVG \r\n \r\n扫地的癞蛤: whiteboard应该有提供chat的功能的 \r\n \r\n破门: 是的 \r\n \r\n扫地的癞蛤: 不过我一直觉得whiteboard在实际中并没有什么太大的作用 \r\n \r\n破门: 第三点,就是工作流了 \r\n \r\n浆糊: 画画图什么. \r\n \r\n扫地的癞蛤: 但是有什么用呢? \r\n \r\n破门对扫地的癞蛤说: 你在公司工作时用过whiteboard么? \r\n \r\n扫地的癞蛤: 不用的 \r\n \r\n扫地的癞蛤: 有什么用啊? \r\n \r\n扫地的癞蛤: 如果要画rose图,传个给我就可以拉 \r\n \r\n浆糊: 例如一些类之间的关系阿,等等,..很多用图更直观 \r\n \r\n破门: 嗯,我现在在公司主要用白板讨论需求,设计和计划 \r\n \r\n \r\n扫地的癞蛤: 画好了,mail给我啊 \r\n \r\n破门: 效果很好,互动性很强。每个人都可以上去画。 \r\n \r\n扫地的癞蛤: 那用netmeeting好了! \r\n \r\n扫地的癞蛤: 为什么还要开发》?有什么优势? \r\n \r\n破门: mail的时间太久了。 \r\n \r\n破门: 主要是考虑防火墙。 \r\n \r\n破门: netmeeting很多时候用不了的,:( \r\n \r\n扫地的癞蛤: 用rmi的方式?这样的实时性是很不好的 \r\n \r\n浆糊: Applet也有防火墙的问题吧. \r\n \r\n扫地的癞蛤: 可以用applet和servlet通信,或者rmi啊 \r\n \r\n破门: qq,也有人用不了:( - 比如notyy \r\n \r\n破门: 对,用soap也可以 \r\n \r\n扫地的癞蛤: 但是这样可是用速度来换取的,还是用socket的最快 \r\n \r\n浆糊: 用xml做协议应该可以.走http \r\n \r\n扫地的癞蛤: 对于whiteboard,实时性是最关键的啊 \r\n \r\n扫地的癞蛤: 我是这样觉得的 \r\n \r\n扫地的癞蛤: 我当初做白板是因为想研究研究p2p的东西,结果失败:) \r\n \r\n扫地的癞蛤: 所以我觉得whiteboard 真是没什么大用处的东西:) \r\n \r\n浆糊: 考虑中..... \r\n \r\n扫地的癞蛤: 不过这个完全是个人之言:) \r\n \r\n \r\n破门: 我以前的考虑是 applet + servlet , 图形也转换成chat的方式发送/传递。 \r\n \r\n扫地的癞蛤: 但是我觉得 \r\n \r\n破门: 画图在本地画,应该效率比较高 \r\n \r\n扫地的癞蛤: 如果可以做个东西,可以共享屏幕,到是很不错的 \r\n \r\n浆糊: 如果试想一下,我们使用netmeeting. \r\n \r\n破门: 共享屏幕很麻烦,点阵数据啊?! \r\n \r\ntakaka: 我来了 \r\n \r\n扫地的癞蛤: 所以有挑战啊 \r\n \r\n破门: 局域网还差不多 \r\n \r\n破门对takaka说: 很久不见了! \r\n \r\n扫地的癞蛤: 所以是一个很有意思的论题啊 \r\n \r\n浆糊: 可以截图的.然后传. \r\n \r\n扫地的癞蛤: 我有同学现在就在自己做这样的东西 \r\n \r\n破门对浆糊说: 效率啊,很可怕的..... \r\n \r\n浆糊对takaka说: 好啊 :) \r\n \r\n扫地的癞蛤: 所以要学点理论啊 \r\n \r\ntakaka对浆糊说:好 \r\n \r\n破门对扫地的癞蛤说: p2p里面有类似这种功能 \r\n \r\n扫地的癞蛤: 而且我觉得应该是做成一个平台,所有软件都可以通过这个来共乡屏幕 \r\n \r\n破门: 我优先考虑 Applet + Servlet 实现 Chat+WhiteBoard \r\n \r\n \r\ntakaka对浆糊说:我记得国外已经有人实现这个功能 \r\n \r\n浆糊: 应该有类似的开发原码的东西. \r\n \r\n破门对takaka说: 是,DrawBoard 。 Applet+Server的 \r\n \r\n扫地的癞蛤: whiteboard提供协作感知和并发控制的功能吗? \r\n \r\n破门对扫地的癞蛤说: 不需要,实现跟现实的白板一样就行了 \r\n \r\n扫地的癞蛤: drawboard的代码我看过,很简单的功能,我说的功能都没 \r\n \r\n扫地的癞蛤: 但是白板必须提供协作感知和并发控制的,要不大家都拖动一个东西, \r\n \r\n扫地的癞蛤: 怎么办? \r\n \r\n扫地的癞蛤: netmeeting采用的是加琐的方法,简单,不过很实用的 \r\n \r\n破门对扫地的癞蛤说: 我们只准画和删就行了 \r\n \r\n浆糊: 我没有用过,呵呵..我想我们要实现的东西不会这么负责. \r\n \r\ntakaka: 就象老式的步话机,讲完话之后就说OVER \r\n \r\n\r\n扫地的癞蛤: 但是不能移动什么的,这样很不爽的 \r\n \r\n浆糊: 差不多,呵呵..OVER \r\n \r\n扫地的癞蛤: faint!!还是单工的啊,over \r\n \r\n破门: 无所谓,一般开会的时候。肯定只有一个人用白板的。 \r\n \r\ntakaka: :-) \r\n \r\n扫地的癞蛤: 哦,那就不是讨论拉 \r\n \r\n破门: 其他人看着就是了。 \r\n \r\n \r\n破门: 等他不画了,你在来就行了,over. \r\n \r\n浆糊: 呵呵..是啊. \r\n \r\n破门: 难道不是讨论么? \r\n \r\n扫地的癞蛤: 不好啊 \r\n \r\n浆糊: 一个简单的东西.实用 \r\n \r\n扫地的癞蛤: ,呵呵 \r\n \r\n破门: 你真要一起画也没问题啊?排队就行了,先进先出。 \r\n \r\ntakaka: 是可以轮流发言,又不是吵架,为什么要同时发言,OVER \r\n \r\n破门: 大不了画花脸猫么,呵呵...over \r\n \r\n浆糊: 呵呵....如果吵架也可以 \r\n \r\n扫地的癞蛤: 哦,takaka 那这样数据库也不要做并发控制了,大不了大家不吵架,哈哈 \r\n \r\n破门: 所以,自由点好了。。。 \r\n \r\n扫地的癞蛤: 哦! \r\n \r\n扫地的癞蛤: 好把,开始讨论workflow把 \r\n \r\n破门: 开发时,讨论本来就会很激烈 \r\n \r\n破门: workflow 也是重点。 \r\n \r\ntakaka: 如果数据只有几个进程,并发就不那么重要了 \r\n \r\n扫地的癞蛤: 我现在就在公司的work flow 引擎组 \r\n \r\n破门: 关键是每个人的待办事项处理, WorkList \r\n \r\n破门: 需要用一个统一的处理界面处理所有的流程类型。 \r\n \r\n\r\n破门对癞蛤蟆说: 你在哪个公司? \r\n \r\n癞蛤蟆: 上海一个公司啊 \r\n \r\n浆糊: 破门: 关键是每个人的待办事项处理, WorkList \r\n \r\n浆糊: 破门: 需要用一个统一的处理界面处理所有的流程类型。 \r\n \r\n癞蛤蟆: 断弦? \r\n \r\n癞蛤蟆: 哦,没 \r\n \r\n破门对癞蛤蟆说: 嗯,按照wfmc的模型建立数据结构都不难。实际处理方式合不合理才是关键。 \r\n \r\ntakaka: 我在听 \r\n \r\n癞蛤蟆: 恩 \r\n \r\n浆糊: 听................ \r\n \r\n癞蛤蟆: 听。。。。。。。。。 \r\n \r\n癞蛤蟆: 破门是弄workflow的? \r\n \r\n破门: 所以,流程定义应该很快可以实现 \r\n \r\n破门: 然后,定义一个流程实例化数据库。 \r\n \r\n破门: 流程服务器的关键是处理实例化后数据的状态控制。 \r\n \r\n破门: 如果有白板,我可以把流程定义与实例化的数据关联画出来。 \r\n \r\n破门: 就方便理解了 \r\n \r\n癞蛤蟆: 用活动状态图还是用perti网来定义呢? \r\n \r\n破门: 简单画画就可以了 \r\n \r\n \r\n癞蛤蟆: 不是,我是说在建摸的时候? \r\n \r\n破门: 我习惯直接画数据对应 \r\n \r\n癞蛤蟆: 哦!!我最竟在看perti网的东西, \r\n \r\n破门: 建模,用表定义就行了。网上协作的流程不可能太复杂。 \r\n \r\n癞蛤蟆: 看离散系统建模的东西:) \r\n \r\n癞蛤蟆: 哦!! \r\n \r\n癞蛤蟆: 其实做一个引擎这样就可以拉 \r\n \r\n破门: 刚才说的成败关键还是WorkList的处理设计。 \r\n \r\n破门: 要处理好不同流程的共性,用统一的待办列表。 \r\n \r\n癞蛤蟆: todolist? \r\n \r\n浆糊: 我对工作流不熟悉.问个问题:工作流能干什么,呵呵... \r\n \r\n破门: WorkList = ToDoList. \r\n \r\n癞蛤蟆: 哦! \r\n \r\n癞蛤蟆: 工作六就是实现工作流程的自动化或者半自动话,呵呵 \r\n \r\n浆糊: 定义工作流程? \r\n \r\n破门: 是WfMC写的,但是我认为还有点不同。 \r\n \r\n癞蛤蟆: 简单就是这样理解 \r\n \r\n癞蛤蟆: 用计算机实现,呵呵 \r\n \r\n破门: 工作流程有三个要素。 \r\n \r\n破门: [工作流程管理简介] \r\n \r\n浆糊: 看了. \r\n \r\n破门: 1。 流转路径的智能化 \r\n \r\n破门: 也就是流程自动化 \r\n \r\n破门: 2. 跟踪与监控信息的提供 \r\n \r\n破门: 第二点主要是为了流程优化 \r\n \r\n破门: 3。与应用结合的能力 \r\n \r\n破门: 在某些情况下,某些环节可以通过特定的应用程序自动实现 \r\n \r\n救世天使对癞蛤蟆说: 我是我啊 \r\n \r\n破门: 这可以理解为“任务自动化”。 \r\n \r\n浆糊: 嗯.要慢慢补课.概念上能理解 \r\n \r\n浆糊: 其实我想如果出一个具体的需求就会清楚很多. \r\n \r\n破门: 我认为我们下阶段还是先作 workshop. 方便大家的交流 \r\n \r\n癞蛤蟆: : 外面有一本情话的workflow的书卖的,可以看看 \r\n \r\n破门: 自动化(工作流)还可以缓缓 \r\n \r\n癞蛤蟆: 作者是自动化专业的 范玉顺 \r\n \r\n癞蛤蟆: workshop干什么的?》? \r\n \r\n浆糊: Chat+Draw \r\n \r\n癞蛤蟆: 哦 \r\n\r\n \r\n破门: 刚才不是说了么? =MeetingRoom \r\n \r\n破门: 大家认为呢? \r\n \r\n浆糊: 我想我们要分主题来讨论.计划中是很多的事情要讨论. \r\n \r\n癞蛤蟆: 恩 \r\n \r\n浆糊: 可以. \r\n \r\n破门: 我们有几个难题: \r\n \r\n破门: 1、源代码管理。 \r\n \r\n癞蛤蟆: 说来听听 \r\n \r\n破门: 2、文档管理。 \r\n \r\n癞蛤蟆: cvs啊 \r\n \r\n癞蛤蟆: 还可以弄个mailing list \r\n \r\n浆糊: 还有就是我们现在自己的项目的文档不全的问题.没有人负责 \r\n \r\n破门: 3、交流方式。- 这个依然成问题。 \r\n \r\n浆糊: 交流的话,我想文档不全也是妨碍交流的一个因素.如果有些UML的话, \r\n \r\n浆糊: 应该好些. \r\n \r\n破门: UML也不好,自己看很累的。还不如看代码 \r\n \r\n癞蛤蟆: 写测试代码啊 \r\n \r\n浆糊: 嗯,看测试也可以. \r\n \r\n午夜流浪: 只要做到测试悠闲,先写unit test就好 \r\n \r\n破门: 源代码管理不可能作了,我倾向于集成CVS \r\n \r\n \r\n午夜流浪: 这样人家就容易理解你的代码啊 \r\n \r\n浆糊: 我们现在是test first的. \r\n \r\n午夜流浪: 比uml可能效果还要好点 \r\n \r\nscaler: 大哥们好 \r\n \r\n午夜流浪: 我是你小弟,哈哈 \r\n \r\n破门: 是的,Test-First Design 要推广 \r\n \r\n◎ 午夜流浪 已经改名为 癞蛤蟆 ◎ \r\n \r\n癞蛤蟆: \r\n \r\n浆糊: 主题1:如何解决文档客户文档的问题.例如:FAQ等.让客户自己到wiki上找? \r\n \r\n破门: 我建议wiki v1.2完成后,核心小组暂停wiki的后续开发。 \r\n \r\n破门: 用一段时间充实/完善wiki的内容。 \r\n \r\n癞蛤蟆: \r\n \r\n浆糊: 恩.我也是这个意思.别的子项目要动起来.把webpm的框架搭起来 \r\n \r\n癞蛤蟆对着所有人捧腹大笑: \r\n \r\n破门: 然后,转向其他子项目。wiki的维护可以寻找志愿者。 \r\n \r\n浆糊: 找维护的人因该不难吧.大家可以找一些 \r\n \r\n破门: 下阶段先进行MeetingRoom(WorkShop)的开发如何? \r\n \r\n破门: 请投票! \r\n \r\n浆糊: 同意.如果人员充足可以同时进行\"工作流\" \r\n \r\n破门: 我赞成!!over \r\n\r\n \r\n浆糊: 人还在马??? \r\n \r\n破门: 怎么不发言? \r\n \r\n破门: 下阶段先进行MeetingRoom(WorkShop)的开发如何? \r\n \r\ntakaka: 在听 \r\n \r\n破门: 我们下阶段先进行MeetingRoom(WorkShop)的开发如何? \r\n \r\n浆糊: 呵呵...没人理 \r\n \r\ntakaka: 我觉得webpm.net比较重要 \r\n \r\nscaler: 先把一些错误的改正吧,至少有的功能能实现 \r\n \r\ntakaka: 不过如果大家觉得MeetingRoom的话,我也同意 \r\n \r\n破门: webpm.net本来就是MeetingRoom \r\n \r\n破门: 我的意思是完成 wiki v1.2以后 \r\n \r\n浆糊: jwiki的继续开发和维护可以请自愿者. \r\n \r\nscaler: 先把比较重要的项目实现筐架 \r\n \r\n破门: 好了。如果没有其他意见,我们进入下一议题。 \r\n \r\n浆糊: OK \r\n \r\nscaler: 没 人 LI WO \r\n \r\n浆糊: 项目部分已经再做了. \r\n \r\n破门: 关于webpm项目的资源组织和管理。 \r\n \r\n浆糊: 不久就可以看到.可以到1.2的故事中了解现在地开发情况. \r\n \r\nscaler: HAO \r\n \r\ntakaka: 同意 \r\n \r\n浆糊: 1.成员加入的条件以及规章. \r\n \r\n破门: 首先是开发组成员的管理,我希望我们能够讨论一下 \r\n \r\n破门: 要对成员提出一定的要求。 \r\n \r\n破门: 不需要很高,但是要能保证项目的正常进度。 \r\n \r\n浆糊: 是的. \r\n \r\ntakaka: hao \r\n \r\n浆糊: 具体内容. \r\n \r\n破门: 我的想法是,要求成员必须加入邮件列表。并按时通报状态。 \r\n \r\n破门: 就像ftp 发noop指令keep online 也行。 \r\n \r\n破门: 其次,要求成员尽量保障参加小组关键会议。 \r\n \r\n破门: 如果确实不能参加,必须尽快了解会议内容,并发表意见。 \r\n \r\n浆糊: 嗯.在接收到任务之后,最好能按时完成.如果有困难,需要及时的通知. \r\n \r\n破门: 第三,如果接受任务后,必须提供必要的投入保证。 \r\n \r\n破门: 尤其是发布计划会议中说明的投入点折算必须准确! \r\n \r\n破门: 第四,webpm的成员有义务为wiki网站提供“灌水”服务! \r\n \r\ntakaka: 如果按投入点投入,但不能按时完成的也要及时通知. \r\n \r\n破门: 是的 \r\n \r\ntakaka: 可不可以把别的网站上的文章copy过来呢 \r\n \r\n \r\n浆糊: 开发时必须遵守相关的开发规范. \r\n \r\n浆糊: 我经常干,呵呵.. \r\n \r\n破门: 我们要强调成员的不间断沟通。这也是XP的重要宗旨。 \r\n \r\n浆糊: 因为我没有时间写技术文章. \r\n \r\n破门: 交流和反馈! \r\n \r\n破门: 可以,最好是负责专栏。充实内容,但是杜绝“垃圾”! \r\n \r\n浆糊: 恩.开发过程参考XP \r\n \r\n浆糊: 嗯.也不要太多的转载.最好原创.不过好像难点. \r\n \r\n破门: 一句话,“宁缺勿滥” \r\n \r\n浆糊: 如果要退出开发组,需要及时通知.做好移交工作. \r\n \r\ntakaka: 但与我们的项目有关的多多益善 \r\n \r\n破门: 我认为第一条是最重要的。没有交流,就没有团队了! \r\n \r\ntakaka: 我那里上班上网不方便,但打电话比上网方便,不介意我打电话打扰大家吧 \r\n \r\n破门: 我们定两个成员报到点。一是邮件列表,二是wiki. \r\n \r\n浆糊: 呵呵..没有关系.随便骚扰我吧 :) \r\n \r\ntakaka: telephone no. \r\n \r\n浆糊: 规定一个时间吧,例如每周一次. \r\n \r\n破门: 没问题。第五,成员要提供真实的通讯地址。 \r\n \r\n浆糊: 联系方式我会发给大家的. \r\n \r\ntakaka: :) \r\n \r\n \r\n破门: 还有什么建议? \r\n \r\n浆糊: 想.......................... \r\n \r\n浆糊: 还是交流,成员之间有义务相互帮助,技术问题. \r\n \r\n破门: 要不然想想权利? \r\n \r\n浆糊: 恩.是啊,怎么忘了,这么重要的事情 :) \r\n \r\ntakaka: 特别是浆糊有权利帮助大家:) \r\n \r\n浆糊: :( 我很菜 \r\n \r\n浆糊: 成员有权利提交cvs代码. \r\n \r\ntakaka: java不菜 \r\n \r\nscaler: 我大哥怎么会菜呢,不要在象以前那样了,呵呵 \r\n \r\ntakaka: 有权利查看最新的代码 \r\n \r\n破门: 有权利在任何地方任何情况下使用源代码? \r\n \r\nscaler: CVS是什么? \r\n \r\ntakaka: 有权利在履行义务的前提下 \r\n \r\n破门: 有权利知道其他成员在任何情况任何地方使用了源代码。 \r\n \r\n浆糊: 不.需要遵守Lience \r\n \r\n破门: 没错! \r\n \r\n浆糊对scaler说: 版本控制.到时候慢慢和你说 \r\n \r\n破门: 加上前缀,在遵守版权的前提下! \r\n \r\ntakaka: 好 \r\n \r\n \r\n浆糊: 对.其实这个其它客户也可以.不能算是权利. \r\n \r\nscaler: 怎么会到权利呢?本来就是FREE \r\n \r\ntakaka对浆糊说: :) \r\n \r\n浆糊: 呵呵...是啊,Free... \r\n \r\ntakaka对scaler说: copyleft \r\n \r\ntakaka对scaler说: 大家说话好少啊 \r\n \r\n浆糊: 在想.. \r\n \r\ntakaka对scaler说: 都是三思而后行的人 \r\n \r\n浆糊: 我想成员的权利就是享受项目带来的成就感. :) \r\n \r\n破门: 有权利骚扰其他成员,呵呵:) \r\n \r\ntakaka对破门说: :) \r\n \r\n浆糊: 呵呵...是啊.takaka别忘了多多骚扰破门 \r\n \r\ntakaka对破门说: 你是领导啊 \r\n \r\n破门: 算了吧,别讨论权利了 \r\n \r\n浆糊: 恩.下个主题. \r\n \r\n破门: 我同意浆糊的看法 \r\n \r\nscaler对takaka说: 我现在觉得和P2P有些类式,一个是代码共享,一个说的简单点就是软件共享 \r\n \r\ntakaka对破门说: 我觉得应该多宣传,多找些人来 \r\n \r\n破门: 没有下个主题了。 \r\n \r\n \r\n破门: 第一个主题讨论的不完善! 我们可以做些什么有意义的。 \r\n \r\n浆糊: WebPM的总体目标.好像不是太明确. \r\n \r\nscaler对takaka说: 或者说有些人觉得莫名其妙 \r\n \r\ntakaka对浆糊说: 在前进中变化 \r\n \r\n破门: 很明确,最好的中文自由软件开发平台。 \r\n \r\ntakaka对浆糊说: 不是项目管理平台吗 \r\n \r\n浆糊: 呵呵..,.有人糊了.. \r\n \r\nscaler对takaka说: 因为是你自己开发的,自己想的当然,能明白拉 \r\n \r\ntakaka对浆糊说: 不准笑 \r\n \r\n破门: 为中文自由软件的开发者、使用者和推广者提供基于互联网的开放式管理平台环境。 \r\n \r\n浆糊: :( 那我们就得有自己的口号!!!! \r\n \r\n癞蛤蟆对着所有人捧腹大笑: hi~~我来拉 \r\n \r\n破门: 呵呵,好像没有人看得明白 \r\n \r\nscaler: 定位在哪个位置? \r\n \r\n浆糊: 至少可以起到煽动作用 :) \r\n \r\n癞蛤蟆对着所有人捧腹大笑: 看明白什么东西啊?破门 \r\n \r\n癞蛤蟆: 刚才有事 \r\n \r\ntakaka对破门说: 交流平台?资料仓库? \r\n \r\n浆糊对癞蛤蟆说: 刚才讨论了很多 \r\n \r\n破门对癞蛤蟆说: 目标:为中文自由软件的开发者、使用者和推广者提供基于互联网的开放式管理平台 \r\n \r\n \r\n癞蛤蟆: 哦! \r\n \r\n癞蛤蟆: 明白! \r\n \r\n破门对浆糊说: 我觉得你那个朋友做的主页上写的不错! \r\n \r\n浆糊: 做最好的中文自由软件的开发平台!可以作为口号,哈哈... \r\n \r\n癞蛤蟆: 最好?这样太张扬了把 \r\n \r\n浆糊: 恩.他很热心,他提出给我们做的. \r\n \r\n浆糊对癞蛤蟆说: 呵呵...破门说的. \r\n \r\n癞蛤蟆: 能学点是最重要的 \r\n \r\n破门对浆糊说: 新概念、新形势,真正的自由! \r\n \r\n癞蛤蟆: 哦! \r\n \r\ntakaka对破门说: 新方式,新思路 \r\n \r\n破门对浆糊说: 我喜欢那个跳动 wiki! 这个星期我一定把主页做好! \r\n \r\n癞蛤蟆: 这个wiki写了多九? \r\n \r\n浆糊: 嗯.事情是要做的,口号也是要有的. :) \r\n \r\n浆糊: OK. \r\n \r\n破门对浆糊说: 2001年12月15日开始的 \r\n \r\n癞蛤蟆: 哦! \r\n \r\n浆糊: 2个月八. \r\n \r\n癞蛤蟆: 知道了 \r\n \r\n癞蛤蟆: 什么主业啊?我去看看 \r\n \r\n \r\ntakaka对浆糊说: 有时间我帮wiki做过一个logo \r\n \r\n破门对浆糊说: 我希望大家从实际的角度出发想想 \r\n \r\n破门对浆糊说: http://210.192.109.59:8080/webpm/test/index.html \r\n \r\nscaler对浆糊说: 哥啊,你把这考下发给我,我走了,饭还没吃Q \r\n \r\ntakaka对癞蛤蟆说: 癞蛤蟆不是\'扫地的癞蛤蟆\'? \r\n \r\n癞蛤蟆: 是啊 \r\n \r\n癞蛤蟆: 就是那只蛤蟆 \r\n \r\ntakaka对癞蛤蟆说: 那还问主页? \r\n \r\n浆糊: 恩.好的.有会议纪要的. \r\n \r\n癞蛤蟆: 呵呵, \r\n \r\n癞蛤蟆: www.extradna.com \r\n \r\nscaler对浆糊说: 走了 \r\n \r\n癞蛤蟆: 我同学做的产品:) \r\n \r\n癞蛤蟆: 他还在念书 \r\n \r\n癞蛤蟆: http://www.extradna.com/ \r\n \r\n癞蛤蟆: faint!!连不上 \r\n \r\n浆糊: 我上了.很酷. \r\n \r\ntakaka对癞蛤蟆说: 能连上啊 \r\n \r\n癞蛤蟆: 呵呵。我怎么不行?fiant! \r\n \r\ntakaka对浆糊说: 那个wiki我也喜欢 \r\n \r\n \r\n癞蛤蟆: 对,提点需求,我来加功能好了 \r\n \r\n癞蛤蟆: jwiki \r\n \r\n癞蛤蟆: 都不说话了? \r\n \r\n浆糊: 嗯.好啊. :) \r\n \r\ntakaka对癞蛤蟆说: 新加项目主页 \r\n \r\n浆糊: 例如一个 javadiff功能. \r\n \r\n癞蛤蟆: 什么意思/。? \r\n \r\ntakaka对癞蛤蟆说: 注册项目 \r\n \r\n癞蛤蟆: cvs上的功能? \r\n \r\n破门: 是的,diff功能拖了好久了 \r\n \r\n癞蛤蟆: differ? \r\n \r\n浆糊: javadiff,类似于cvs地diff \r\n \r\n癞蛤蟆: 又不是代码,要differ什么啊? \r\n \r\n破门对takaka说: 注册项目已经搞定了,:) \r\n \r\n浆糊: 这个功能一直拖者,而且有些难度. \r\n \r\n癞蛤蟆: 江湖那里??上海乡下是哪里?金桥? \r\n \r\n破门: 看看v1.2的故事吧 \r\n \r\n浆糊: jwiki也有版本的阿,需要知道有什么变化. \r\n \r\n癞蛤蟆: 张江? \r\n \r\n浆糊: 康桥. \r\n \r\n \r\n癞蛤蟆: 哦,不知道! \r\n \r\n癞蛤蟆: 我在张江高科的 \r\n \r\ntakaka对破门说: 高兴 \r\n \r\n浆糊: 张江边上. \r\n \r\n癞蛤蟆: 哦! \r\n \r\n浆糊: 阿,我们很近. \r\n \r\n癞蛤蟆: 哈哈! \r\n \r\n浆糊: diff怎么样? \r\n \r\n癞蛤蟆跟大家握了握手。 \r\n \r\n癞蛤蟆: 好啊! \r\n \r\n癞蛤蟆: 可以啊,我去做! \r\n \r\n浆糊: :) \r\n \r\n癞蛤蟆: 不过,主要有一点,我下阶段很忙 \r\n \r\n浆糊: 太好了.时间点多少 \r\n \r\ntakaka对浆糊说: 你有救了 \r\n \r\n浆糊: 如果全工作日需要几天? \r\n \r\n癞蛤蟆: 今天中午上载也是用了休息的时间做的 \r\n \r\n破门: 就算每周提供1d 也可以。 \r\n \r\n浆糊: 辛苦了 \r\n \r\n癞蛤蟆: hehe ,这个不清楚啊, \r\n \r\n \r\n癞蛤蟆: 啊~每周要做1天啊!? \r\n \r\n癞蛤蟆: 我每周最多抽出1d来学习:) \r\n \r\n癞蛤蟆: 写这些,可以在空闲的时间,偷偷写,哈哈 \r\n \r\n浆糊: 呵呵..你看吧,慢点没有关系 \r\n \r\n破门: 8个工作时,我现在一周提供3d了,:)本职工作都压着呢 \r\n \r\n癞蛤蟆: 好! \r\n \r\n浆糊: 和我一样,呵呵...一堆的事情.. \r\n \r\n癞蛤蟆: faint!!我可是做coding的,被老板压迫的紧啊! \r\n \r\n破门: 嗯,未列入版本计划的都可以慢慢做。 \r\n \r\n癞蛤蟆: 不敢太嚣张哦 \r\n \r\n浆糊: 呵呵..我:需求,设计,编码,测试,验收 :) \r\n \r\n癞蛤蟆: 我就。。。。编码 \r\n \r\n浆糊: 慢慢做吧,量力吧. \r\n \r\ntakaka对浆糊说: 我:打电话,催报表,发传真:) \r\n \r\n癞蛤蟆: 公司里是什么都做,我说webpm,我就编码:) \r\n \r\n破门: 我在公司,除了编码,什么都做。 \r\n \r\n癞蛤蟆: 呵呵,对了,江湖,狂假要不要换? \r\n \r\n癞蛤蟆: 狂假=framework,呵呵 \r\n \r\n浆糊: 要的,肯定的.不过代码需要及时的给我,要和大家同步. \r\n \r\n癞蛤蟆: 用mvc的方式比较好 \r\n \r\n \r\n癞蛤蟆: 但是这样要修改很多地方啊 \r\n \r\n破门: 给了实例吧。比如该一下用户注册先 \r\n \r\n浆糊: 你估计工作量有多少? \r\n \r\n癞蛤蟆: 不过其实整个项目也不大,还可以接受 \r\n \r\n癞蛤蟆: 我估计? \r\n \r\n浆糊: 恩. \r\n \r\n癞蛤蟆: 如果用我现在用的狂假,我1天就可以写好 \r\n \r\n破门: 只改用户处理部分的 \r\n \r\n癞蛤蟆: 1天调试 \r\n \r\n癞蛤蟆: 但是,我做的拿出来直接用,不太好把 \r\n \r\n破门: 嗯,要两周 \r\n \r\n浆糊: OK.那你改吧.代码给你向破门要 最新的 :) \r\n \r\n癞蛤蟆: 还有,实体类最好用jdo来做 \r\n \r\n癞蛤蟆: 这样,就可以在很多数据哭下用了 \r\n \r\n破门: 我会上传到 /webpm/downloads/ \r\n \r\n癞蛤蟆: 现在的只能在mysql下 \r\n \r\n癞蛤蟆: 啊?让我全修改了? \r\n \r\n癞蛤蟆: 这个不好把 \r\n \r\n破门: jdo要收钱的。:( \r\n \r\n浆糊: OK.现在要确定的是如何修改,谁修改,如何集成. \r\n \r\n \r\n癞蛤蟆: 哦? \r\n \r\n癞蛤蟆: 我给你个方俺,你来写和该把 \r\n \r\n浆糊: 多少时间,如果有文档,我可以辛苦点.不过文档要详细. \r\n \r\n癞蛤蟆: 因为我用公司里用的,拿出来用,不好的 \r\n \r\n破门: 我同意 \r\n \r\n癞蛤蟆: 那成剽窃拉 \r\n \r\n癞蛤蟆: 虽然我可以重写,但是总是不能脱离。。。。。 \r\n \r\n浆糊: 哇,那你千万不能换公司了 :) \r\n \r\n破门: 提个方案吧 \r\n \r\n癞蛤蟆: 因为是自己写的,总回有影象的 \r\n \r\n癞蛤蟆: 分m v c \r\n \r\n癞蛤蟆: m是实体类 \r\n \r\n癞蛤蟆: v是jsp页面 \r\n \r\n浆糊: servlet做control \r\n \r\n破门对癞蛤蟆说: 劳驾,整理一下,贴到wiki \r\n \r\n癞蛤蟆: 用一个servlet做总控制servlet \r\n \r\ntakaka对浆糊说: 好象IBM的DW上有文章啊 \r\n \r\n浆糊: 大体的框架清楚,需要的是细节. \r\n \r\n癞蛤蟆: 用xml来定义如何分发 \r\n \r\ntakaka对浆糊说: 关于mvc的 \r\n \r\n \r\n癞蛤蟆: 我就是那样做的,我做的比他早,哈哈 \r\n \r\n癞蛤蟆: 至少我做好了几个月以后才见到他的文章的 \r\n \r\n破门: 我们不讨论细节吧。还有什么关键主题要讨论? \r\n \r\n癞蛤蟆: 不过还是有很多地方不一样 \r\n \r\ntakaka对癞蛤蟆说: 不会吧,那上面是英文的译本,写的还是tomcat3.2 \r\n \r\n癞蛤蟆: 那我就不知道了,我用resin的,嘿嘿 \r\n \r\n浆糊对癞蛤蟆说: 你些个详细的文档可以吗?我来实现,你验收,OK? \r\n \r\n癞蛤蟆: 可以! \r\n \r\n癞蛤蟆: 好的 \r\n \r\n癞蛤蟆: 没问题的说 \r\n \r\ntakaka对癞蛤蟆说: 是不是你写test,浆糊code \r\n \r\n浆糊: 我们的model部分应该不会太大的变化吧? \r\n \r\n浆糊: 也可以得.最好了. \r\n \r\n癞蛤蟆: faint!!! \r\n \r\n癞蛤蟆: 我写test??接口也我定? \r\n \r\n癞蛤蟆: 我写文档,hohoho \r\n \r\n浆糊: 可以.最好是根据现在地情况 \r\n \r\n\r\n破门: 呵呵,又有人要倒了 \r\n \r\n浆糊: 好的. \r\n \r\n \r\n癞蛤蟆: 好地~ \r\n \r\n破门: takaka能不能研究一下SVG? \r\n \r\n癞蛤蟆: 研究svg干什么啊? \r\n \r\n破门: 灌点水来,为 WhiteBoard做准备 \r\n \r\n癞蛤蟆: 我要下拉~~~~ \r\n \r\n浆糊: 嗯.好的.88 \r\n \r\ntakaka对破门说: 是啊,SVG是什么? \r\n \r\n癞蛤蟆: 有点事情, \r\n \r\n癞蛤蟆: 各位 \r\n \r\ntakaka对癞蛤蟆说: 88 \r\n \r\n癞蛤蟆: 886:) \r\n \r\n癞蛤蟆: svg就是可以取代flash的东西 \r\n \r\n癞蛤蟆: 和xml相关 \r\n \r\n破门: 矢量图的XML描述 \r\n \r\n浆糊: 等你的文档 \r\n \r\ntakaka对癞蛤蟆说: 好象是IBM出的? \r\n \r\n癞蛤蟆: 我给的是最容易理解的解释,虽然土,哈哈 \r\n \r\n癞蛤蟆: 好的! \r\n \r\ntakaka对癞蛤蟆说: 88 \r\n \r\ntakaka对癞蛤蟆说: 请茶 \r\n \r\n \r\n癞蛤蟆: 几天之内:)明天反正上载的一定mail给你 \r\n \r\n浆糊: OK \r\n \r\n癞蛤蟆: 886~ \r\n \r\n癞蛤蟆: all \r\n \r\n破门对takaka说: 这里有:http://xml.apache.org/batik/index.html \r\n \r\n浆糊: 我们怎么样? \r\n \r\n破门对浆糊说: 还有什么问题么? \r\n \r\ntakaka: Scalable Vector Graphics \r\n \r\ntakaka: http://www.w3.org/Graphics/SVG/Overview.html \r\n \r\ntakaka: 没问题了 \r\n \r\n破门对takaka说: 找点关键的翻译一点。 \r\n \r\n浆糊: takaka最近时间怎么? \r\n \r\ntakaka: 再过一个月,我们部分就会有新人来了 \r\n \r\ntakaka: 现在白天忙,晚上看oracle \r\n \r\n浆糊: 那我接下来的任务就是重构jwiki,进行大手术 \r\n \r\ntakaka: 时间要挤还是有的,但心静不下来 \r\n \r\n浆糊: 还有就是多语言的配置. \r\n \r\n破门对浆糊说: 我们新的主页就是softme.org 的 logo 不太好 \r\n \r\n浆糊: 我估计重构的工作量很大. \r\n \r\n浆糊: 我这里有一个美工,很厉害的,叫他做一个怎么样? \r\n \r\n \r\n破门对浆糊说: 正好看看test-first能不能保证我的代码不受影响。 \r\n \r\n破门对浆糊说: 你改你的,我做我的。 \r\n \r\n浆糊: 我会修改test的. \r\n \r\n浆糊: 可以得.要及时集成. \r\n \r\n破门对浆糊说: 好啊 \r\n \r\n浆糊: 网站上的代码我不更新了,如果要更新的话,你来. \r\n \r\n破门对takaka说: 很久不来,也不多聊聊? \r\n \r\ntakaka: 我插不上话 \r\n \r\n浆糊: Logo要不要重新设计? \r\n \r\ntakaka: 下个月我可能有机会去珠海 \r\n \r\n破门: 好啊 \r\n \r\ntakaka: 或者无锡 \r\n \r\n破门: 我不一定有时间,:( \r\n \r\ntakaka: 我希望两个地方都能去 \r\n \r\n \r\n浆糊: 无锡离上海还是挺远. \r\n \r\ntakaka: 路过 \r\n \r\n破门: 虽然珠海到深圳只有2个小时的距离 \r\n \r\ntakaka: 你们都怕我去骚扰吗?:) \r\n \r\n浆糊: 呵呵... \r\n \r\n浆糊: 开发组是不是要定期开会? \r\n \r\n破门对浆糊说: 用邮件列表吧 \r\n \r\n破门: 只要常用列表和wiki,问题就少多了 \r\n \r\n浆糊: 哦 \r\n \r\n浆糊: 我习惯wiki了. :) \r\n \r\ntakaka对浆糊说: 我也喜欢wiki \r\n \r\ntakaka对浆糊说: 我的wiki 1.1中的乱码要如何解决? \r\n \r\n浆糊: 问破门.他好像知道. \r\n \r\n破门: 那我们在章程里,把wiki放在maillist前面! \r\n \r\n浆糊: 嗯.好的. \r\n \r\n破门对takaka说: 你这里有乱码么? \r\n \r\n破门对takaka说: 访问 softme.org 也有? \r\n \r\ntakaka对破门说: 标题和页脚有 \r\n \r\n浆糊: 你是不是只有标头有问题啊,输入和查看没有问题吧. \r\n \r\n \r\ntakaka对破门说: 我是说在我的机器上的wiki \r\n \r\ntakaka对破门说: 对 \r\n \r\ntakaka对破门说: 查看标题也有 \r\n \r\n浆糊: 你的是98?tomcat什么版本? \r\n \r\ntakaka对破门说: 比如最近访问就有 \r\n \r\ntakaka对破门说: 3.2 \r\n \r\n浆糊: 哦,也许就是这个问题了. \r\n \r\n破门: 最好换tomcat4 \r\n \r\ntakaka对破门说: 我试试 \r\n \r\n破门: 我们没有测试tomcat3.2 \r\n \r\n浆糊: 用4.0没有问题.解决方法就是设置config.xml \r\n \r\ntakaka对浆糊说: 好的 \r\n \r\n破门: 有时间我测试一下看 \r\n \r\n浆糊: 用破门的那个resin的配置应该没有问题的. \r\n \r\n破门: 是的,resin我测试过了。 \r\n \r\n浆糊: resin和tomcat3.2差不多的. \r\n \r\ntakaka对浆糊说: 那可能是tomcat3.2的问题了 \r\n \r\n浆糊: 不过我们应该解决多平台的问题. \r\n \r\ntakaka对浆糊说: 不过不是全部是乱码 \r\n \r\n浆糊: 最好把weblogic地配置也弄出来. \r\n \r\n \r\n破门: 嗯,这个很头痛! \r\n \r\n浆糊: 如果输入和读出没有问题,就不用修改db的中文编码了. \r\n \r\ntakaka: 我觉得是inc文件的问题 \r\n \r\n浆糊: 恩.是的.你自己调试一下看看. \r\n \r\n破门: 如果没有其他问题,我们就整理一个开发人员章程。 \r\n \r\n破门: 放到wiki上让大家讨论 \r\n \r\n浆糊: 嗯.好的. \r\n \r\ntakaka对浆糊说: 我找时间看一下,不明白的就问你了 \r\n \r\n浆糊: 好的. \r\n \r\n破门: 我觉得webpm最初的目标还是正确的 \r\n \r\ntakaka对浆糊说: 我在wiki错误报告中说过我的问题啊 \r\n \r\n破门: 这段时间过了我们要加快整体的进度了! \r\n \r\ntakaka: 我觉得还是人手少 \r\n \r\n浆糊: 人少就自己辛苦点了. \r\n \r\n破门: 是的,我们一个一个突破,先搭起框架。 \r\n \r\n浆糊: 不过会有人加入进来的,例如:蛤蟆,呵呵... \r\n \r\ntakaka: xp中有一个原则是每周40h \r\n \r\n浆糊: 我要需要稳定的开发成员. \r\n \r\n破门对takaka说: 你怎么理解? \r\n \r\ntakaka对破门说: 疲倦的程序员写不出好程序 \r\n \r\n \r\n破门对takaka说: 是的 \r\n \r\n破门对takaka说: 我们并不疲倦,我累的时候是不写程序的。 \r\n \r\ntakaka对破门说: 加班可以偶而为之,长期存在就是管理上的结构性问题了 \r\n \r\n浆糊: 呵呵..我一天没有精神的时候, :) \r\n \r\n破门对浆糊说: 要不就不是浆糊了 \r\n \r\ntakaka对破门说: 写得辛苦也不好 \r\n \r\ntakaka对破门说: 千秋万载,一统江湖! \r\n \r\ntakaka对浆糊说: 千秋万载,一统江湖! \r\n \r\ntakaka对浆糊说: :) \r\n \r\ntakaka对浆糊说: 一桶浆糊 \r\n \r\n浆糊: 呵呵.. \r\n \r\n破门: 因为,大家都有工作,加班是肯定的了。 \r\n \r\n破门: 所以我们要求有效的投入 \r\n\r\ntakaka对浆糊说: 你和wader在一起的时间挺精神的 \r\n \r\n浆糊: 靠,你怎么知道啊,NND \r\n \r\n破门对takaka说: 你有没有相片贴啊? \r\n \r\ntakaka对浆糊说: 我们7月份全员竞岗,心累啊 \r\n \r\ntakaka对破门说: 有啊 \r\n \r\n浆糊: 没有看到阿. \r\n \r\n\r\ntakaka对破门说: 不过没时间去扫描 \r\n \r\ntakaka对浆糊说: 我发给你帮我放上去,可以吗? \r\n \r\n浆糊: 可以. \r\n \r\ntakaka对浆糊说: 过两天就去扫描 \r\n \r\ntakaka: 踏冰有消息吗? \r\n \r\n浆糊: 没有. \r\n \r\ntakaka: 这家伙好象为情所困了 \r\n \r\n破门: 以后按章程办,2周不报到者--斩!! \r\n \r\n破门: 在加入要重新申请,呵呵... \r\n \r\n浆糊: 呵呵..好.刀下不留情! \r\n \r\n浆糊: :) \r\n \r\ntakaka: :) \r\n \r\n浆糊: 破门先整理规章吧. \r\n \r\n破门: 对了,刚才没有讨论加入的问题 \r\n \r\n浆糊: 我看MVC的资料. \r\n \r\n破门: 成员的审核怎么办? \r\n \r\ntakaka: 现在人少,审核就放一放吧 \r\n \r\n破门: 必须承接一个任务,并按期完成怎么样? \r\n \r\ntakaka: 我们现在是来者不拒 \r\n \r\ntakaka: 同意啊 \r\n \r\n \r\n破门: 来者不拒也不行啊?光有人加入,不做事有什么用? \r\n \r\n浆糊: 没有做过任务的,不允许commit \r\n \r\n破门: ok! \r\n \r\ntakaka: 那也是 \r\n \r\n浆糊: 破门有没有jdo的资料? \r\n \r\n破门: 焦点网上webpm小组几十人,现在还不是只剩我们了 \r\n \r\ntakaka: :) \r\n \r\n破门对浆糊说: 没有 \r\n \r\ntakaka: Java Data Objects \r\n \r\n破门: 我现在的确有点忙不过来了。 \r\n \r\n浆糊: 呵呵..是啊.贵在坚持 \r\n \r\n浆糊: 我也是. \r\n \r\ntakaka: 我主张细水长流 \r\n \r\n浆糊: 太细了不行啊, \r\n \r\n破门: 关键是目标导向 \r\n \r\n浆糊: 就像虚虚..总会断地 :) \r\n \r\ntakaka对浆糊说: 我找了一下,好象有很多不同的jdo \r\n \r\n破门: 不要过多浪费精力在没有效果或不明显的需求上 \r\n \r\n浆糊: 这些的话,对整个系统有本质的提高. \r\n \r\n破门: 所以,我们今天讨论目标。要最快的向目标迈进! \r\n \r\n \r\ntakaka对浆糊说: 好的 \r\n \r\n浆糊: 磨刀不误砍材 \r\n \r\n破门: 是的,有些不重要的bug可以放在那里。做一个buglist. \r\n \r\n破门: 找人做! \r\n \r\n浆糊: 恩.是.应该让别人知道他们可以帮助我们什么. \r\n \r\n破门: 比如:审核成员的时候。呵呵...有点黑! \r\n \r\n浆糊: 呵呵..是啊. \r\n \r\n----\r\n删除以下有关浆糊黄山之旅的秘史的讨论。 BrokenDoor - 2002-2-28\r\n----\r\n \r\n破门: 呵呵,我只有一张 \r\n \r\n破门: 其他的没有扫描 \r\n \r\n浆糊对takaka说: 是啊,爬山类死 \r\n \r\ntakaka对浆糊说: 我明天也去扫一张国庆去海边玩的 \r\n \r\n浆糊对takaka说: 呵呵.. \r\n \r\ntakaka对浆糊说: 你们坐汽车还是火车? \r\n \r\n浆糊对takaka说: takaka你能帮我招招jdo的资料吗? \r\n \r\n浆糊对takaka说: 火车. \r\n \r\ntakaka对浆糊说: 到google上一找一大堆 \r\n \r\n浆糊对takaka说: 我要有用的阿 \r\n \r\ntakaka对浆糊说: 我刚才copy了几个地址,发现被聊天室系统自动过滤了 \r\n \r\n浆糊对takaka说: 那算了,我自己找吧. \r\n \r\ntakaka对浆糊说: 我放在wiki上吧 \r\n \r\n浆糊对takaka说: http://www-900.ibm.com/developerWorks/java/l-mvc/index.shtml \r\n \r\n浆糊对takaka说: MVC的中文文章. \r\n \r\n浆糊对takaka说: 好. \r\n \r\ntakaka对浆糊说: 我看过了 \r\n \r\n浆糊对takaka说: 我看资料了. \r\n \r\ntakaka对浆糊说: wiki的保存按钮能不能在下面也放一个? \r\n \r\n破门: 大家最好保持联系! \r\n \r\n浆糊对takaka说: 嗯.我每天看jwiki几十次,呵呵.. \r\n \r\n破门: 我看wiki比我看孩子的次数还多啊. \r\n \r\ntakaka对浆糊说: 我的意思是文章太长的时间,保存不方便,要向上翻页 \r\n \r\n \r\n浆糊对takaka说: 呵呵..那个叫破门加吧 \r\n \r\n破门: 我来处理好了 \r\n \r\n破门: 开工了。 \r\n \r\n浆糊对takaka说: 我也开工了. \r\n \r\n破门: 以后做好MeetingRoom一定要自动记录,记录这个chatroom很烦的。 \r\n \r\n浆糊对takaka说: 嗯.是啊. \r\n \r\ntakaka: me too \r\n \r\n破门: 走了,保持联络。 \r\n[/no]\r\n----\r\n分类: [WebPM] | [WebPM 小组会议]\r\n\r\n参考: [webpm_wiki] ','BrokenDoor','2002-02-28 09:29:28','2002-03-04 15:40:37',0,'BrokenDoor',175),('ConnectionPool','[code]\r\n/*\r\n * @(#)ConnectionPool\r\n *\r\n * Copyright (c) 1998 Karl Moss. All Rights Reserved.\r\n *\r\n * You may study, use, modify, and distribute this software for any\r\n * purpose provided that this copyright notice appears in all copies.\r\n *\r\n * This software is provided WITHOUT WARRANTY either expressed or\r\n * implied.\r\n *\r\n * @author Karl Moss\r\n * @version 1.0\r\n * @date 11Mar98\r\n *\r\n */\r\n\r\npackage javaservlets.jdbc;\r\n\r\nimport java.sql.*;\r\n\r\n/**\r\n *

This class serves as a JDBC connection repository. Since\r\n * creating database connections is one of the most time\r\n * intensive aspects of JDBC, we\'ll create a pool of connections.\r\n * Each connection can be used and then replaced back into the\r\n * pool.\r\n *\r\n *

A properties file \'ConnectionPool.cfg\' will be used to\r\n * specify the types of JDBC connections to create, as well as\r\n * the minimum and maximum size of the pool. The format of\r\n * the configuration file is:\r\n *\r\n * #(comment)\r\n * JDBCDriver=\r\n * JDBCConnectionURL=\r\n * ConnectionPoolSize=\r\n * ConnectionPoolMax=\r\n * ConnectionUseCount=\r\n * ConnectionTimeout=\r\n * =\r\n *\r\n *

Any number of additional properties may be given (such\r\n * as username and password) as required by the JDBC driver.\r\n *\r\n */\r\n\r\npublic class ConnectionPool\r\n implements javaservlets.timer.TimerListener\r\n{\r\n // JDBC Driver name\r\n String m_JDBCDriver;\r\n\r\n // JDBC Connection URL\r\n String m_JDBCConnectionURL;\r\n\r\n // Minimum size of the pool\r\n int m_ConnectionPoolSize;\r\n\r\n // Maximum size of the pool\r\n int m_ConnectionPoolMax;\r\n\r\n // Maximum number of uses for a single connection, or -1 for\r\n // none\r\n int m_ConnectionUseCount;\r\n\r\n // Maximum connection idle time (in minutes)\r\n int m_ConnectionTimeout;\r\n\r\n // Additional JDBC properties\r\n java.util.Properties m_JDBCProperties;\r\n\r\n // The Connection pool. This is a vector of ConnectionObject\r\n // objects\r\n java.util.Vector m_pool;\r\n\r\n // The maximum number of simultaneous connections as reported\r\n // by the JDBC driver\r\n int m_MaxConnections = -1;\r\n\r\n // Our Timer object\r\n javaservlets.timer.Timer m_timer;\r\n \r\n /**\r\n *

Initializes the ConnectionPool object using\r\n * \'ConnectionPool.cfg\' as the configuration file\r\n *\r\n * @return true if the ConnectionPool was initialized\r\n * properly\r\n */\r\n public boolean initialize() throws Exception\r\n {\r\n return initialize(\"javaservlets/jdbc/ConnectionPool.cfg\");\r\n }\r\n\r\n /**\r\n *

Initializes the ConnectionPool object with the specified\r\n * configuration file\r\n *\r\n * @param config Configuration file name\r\n * @return true if the ConnectionPool was initialized\r\n * properly\r\n */\r\n public boolean initialize(String config) throws Exception\r\n {\r\n // Load the configuration parameters. Any leftover parameters\r\n // from the configuration file will be considered JDBC\r\n // connection attributes to be used to establish the\r\n // JDBC connections\r\n boolean rc = loadConfig(config);\r\n\r\n if (rc) {\r\n // Properties were loaded; attempt to create our pool\r\n // of connections\r\n createPool();\r\n\r\n // Start our timer so we can timeout connections. The\r\n // clock cycle will be 20 seconds\r\n m_timer = new javaservlets.timer.Timer(this, 20);\r\n m_timer.start();\r\n }\r\n return rc;\r\n }\r\n\r\n /**\r\n *

Destroys the pool and it\'s contents. Closes any open\r\n * JDBC connections and frees all resources\r\n */\r\n public void destroy()\r\n {\r\n try {\r\n\r\n // Stop our timer thread\r\n if (m_timer != null) {\r\n m_timer.stop();\r\n m_timer = null;\r\n }\r\n\r\n // Clear our pool\r\n if (m_pool != null) {\r\n\r\n // Loop throught the pool and close each connection\r\n for (int i = 0; i < m_pool.size(); i++) {\r\n close((ConnectionObject) m_pool.elementAt(i));\r\n }\r\n }\r\n m_pool = null;\r\n }\r\n catch (Exception ex) {\r\n ex.printStackTrace();\r\n }\r\n }\r\n\r\n /**\r\n *

Gets an available JDBC Connection. Connections will be\r\n * created if necessary, up to the maximum number of connections\r\n * as specified in the configuration file.\r\n *\r\n * @return JDBC Connection, or null if the maximum\r\n * number of connections has been exceeded\r\n */\r\n public synchronized java.sql.Connection getConnection()\r\n {\r\n // If there is no pool it must have been destroyed\r\n if (m_pool == null) {\r\n return null;\r\n }\r\n\r\n java.sql.Connection con = null;\r\n ConnectionObject connectionObject = null;\r\n int poolSize = m_pool.size();\r\n\r\n // Get the next available connection\r\n for (int i = 0; i < poolSize; i++) {\r\n\r\n // Get the ConnectionObject from the pool\r\n ConnectionObject co = (ConnectionObject)\r\n m_pool.elementAt(i);\r\n\r\n // If this is a valid connection and it is not in use,\r\n // grab it\r\n if (co.isAvailable()) {\r\n connectionObject = co;\r\n break;\r\n }\r\n }\r\n\r\n // No more available connections. If we aren\'t at the\r\n // maximum number of connections, create a new entry\r\n // in the pool\r\n if (connectionObject == null) {\r\n if ((m_ConnectionPoolMax < 0) ||\r\n ((m_ConnectionPoolMax > 0) &&\r\n (poolSize < m_ConnectionPoolMax))) {\r\n \r\n // Add a new connection.\r\n int i = addConnection();\r\n \r\n // If a new connection was created, use it\r\n if (i >= 0) {\r\n connectionObject = (ConnectionObject)\r\n m_pool.elementAt(i);\r\n }\r\n }\r\n else {\r\n trace(\"Maximum number of connections exceeded\");\r\n }\r\n }\r\n\r\n // If we have a connection, set the last time accessed,\r\n // the use count, and the in use flag\r\n if (connectionObject != null) {\r\n connectionObject.inUse = true;\r\n connectionObject.useCount++;\r\n touch(connectionObject);\r\n con = connectionObject.con;\r\n }\r\n \r\n return con;\r\n }\r\n\r\n /**\r\n *

Places the connection back into the connection pool,\r\n * or closes the connection if the maximum use count has\r\n * been reached\r\n *\r\n * @param Connection object to close\r\n */\r\n public synchronized void close(java.sql.Connection con)\r\n {\r\n // Find the connection in the pool\r\n int index = find(con);\r\n \r\n if (index != -1) {\r\n ConnectionObject co = (ConnectionObject)\r\n m_pool.elementAt(index);\r\n \r\n // If the use count exceeds the max, remove it from\r\n // the pool.\r\n if ((m_ConnectionUseCount > 0) &&\r\n (co.useCount >= m_ConnectionUseCount)) {\r\n trace(\"Connection use count exceeded\");\r\n removeFromPool(index);\r\n }\r\n else {\r\n // Clear the use count and reset the time last used\r\n touch(co);\r\n co.inUse = false;\r\n }\r\n }\r\n }\r\n \r\n /**\r\n *

Prints the contents of the connection pool to the\r\n * standard output device\r\n */\r\n public void printPool()\r\n {\r\n System.out.println(\"--ConnectionPool--\");\r\n if (m_pool != null) {\r\n for (int i = 0; i < m_pool.size(); i++) {\r\n ConnectionObject co = (ConnectionObject)\r\n m_pool.elementAt(i);\r\n System.out.println(\"\" + i + \"=\" + co);\r\n }\r\n }\r\n }\r\n \r\n /**\r\n *

Removes the ConnectionObject from the pool at the\r\n * given index\r\n *\r\n * @param index Index into the pool vector\r\n */\r\n private synchronized void removeFromPool(int index)\r\n {\r\n // Make sure the pool and index are valid\r\n if (m_pool != null) {\r\n\r\n if (index < m_pool.size()) {\r\n\r\n // Get the ConnectionObject and close the connection\r\n ConnectionObject co = (ConnectionObject)\r\n m_pool.elementAt(index);\r\n close(co);\r\n\r\n // Remove the element from the pool\r\n m_pool.removeElementAt(index);\r\n }\r\n }\r\n }\r\n \r\n /**\r\n *

Closes the connection in the given ConnectionObject\r\n *\r\n * @param connectObject ConnectionObject\r\n */\r\n private void close(ConnectionObject connectionObject)\r\n {\r\n if (connectionObject != null) {\r\n if (connectionObject.con != null) {\r\n try {\r\n \r\n // Close the connection\r\n connectionObject.con.close();\r\n }\r\n catch (Exception ex) {\r\n // Ignore any exceptions during close\r\n }\r\n\r\n // Clear the connection object reference\r\n connectionObject.con = null;\r\n }\r\n }\r\n }\r\n \r\n /**\r\n *

Loads the given configuration file. All global\r\n * properties (such as JDBCDriver) will be\r\n * read and removed from the properties list. Any leftover\r\n * properties will be returned. Returns null if the\r\n * properties could not be loaded\r\n *\r\n * @param name Configuration file name\r\n * @return true if the configuration file was loaded\r\n */\r\n private boolean loadConfig(String name)\r\n throws Exception\r\n {\r\n boolean rc = false;\r\n\r\n // Get our class loader\r\n ClassLoader cl = getClass().getClassLoader();\r\n\r\n // Attempt to open an input stream to the configuration file.\r\n // The configuration file is considered to be a system\r\n // resource.\r\n java.io.InputStream in;\r\n \r\n if (cl != null) {\r\n in = cl.getResourceAsStream(name);\r\n }\r\n else {\r\n in = ClassLoader.getSystemResourceAsStream(name);\r\n }\r\n\r\n // If the input stream is null, then the configuration file\r\n // was not found\r\n if (in == null) {\r\n throw new Exception(\"ConnectionPool configuration file \'\" +\r\n name + \"\' not found\");\r\n }\r\n else {\r\n try {\r\n m_JDBCProperties = new java.util.Properties();\r\n \r\n // Load the configuration file into the properties table\r\n m_JDBCProperties.load(in);\r\n\r\n // Got the properties. Pull out the properties that we\r\n // are interested in\r\n m_JDBCDriver = consume(m_JDBCProperties, \"JDBCDriver\");\r\n m_JDBCConnectionURL = consume(m_JDBCProperties,\r\n \"JDBCConnectionURL\");\r\n m_ConnectionPoolSize = consumeInt(m_JDBCProperties,\r\n \"ConnectionPoolSize\");\r\n m_ConnectionPoolMax = consumeInt(m_JDBCProperties,\r\n \"ConnectionPoolMax\");\r\n m_ConnectionTimeout = consumeInt(m_JDBCProperties,\r\n \"ConnectionTimeout\");\r\n m_ConnectionUseCount = consumeInt(m_JDBCProperties,\r\n \"ConnectionUseCount\");\r\n rc = true;\r\n }\r\n finally {\r\n // Always close the input stream\r\n if (in != null) {\r\n try {\r\n in.close();\r\n }\r\n catch (Exception ex) {\r\n }\r\n }\r\n }\r\n }\r\n return rc;\r\n }\r\n\r\n /**\r\n *

Consumes the given property and returns the value.\r\n *\r\n * @param properties Properties table\r\n * @param key Key of the property to retrieve and remove from\r\n * the properties table\r\n * @return Value of the property, or null if not found\r\n */\r\n private String consume(java.util.Properties p, String key)\r\n {\r\n String s = null;\r\n\r\n if ((p != null) &&\r\n (key != null)) {\r\n\r\n // Get the value of the key\r\n s = p.getProperty(key);\r\n \r\n // If found, remove it from the properties table\r\n if (s != null) {\r\n p.remove(key);\r\n }\r\n }\r\n return s;\r\n }\r\n\r\n /**\r\n *

Consumes the given property and returns the integer\r\n * value.\r\n *\r\n * @param properties Properties table\r\n * @param key Key of the property to retrieve and remove from\r\n * the properties table\r\n * @return Value of the property, or -1 if not found\r\n */\r\n private int consumeInt(java.util.Properties p, String key)\r\n {\r\n int n = -1;\r\n\r\n // Get the String value\r\n String value = consume(p, key);\r\n\r\n // Got a value; convert to an integer\r\n if (value != null) {\r\n try {\r\n n = Integer.parseInt(value);\r\n }\r\n catch (Exception ex) {\r\n }\r\n }\r\n return n;\r\n }\r\n\r\n /**\r\n *

Creates the initial connection pool. A timer thread\r\n * is also created so that connection timeouts can be\r\n * handled.\r\n *\r\n * @return true if the pool was created\r\n */\r\n private void createPool() throws Exception\r\n {\r\n // Sanity check our properties\r\n if (m_JDBCDriver == null) {\r\n throw new Exception(\"JDBCDriver property not found\");\r\n }\r\n if (m_JDBCConnectionURL == null) {\r\n throw new Exception(\"JDBCConnectionURL property not found\");\r\n }\r\n if (m_ConnectionPoolSize < 0) {\r\n throw new Exception(\"ConnectionPoolSize property not found\");\r\n }\r\n if (m_ConnectionPoolSize == 0) {\r\n throw new Exception(\"ConnectionPoolSize invalid\");\r\n }\r\n if (m_ConnectionPoolMax < m_ConnectionPoolSize) {\r\n trace(\"WARNING - ConnectionPoolMax is invalid and will \" +\r\n \"be ignored\");\r\n m_ConnectionPoolMax = -1;\r\n }\r\n if (m_ConnectionTimeout < 0) {\r\n // Set the default to 30 minutes\r\n m_ConnectionTimeout = 30;\r\n }\r\n\r\n // Dump the parameters we are going to use for the pool.\r\n // We don\'t know what type of servlet environment we will\r\n // be running in - this may go to the console or it\r\n // may be redirected to a log file\r\n trace(\"JDBCDriver = \" + m_JDBCDriver);\r\n trace(\"JDBCConnectionURL = \" + m_JDBCConnectionURL);\r\n trace(\"ConnectionPoolSize = \" + m_ConnectionPoolSize);\r\n trace(\"ConnectionPoolMax = \" + m_ConnectionPoolMax);\r\n trace(\"ConnectionUseCount = \" + m_ConnectionUseCount);\r\n trace(\"ConnectionTimeout = \" + m_ConnectionTimeout +\r\n \" seconds\");\r\n\r\n // Also dump any additional JDBC properties\r\n java.util.Enumeration enum = m_JDBCProperties.keys();\r\n while (enum.hasMoreElements()) {\r\n String key = (String) enum.nextElement();\r\n String value = m_JDBCProperties.getProperty(key);\r\n trace(\"(JDBC Property) \" + key + \" = \" + value);\r\n }\r\n\r\n // Attempt to create a new instance of the specified\r\n // JDBC driver. Well behaved drivers will register\r\n // themselves with the JDBC DriverManager when they\r\n // are instantiated\r\n trace(\"Registering \" + m_JDBCDriver);\r\n java.sql.Driver d = (java.sql.Driver)\r\n Class.forName(m_JDBCDriver).newInstance();\r\n \r\n // Create the vector for the pool\r\n m_pool = new java.util.Vector();\r\n\r\n // Bring the pool to the minimum size\r\n fillPool(m_ConnectionPoolSize);\r\n }\r\n\r\n /**\r\n *

Adds a new connection to the pool\r\n *\r\n * @return Index of the new pool entry, or -1 if an\r\n * error has occurred\r\n */\r\n private int addConnection()\r\n {\r\n int index = -1;\r\n\r\n try {\r\n // Calculate the new size of the pool\r\n int size = m_pool.size() + 1;\r\n\r\n // Create a new entry\r\n fillPool(size);\r\n\r\n // Set the index pointer to the new connection if one\r\n // was created\r\n if (size == m_pool.size()) {\r\n index = size - 1;\r\n }\r\n }\r\n catch (Exception ex) {\r\n ex.printStackTrace();\r\n }\r\n return index;\r\n }\r\n \r\n /**\r\n *

Brings the pool to the given size\r\n */\r\n private synchronized void fillPool(int size) throws Exception\r\n {\r\n boolean useProperties = true;\r\n String userID = null;\r\n String password = null;\r\n \r\n // If the only properties present are the user id and\r\n // password, get the connection using them instead of\r\n // the properties object\r\n if (m_JDBCProperties != null) {\r\n \r\n // Make sure there are only 2 properties, and they are\r\n // the user id and password\r\n if (m_JDBCProperties.size() == 2) {\r\n userID =\r\n getPropertyIgnoreCase(m_JDBCProperties, \"user\");\r\n password =\r\n getPropertyIgnoreCase(m_JDBCProperties, \"password\");\r\n\r\n // If all we\'ve got is a user id and password then\r\n // don\'t use the properties\r\n if ((userID != null) && (password != null)) {\r\n useProperties = false;\r\n }\r\n }\r\n \r\n }\r\n \r\n // Loop while we need to create more connections\r\n while (m_pool.size() < size) {\r\n \r\n ConnectionObject co = new ConnectionObject();\r\n\r\n // Create the connection\r\n if (useProperties) {\r\n co.con = DriverManager.getConnection(m_JDBCConnectionURL,\r\n m_JDBCProperties);\r\n }\r\n else {\r\n co.con = DriverManager.getConnection(m_JDBCConnectionURL,\r\n userID, password);\r\n }\r\n \r\n // Do some sanity checking on the first connection in\r\n // the pool\r\n if (m_pool.size() == 0) {\r\n\r\n // Get the maximum number of simultaneous connections\r\n // as reported by the JDBC driver\r\n java.sql.DatabaseMetaData md = co.con.getMetaData();\r\n m_MaxConnections = md.getMaxConnections();\r\n }\r\n\r\n // Give a warning if the size of the pool will exceed\r\n // the maximum number of connections allowed by the\r\n // JDBC driver\r\n if ((m_MaxConnections > 0) &&\r\n (size > m_MaxConnections)) {\r\n trace(\"WARNING: Size of pool will exceed safe maximum of \" +\r\n m_MaxConnections);\r\n }\r\n\r\n // Clear the in use flag\r\n co.inUse = false;\r\n \r\n // Set the last access time\r\n touch(co);\r\n \r\n m_pool.addElement(co);\r\n }\r\n }\r\n\r\n /**\r\n * Gets a the named propery, ignoring case. Returns null if\r\n * not found\r\n * @param p The property set\r\n * @param name The property name\r\n * @return The value of the propery, or null if not found\r\n */\r\n private String getPropertyIgnoreCase(java.util.Properties p,\r\n String name)\r\n {\r\n if ((p == null) || (name == null)) return null;\r\n \r\n String value = null;\r\n \r\n // Get an enumeration of the property names\r\n java.util.Enumeration enum = p.propertyNames();\r\n \r\n // Loop through the enum, looking for the given property name\r\n while (enum.hasMoreElements()) {\r\n String pName = (String) enum.nextElement();\r\n if (pName.equalsIgnoreCase(name)) {\r\n value = p.getProperty(pName);\r\n break;\r\n }\r\n }\r\n \r\n return value;\r\n }\r\n \r\n /**\r\n *

Find the given connection in the pool\r\n *\r\n * @return Index into the pool, or -1 if not found\r\n */\r\n private int find(java.sql.Connection con)\r\n {\r\n int index = -1;\r\n\r\n // Find the matching Connection in the pool\r\n if ((con != null) &&\r\n (m_pool != null)) {\r\n for (int i = 0; i < m_pool.size(); i++) {\r\n ConnectionObject co = (ConnectionObject)\r\n m_pool.elementAt(i);\r\n if (co.con == con) {\r\n index = i;\r\n break;\r\n }\r\n }\r\n }\r\n return index;\r\n }\r\n \r\n /**\r\n *

Called by the timer each time a clock cycle expires.\r\n * This gives us the opportunity to timeout connections\r\n */\r\n public synchronized void TimerEvent(Object object)\r\n {\r\n // No pool means no work\r\n if (m_pool == null) {\r\n return;\r\n }\r\n\r\n // Get the current time in milliseconds\r\n long now = System.currentTimeMillis();\r\n \r\n // Check for any expired connections and remove them\r\n for (int i = m_pool.size() - 1; i >= 0; i--) {\r\n ConnectionObject co = (ConnectionObject)\r\n m_pool.elementAt(i);\r\n\r\n // If the connection is not in use and it has not been\r\n // used recently, remove it\r\n if (!co.inUse) {\r\n if ((m_ConnectionTimeout > 0) &&\r\n (co.lastAccess +\r\n (m_ConnectionTimeout * 1000) < now)) {\r\n removeFromPool(i);\r\n }\r\n }\r\n }\r\n\r\n // Remove any connections that are no longer open\r\n for (int i = m_pool.size() - 1; i >= 0; i--) {\r\n ConnectionObject co = (ConnectionObject)\r\n m_pool.elementAt(i);\r\n try {\r\n // If the connection is closed, remove it from the pool\r\n if (co.con.isClosed()) {\r\n trace(\"Connection closed unexpectedly\");\r\n removeFromPool(i);\r\n }\r\n }\r\n catch (Exception ex) {\r\n }\r\n }\r\n\r\n // Now ensure that the pool is still at it\'s minimum size\r\n try {\r\n if (m_pool != null) {\r\n if (m_pool.size() < m_ConnectionPoolSize) {\r\n fillPool(m_ConnectionPoolSize);\r\n }\r\n }\r\n }\r\n catch (Exception ex) {\r\n ex.printStackTrace();\r\n }\r\n }\r\n \r\n /**\r\n *

Sets the last access time for the given ConnectionObject\r\n */\r\n private void touch(ConnectionObject co)\r\n {\r\n if (co != null) {\r\n co.lastAccess = System.currentTimeMillis();\r\n }\r\n }\r\n \r\n /**\r\n *

Trace the given string\r\n */\r\n private void trace(String s)\r\n {\r\n System.out.println(\"ConnectionPool: \" + s);\r\n }\r\n}\r\n\r\n// This package-private class is used to represent a single\r\n// connection object\r\nclass ConnectionObject\r\n{\r\n // The JDBC Connection\r\n public java.sql.Connection con;\r\n\r\n // true if this connection is currently in use\r\n public boolean inUse;\r\n\r\n // The last time (in milliseconds) that this connection was used\r\n public long lastAccess;\r\n\r\n // The number of times this connection has been used\r\n public int useCount;\r\n\r\n /**\r\n *

Determine if the connection is available\r\n *\r\n * @return true if the connection can be used\r\n */\r\n public boolean isAvailable()\r\n {\r\n boolean available = false;\r\n\r\n try {\r\n\r\n // To be available, the connection cannot be in use\r\n // and must be open\r\n if (con != null) {\r\n if (!inUse &&\r\n !con.isClosed()) {\r\n available = true;\r\n }\r\n }\r\n }\r\n catch (Exception ex) {\r\n }\r\n \r\n return available;\r\n }\r\n \r\n /**\r\n *

Convert the object contents to a String\r\n */\r\n public String toString()\r\n {\r\n return \"Connection=\" + con + \",inUse=\" + inUse +\r\n \",lastAccess=\" + lastAccess + \",useCount=\" + useCount;\r\n }\r\n}\r\n[/code]','takaka','2002-02-28 16:08:36','2002-02-28 16:08:36',0,'takaka',176),('svg','[Batik SVG Toolkit|http://xml.apache.org/batik/index.html]\r\n[VR技术应用-SVG|http://www.86vr.net/plugs/svg/svg.htm]\r\n[一个纯SVG的网站|http://www.svgspider.com/]','takaka','2002-02-28 18:10:31','2002-02-28 18:10:31',0,'takaka',177),('lua','=== High Performance Script Language ===\r\n\r\n[HOME | http://www.lua.org]','61.151.236.152','2002-03-01 14:06:58','2002-03-01 14:06:58',0,'61.151.236.152',178),('自由开发者','\'\'\'自由开发者就是满腔热血没处发泄的开发者,多半是刚刚毕业的或没有毕业的学生\'\'\'\r\n--未必,国外不是有很多这样的开发者马?看国内,也不是你说的那样,看看我们的破门 :) 2002/02/28[浆糊]\r\n----\r\n不要把我们这些开发了好多年也没有开发出什么有用的东东的同志排除在外嘛。[panhwa]\r\n----','hdw1978','2002-03-01 14:20:20','2002-03-01 15:47:41',0,'panhwa',179),('TestFirst','----\r\n测试在先,极端编程的关键实践之一。\r\n----','61.141.211.93','2002-03-01 15:07:24','2002-03-01 15:36:06',0,'panhwa',180),('资料翻译','----\r\n先来一篇Kent的原文,哈哈。\r\nBeckTestingFramework\r\n----','panhwa','2002-03-01 15:42:33','2002-03-01 15:42:33',0,'panhwa',181),('BeckTestingFramework','可惜格式和图像没法copy [panhwa]\r\n----\r\nBeck Testing Framework\r\n----\r\nSimple Smalltalk Testing:\r\nWith Patterns\r\n\r\nKent Beck, \r\nFirst Class Software, Inc.\r\nKentBeck@compuserve.com\r\n\r\nThis software and documentation is provided as a service to the programming community. Distribute it free as you see fit. First Class Software, Inc. provides no warranty of any kind, express or implied.\r\n\r\n(Transcribed to HTML by Ron Jeffries. The software is available for many Smalltalks, and for C++, on my FTP site.)\r\n\r\nIntroduction\r\n\r\nSmalltalk has suffered because it lacked a testing culture. This column describes a simple testing strategy and a framework to support it. The testing strategy and framework are not intended to be complete solutions, but rather a starting point from which industrial strength tools and procedures can be constructed.\r\n\r\nThe paper is divided into three sections: \r\n\r\nPhilosophy - Describes the philosophy of writing and running tests embodied by the framework. Read this section for general background. \r\nCookbook - A simple pattern system for writing your own tests. \r\nFramework - A literate program version of the testing framework. Read this for in-depth knowledge of how the framework operates. \r\nExample - An example of using the testing framework to test part of the methods in Set. \r\nPhilosophy\r\n\r\nI don’t like user interface-based tests. In my experience, tests based on user interface scripts are too brittle to be useful. When I was on a project where we used user interface testing, it was common to arrive in the morning to a test report with twenty or thirty failed tests. A quick examination would show that most or all of the failures were actually the program running as expected. Some cosmetic change in the interface had caused the actual output to no longer match the expected output. Our testers spent more time keeping the tests up to date and tracking down false failures and false successes than they did writing new tests.\r\n\r\nMy solution is to write the tests and check results in Smalltalk. While this approach has the disadvantage that your testers need to be able to write simple Smalltalk programs, the resulting tests are much more stable.\r\n\r\nFailures and Errors\r\n\r\nThe framework distinguishes between failures and errors. A failure is an anticipated problem. When you write tests, you check for expected results. If you get a different answer, that is a failure. An error is more catastrophic, a error condition you didn\'t check for.\r\n\r\nUnit testing\r\n\r\nI recommend that developers write their own unit tests, one per class. The framework supports the writing of suites of tests, which can be attached to a class. I recommend that all classes respond to the message \"testSuite\", returning a suite containing the unit tests. I recommend that developers spend 25-50% of their time developing tests.\r\n\r\nIntegration testing\r\n\r\nI recommend that an independent tester write integration tests. Where should the integration tests go? The recent movement of user interface frameworks to better programmatic access provides one answer- drive the user interface, but do it with the tests. In VisualWorks (the dialect used in the implementation below), you can open an ApplicationModel and begin stuffing values into its ValueHolders, causing all sorts of havoc, with very little trouble.\r\n\r\nRunning tests\r\n\r\nOne final bit of philosophy. It is tempting to set up a bunch of test data, then run a bunch of tests, then clean up. In my experience, this always causes more problems that it is worth. Tests end up interacting with one another, and a failure in one test can prevent subsequent tests from running. The testing framework makes it easy to set up a common set of test data, but the data will be created and thrown away for each test. The potential performance problems with this approach shouldn\'t be a big deal because suites of tests can run unobserved.\r\n\r\nCookbook\r\n\r\nHere is a simple pattern system for writing tests. The patterns are:\r\n\r\nPattern Purpose \r\nFixture Create a common test fixture. \r\nTest Case Create the stimulus for a test case. \r\nCheck Check the response for a test case. \r\nTest Suite Aggregate TestCases. \r\n\r\nFixture\r\n\r\nHow do you start writing tests?\r\n\r\nTesting is one of those impossible tasks. You’d like to be absolutely complete, so you can be sure the software will work. On the other hand, the number of possible states of your program is so large that you can’t possibly test all combinations.\r\n\r\nIf you start with a vague idea of what you’ll be testing, you’ll never get started. Far better to start with a single configuration whose behavior is predictable. As you get more experience with your software, you will be able to add to the list of configurations.\r\n\r\nSuch a configuration is called a \"fixture\". Examples of fixtures are:\r\n\r\nFixture Predictions \r\n1.0 and 2.0 Easy to predict answers to arithmetic problems \r\nNetwork connection to a known machine Responses to network packets \r\n#() and #(1 2 3) Results of sending testing messages \r\n\r\nBy choosing a fixture you are saying what you will and won’t test for. A complete set of tests for a community of objects will have many fixtures, each of which will be tested many ways.\r\n\r\nDesign a test fixture. \r\n\r\nSubclass TestCase \r\nAdd an instance variable for each known object in the fixture \r\nOverride setUp to initialize the variables \r\nIn the example, the test fixture is two Sets, one empty and one with elements. First we subclass TestCase and add instance variables for the objects we will need to reference later:\r\n\r\nClass: SetTestCase\r\n superclass: TestCase\r\n instance variables: empty full\r\nThen we override setUp to create the objects for the fixture:\r\n\r\nSetTestCase>>setUp\r\n empty := Set new.\r\n full := Set\r\n with: #abc\r\n with: 5\r\nTest Case\r\n\r\nYou have a Fixture, what do you do next?\r\n\r\nHow do you represent a single unit of testing?\r\n\r\nYou can predict the results of sending a message to a fixture. You need to represent such a predictable situation somehow.\r\n\r\nThe simplest way to represent this is interactively. You open an Inspector on your fixture and you start sending it messages. There are two drawbacks to this method. First, you keep sending messages to the same fixture. If a test happens to mess that object up, all subsequent tests will fail, even though the code may be correct. More importantly, though, you can’t easily communicate interactive tests to others. If you give someone else your objects, the only way they have of testing them is to have you come and inspect them.\r\n\r\nBy representing each predictable situation as an object, each with its own fixture, no two tests will ever interfere. Also, you can easily give tests to others to run.\r\n\r\nRepresent a predictable reaction of a fixture as a method. \r\n\r\nAdd a method to TestCase subclass \r\nStimulate the fixture in the method \r\nThe example code shows this. We can predict that adding \"5\" to an empty Set will result in \"5\" being in the set. We add a method to our TestCase subclass. In it we stimulate the fixture:\r\n\r\nSetTestCase>>testAdd\r\n empty add: 5.\r\n ...\r\nOnce you have stimulated the fixture, you need to add a Check to make sure your prediction came true.\r\n\r\nCheck\r\n\r\nA Test Case stimulates a Fixture.\r\n\r\nHow do you test for expected results?\r\n\r\nIf you’re testing interactively, you check for expected results directly. If you are looking for a particular return value, you use \"print it\", and make sure that you got the right object back. If you are looking for side effects, you use the Inspector.\r\n\r\nSince tests are in their own objects, you need a way to programmatically look for problems. One way to accomplish this is to use the standard error handling mechanism (Object>>error:) with testing logic to signal errors:\r\n\r\n2 + 3 = 5 ifFalse: [self error: ‘Wrong answer’]\r\nWhen you’re testing, you’d like to distinguish between errors you are checking for, like getting six as the sum of two and three, and errors you didn’t anticipate, like subscripts being out of bounds or messages not being understood.\r\n\r\nThere’s not a lot you can do about unanticipated errors (if you did something about them, they wouldn’t be unanticipated any more, would they?) When a catastrophic error occurs, the framework stops running the test case, records the error, and runs the next test case. Since each test case has its own fixture, the error in the previous case will not affect the next.\r\n\r\nThe testing framework makes checking for expected values simple by providing a method, \"should:\", that takes a Block as an argument. If the Block evaluates to true, everything is fine. Otherwise, the test case stops running, the failure is recorded, and the next test case runs.\r\n\r\nTurn checks into a Block evaluating to a Boolean. Send the Block as the parameter to \"should:\".\r\n\r\nIn the example, after stimulating the fixture by adding \"5\" to an empty Set, we want to check and make sure it’s in there:\r\n\r\nSetTestCase>>testAdd\r\n empty add: 5.\r\n self should: [empty includes: 5]\r\nThere is a variant on TestCase>>should:. TestCase>>shouldnt: causes the test case to fail if the Block argument evaluates to true. It is there so you don’t have to use \"(...) not\".\r\n\r\nOnce you have a test case this far, you can run it. Create an instance of your TestCase subclass, giving it the selector of the testing method. Send \"run\" to the resulting object:\r\n\r\n(SetTestCase selector: #testAdd) run\r\nIf it runs to completion, the test worked. If you get a walkback, something went wrong.\r\n\r\nTest Suite\r\n\r\nYou have several Test Cases.\r\n\r\nHow do you run lots of tests?\r\n\r\nAs soon as you have two test cases running, you’ll want to run them both one after the other without having to execute two do it’s. You could just string together a bunch of expressions to create and run test cases. However, when you then wanted to run \"this bunch of cases and that bunch of cases\" you’d be stuck.\r\n\r\nThe testing framework provides an object to represent \"a bunch of tests\", TestSuite. A TestSuite runs a collection of test cases and reports their results all at once. Taking advantage of polymorphism, TestSuites can also contain other TestSuites, so you can put Joe’s tests and Tammy’s tests together by creating a higher level suite.\r\n\r\nCombine test cases into a test suite.\r\n\r\n(TestSuite named: ‘Money’)\r\n add: (MoneyTestCase selector: #testAdd);\r\n add: (MoneyTestCase selector: #testSubtract);\r\n run\r\nThe result of sending \"run\" to a TestSuite is a TestResult object. It records all the test cases that caused failures or errors, and the time at which the suite was run.\r\n\r\nAll of these objects are suitable for storing with the ObjectFiler or BOSS. You can easily store a suite, then bring it in and run it, comparing results with previous runs.\r\n\r\nFramework\r\n\r\nThis section presents the code of the testing framework in literate program style. It is here in case you are curious about the implementation of the framework, or you need to modify it in any way.\r\n\r\nWhen you talk to a tester, the smallest unit of testing they talk about is a test case. TestCase is a User’s Object, representing a single test case.\r\n\r\nClass: TestCase\r\n superclass: Object\r\nTesters talk about setting up a \"test fixture\", which is an object structure with predictable responses, one that is easy to create and to reason about. Many different test cases can be run against the same fixture.\r\n\r\nThis distinction is represented in the framework by giving each TestCase a Pluggable Selector. The variable behavior invoked by the selector is the test code. All instances of the same class share the same fixture.\r\n\r\nClass: TestCase\r\n superclass: Object\r\n instance variables: selector\r\n class variable: FailedCheckSignal\r\nTestCase class>>selector: is a Complete Creation Method.\r\n\r\nTestCase class>>selector: aSymbol\r\n ^self new setSelector: aSymbol\r\nTestCase>>setSelector: is a Creation Parameter Method.\r\n\r\nTestCase>>setSelector: aSymbol\r\n selector := aSymbol\r\nSubclasses of TestCase are expected to create and destroy test fixtures by overriding the Hook Methods setUp and tearDown, respectively. TestCase itself provides Stub Methods for these methods which do nothing.\r\n\r\nTestCase>>setUp\r\n \"Run whatever code you need to get ready for the test to run.\"\r\n\r\nTestCase>>tearDown\r\n \"Release whatever resources you used for the test.\"\r\nThe simplest way to run a TestCase is just to send it the message \"run\". Run invokes the set up code, performs the selector, the runs the tear down code. Notice that the tear down code is run regardless of whether there is an error in performing the test. Invoking setUp and tearDown could be encapsulated in an Execute Around Method, but since they aren’t part of the public interface they are just open coded here.\r\n\r\nTestCase>>run\r\n self setUp.\r\n [self performTest] valueNowOrOnUnwindDo: [self tearDown]\r\nPerformTest just performs the selector.\r\n\r\nTestCase>>performTest\r\n self perform: selector\r\nA single TestCase is hardly ever interesting, once you have gotten it running. In production, you will want to run many TestCases at a time. Testers talk of running test \"suites\". TestSuite is a User’s Object. It is a Composite of Test Cases.\r\n\r\nClass: TestSuite\r\n superclass: Object\r\n instance variables: name testCases\r\nTestSuites are Named Objects. This makes them easy to identify so they can be simply stored on and retrieved from secondary storage. Here is the Complete Creation Method and Creation Parameter Method.\r\n\r\nTestSuite class>>named: aString\r\n ^self new setName: aString\r\n\r\nTestSuite>>setName: aString\r\n name := aString.\r\n testCases := OrderedCollection new\r\nThe testCases instance variable is initialized right in TestSuite>>setName: because I don’t anticipate needing it to be any different kind of collection.\r\n\r\nTestSuites have an Accessing Method for their name, in anticipation of user interfaces which will have to display them.\r\n\r\nTestSuite>>name\r\n ^name\r\nTestSuites have Collection Accessor Methods for adding one or more TestCases.\r\n\r\nTestSuite>>addTestCase: aTestCase\r\n testCases add: aTestCase\r\n\r\nTestSuite>>addTestCases: aCollection\r\n aCollection do: [:each | self addTestCase: each]\r\nWhen you run a TestSuite, you\'d like all of its TestCases to run. It\'s not quite that simple, though. If you have a suite that represents the acceptance test for your application, after it runs you\'d like to know how long the suite ran and which of the cases had problems. This is information you would like to be able to store away for future reference. \r\n\r\nTestResult is a Result Object for a TestSuite. Running a TestSuite returns a TestResult which records the information described above- the start and stop times of the run, the name of the suite, and any failures or errors.\r\n\r\nClass: TestResult\r\n superclass: Object\r\n instance variables: startTime stopTime testName failures errors\r\nWhen you run a TestSuite, it creates a TestResult which is timestamped before and after the TestCases are run. \r\n\r\nTestSuite>>run\r\n | result |\r\n result := self defaultTestResult.\r\n result start.\r\n self run: result.\r\n result stop.\r\n ^result\r\nTestCase>>run and TestSuite>>run are not polymorphically equivalent. This is a problem that needs to be addressed in future versions of the framework. One option is to have a TestCaseResult which measures time in milliseconds to enable performance regression testing.\r\n\r\nThe default TestResult is constructed by the TestSuite, using a Default Class.\r\n\r\nTestSuite>>defaultTestResult\r\n ^self defaultTestResultClass test: self\r\n\r\nTestSuite>>defaultTestResultClass \r\n ^TestResult\r\nA TestResult Complete Creation Method takes a TestSuite.\r\n\r\nTestResult class>>test: aTest\r\n ^self new setTest: aTest\r\n\r\nTestResult>>setTest: aTest\r\n testName := aTest name.\r\n failures := OrderedCollection new.\r\n errors := OrderedCollection new\r\nTestResults are timestamped by sending them the messages start and stop. Since start and stop need to be executed in pairs, they could be hidden behind an Execute Around Method. This is something else to do later.\r\n\r\nTestResult>>start\r\n startTime := Date dateAndTimeNow\r\nTestResult>>stop\r\n stopTime := Date dateAndTimeNow\r\nWhen a TestSuite runs for a given TestResult, it simply runs each of its TestCases with that TestResult.\r\n\r\nTestSuite>>run: aTestResult\r\n testCases do: [:each | each run: aTestResult]\r\n#run: is the Composite selector in TestSuite and TestCase, so you can construct TestSuites which contain other TestSuites, instead of or in addition to containing TestCases.\r\n\r\nWhen a TestCase runs for a given TestResult, it should either silently run correctly, add an error to the TestResult, or add a failure to the TestResult. Catching errors is simple-use the system supplied errorSignal. Catching failures must be supported by the TestCase itself. First, we need a Class Initialization Method to create a Signal. \r\n\r\nTestCase class>>initialize\r\n FailedCheckSignal := self errorSignal newSignal\r\n notifierString: \'Check failed - \';\r\n nameClass: self message: #checkSignal\r\nNow we need an Accessing Method.\r\n\r\nTestCase>>failedCheckSignal\r\n ^FailedCheckSignal\r\nNow, when the TestCase runs with a TestResult, it must catch errors and failures and inform the TestResult, and it must run the tearDown code regardless of whether the test executed correctly. This results in the ugliest method in the framework, because there are two nested error handlers and valueNowOrOnUnwindDo: in one method. There is a missing pattern expressed here and in TestCase>>run about using ensure: to safely run the second halt of an Execute Around Method.\r\n\r\nTestCase>>run: aTestResult\r\n self setUp.\r\n [self errorSignal\r\n handle: [:ex | aTestResult error: ex errorString in: self]\r\n do: \r\n [self failedCheckSignal\r\n handle: [:ex | aTestResult failure: ex errorString in: self]\r\n do: [self performTest]]] valueNowOrOnUnwindDo: [self tearDown]\r\nWhen a TestResult is told that an error or failure happened, it records that fact in one of its two collections. For simplicity, the record is just a two element array, but it probably should be a first class object with a timestamp and more details of the blowup.\r\n\r\nTestResult>>error: aString in: aTestCase\r\n errors add: (Array with: aTestCase with: aString)\r\n\r\nTestResult>>failure: aString in: aTestCase\r\n failures add: (Array with: aTestCase with: aString)\r\nThe error case gets invoked if there is ever an uncaught error (for example, message not understood) in the testing method. How do the failures get invoked? TestCase provides two methods that simplify checking for failure. The first, should: aBlock, signals a failure if the evaluation of aBlock returns false. The second, shouldnt: aBlock, does just the opposite.\r\n\r\nshould: aBlock\r\n aBlock value ifFalse: [self failedCheckSignal raise]\r\n\r\nshouldnt: aBlock\r\n aBlock value ifTrue: [self failedCheckSignal raise]\r\nTesting methods will run code to stimulate the test fixture, then check the results inside should: and shouldnt: blocks.\r\n\r\nExample\r\n\r\nOkay, that\'s how it works, how do you use it? Here\'s a short example that tests a few of the messages supported by Sets. First we subclass TestCase, because we\'ll always want a couple of interesting Sets around to play with.\r\n\r\nClass: SetTestCase\r\n superclass: TestCase\r\n instance variables: empty full\r\nNow we need to initialize these variables, so we subclass setUp.\r\n\r\nSetTestCase>>setUp\r\n empty := Set new.\r\n full := Set \r\n with: #abc \r\n with: 5\r\nNow we need a testing method. Let\'s test to see if adding an element to a Set really works.\r\n\r\nSetTestCase>>testAdd\r\n empty add: 5.\r\n self should: [empty includes: 5]\r\nNow we can run a test case by evaluating \"(SetTestCase selector: #testAdd) run\".\r\n\r\nHere\'s a case that uses shouldnt:. It reads \"after removing 5 from full, full should include #abc and it shouldn\'t include 5.\"\r\n\r\nSetTestCase>>testRemove\r\n full remove: 5.\r\n self should: [full includes: #abc].\r\n self shouldnt: [full includes: 5]\r\nHere\'s one that makes sure an error is signalled if you try to do keyed access.\r\n\r\nSetTestCase>>testIllegal\r\n self should: [self errorSignal handle: [:ex | true] do: [empty at: 5. false]]\r\nNow we can put together a TestSuite.\r\n\r\n| suite |\r\nsuite := TestSuite named: \'Set Tests\'.\r\nsuite addTestCase: (SetTestCase selector: #testAdd).\r\nsuite addTestCase: (SetTestCase selector: #testRemove).\r\nsuite addTestCase: (SetTestCase selector: #testIllegal).\r\n^suite\r\nHere is an Object Explorer picture of the suite and the TestResult we get back when we run it.\r\n\r\n\r\n\r\nThe test methods shown above only cover a fraction of the functionality in Set. Writing tests for all the public methods in Set is a daunting task. However, as Hal Hildebrand told me after using an earlier version of this framework, \"If the underlying objects don\'t work, nothing else matters. You have to write the tests to make sure everything is working.\"\r\n\r\n----\r\n\'\'是从哪里copy过来的?\'\' --2002/03/01 by [takaka]','panhwa','2002-03-01 15:43:59','2002-03-01 21:20:32',0,'takaka',182),('panhwa','[user=panhwa]\r\n一间小公司的软件项目经理。\r\n最近的兴趣:\r\n项目过程改进\r\n编码风格\r\n单元测试\r\n工作量估算\r\n','panhwa','2002-03-01 15:52:37','2002-03-01 16:22:45',0,'浆糊',183),('hdw1978','[user=hdw1978]','61.151.236.152','2002-03-01 18:03:41','2002-03-01 18:03:41',0,'61.151.236.152',184),('haha','delete','haha12','2002-03-01 18:29:22','2002-03-07 12:05:49',0,'haha12',185),('阿','Delete','haha12','2002-03-01 18:31:48','2002-03-01 18:32:27',0,'haha12',186),('幽柱','[user=幽柱]\r\n兄弟,这样不就行了.','浆糊','2002-03-01 20:46:18','2002-03-01 20:46:18',0,'浆糊',187),('什么是XP?','[h1]什么是极端编程?[/h1]\r\nRon Jeffries 11/08/2001 \r\n[no]翻译:xlp223 2001/12/06\r\n chen_qj 2001/12/07\r\n notyy 2001/12/06\r\n brokendoor 2001-12-14\r\n\r\n整理: BrokenDoor 2001-12-18 [/no]\r\n----\r\n[big]极端编程(eXtreme Programming)是一种开发纪律,以简单性、交流、反馈和勇气为基本宗旨。它的做法是以有效的实践规则将整个团队紧密联系起来,通过充分的反馈使团队能随时知道自己目前的状况和恰当的调节规则以适应自己的特殊情况。[/big]\r\n\r\n在极端编程中,每一个项目贡献者都是“团队”完整的一部分。这个队伍是围绕着一个每天和队伍坐在一起共同工作的商业代表——“客户”建立起来的。\r\n\'\'\'核心实践:整体团队\'\'\'\r\n\r\n极端编程的队伍采用一种简单的方式来进行规划和跟踪,以决定下一步要做什么和预知项目什么时候会完成。聚焦于商业价值,团队通过一系列的通过了客户定义的测试和完全集成的小的发布来创作软件系统。\r\n\'\'\'核心实践:规划策略,小发行版,客户测试\'\'\'\r\n\r\n极端编程者通过成对和小组的方式共同工作,通过简单设计和强制测试的代码,不断的提升设计以保证设计总是适合当前的需求。\r\n\'\'\'核心实践:简单设计,成对编程,测试优先开发,设计改进\'\'\'\r\n\r\n极端编程队伍会总是保持系统能够集成并且在所有的时间运行。程序员以成对的方式编写所有的产品代码,并且在所有时间内都共同工作。他们以相似的形式编码以保证所有成员都可以按需要理解和改进所有的代码。\r\n\'\'\'核心实践:持续集成,集体代码所有权,编码标准\'\'\'\r\n\r\n极端编程队伍分享一个公共并且简单的系统蓝图。所有成员可以按照一种不时保持同步的节奏进行工作。\r\n\'\'\'核心实践:系统比喻,可接受的步伐\'\'\'\r\n\r\n[h2]核心实践[/h2]\r\n\r\n\'\'\'团队整体\'\'\'\r\n一个XP项目的所有参与者都作为一个团队的成员坐在一起。这个团队必须包括一个业务的代表——“客户”,他提供需求,设置优先度,并掌管整个项目的方向。最好这个客户或者他的助手是一个最终用户,了解该领域,知道什么是所需要的。团队当然还要有程序员。团队可能会包含测试员,他帮助客户定义客户验收测试。分析员可以作为客户的助手,帮助客户定义需求。通常还会有一个指导,他帮助整个团队跟踪、推动开发进程。也可能会有一个管理者,他提供资源、处理对外交流和分工协作。这些职责中没有任何一个是必须某个个人独有的:每一个XP团队的成员都以任何他们所能做到的方式参与,最好的团队没有专家,只有一些有着特殊的技能的一般的参与者。 \r\n\r\n\'\'\'规划策略\'\'\'\r\nXP的计划解决软件开发中的两个关键问题:预知在责任期内哪些东西将被完成,并且确定下一步需要做什么。重点是把握项目的正确轨道——这是相当简单明了的——更胜于希望精确预知哪些东西将会需要以及可能花费多少时间——这是相当困难的。在XP这里有两个关键的规划步骤,用来解决这两个问题:\r\n\r\n发布计划是一个实践让客户向程序员们演示所希望获得的特性,然后程序员们评估它们的难度。当手中有了代价的评估和这些特性的重要程序的认知之后,客户安排一个项目计划。最初的发布计划需要留有足够的余地:优先级以及评估都不是真实可靠的,并且知道团队开始工作以前,我们都无法确切地了解队伍的开发进度。甚至最初的发布计划也不是足够精确能进行决断,所以XP队伍通常会不时地校正发布计划。\r\n\r\n迭代计划是一个实践籍此可以为团队提供每几个开发周的导向。XP队伍通过两周的“迭代”来建立软件系统,在每一个迭代结束时提供可以运行的有实际用途的软件系统。在进行迭代计划时,客户演示下两周内希望完成的特性。程序员们将它们分割成若干个任务,并且评估它们的成本(比发布计划要细致一些)。基于在之前的迭代中完成的工作,团队签定当前迭代中将要承担的工作。\r\n\r\n这些计划十分的简单,然而他们为客户提供了非常好的信息和极好的操纵控制。每隔几周,多少进展都可以一目了然。在XP中没有“百分之九十完成”:一个特性故事要么完成了,要么没有完成。关注可视结果方法在于一个很好的小的对立论点:一方面来说,非常直观地,如果进度不能令人满意,客户可以在某一个位置取消项目。从另一方面说,进度是显而易见地,并且判断哪些东西将会完成的能力是很完善的,因此XP项目往往可以在较少的压力下完成更多的需要的东西。\r\n\r\n\'\'\'客户测试\'\'\'\r\n作为每一个所要求特性的演示的一部分,XP客户定义一个或者多个自动进行的接受测试来表明特性已经能够实现。团队实现这些测试并且用它们来向自己和客户证明特性已经被正确的实现了。由于时间的压力,自动化是很重要的,手工测试将被跳过。这就像当黑夜来临的时候,就可以关掉你的灯一样。\r\n\r\n最好的XP团队会将他们的客户测试当作程序员的测试一样对待:一旦测试运行了,从此之后团队会保持它能够一直正确运行。这意味着系统只能够被改进,总是向前的,从不会倒退。\r\n\r\n\'\'\'小发行版本\'\'\'\r\nXP团队通过两个重要的方式实践小发行版本:\r\n\r\n第一,团队在每一个迭代发布可以运行的,测试过的软件系统,提供客户选择的商业价值。客户可以为任何目的使用这个软件系统,无论是评估还是发布给最终用户(强烈推荐)。最重要的方式是在每一个迭代结束的时候软件系统是可见的,并且提交给了客户。这保证了任何事情都是公开和真实的。\r\n\r\n第二,XP团队尽可能频繁地发布给他们的最终用户。XP网站项目每天都进行发布,居家项目则每月或者更频繁地发布。甚至可以简包装的产品可以每季度地发运。\r\n\r\n这么频繁地创建好的版本也许显得不太可能,但是XP团队每时每刻都在进行着发布。更多信息可以参看持续集成,并请注意这些频繁的发布通过XP中随处可见的测试(如同客户测试和测试优先开发中所描述的)变得现实了。\r\n\r\n\'\'\'简单设计\'\'\'\r\nXP团队建构软件系统为一个简单的设计。他们从简单开始,并且在整个程序员测试和设计改进过程中,他们保持着简单的设计。一个XP团队保持着设计总是刚好适合系统当前的功能要求。这里没有多余的投入,并且软件系统总是为将来做好了准备。\r\n\r\n在XP中设计并不是一次性完成的事情,也不是一件从上到下的事情,它是自始至终的事情。在发布计划和迭代计划中都有设计的步骤,在快速设计过程中集合了团队的能力并且在整个项目过程地构中改进设计。在类似于极端编程这样的递增和迭代过程中,良好的设计是本质。这是在整个开发过程中必须更多的关注设计的原因。\r\n\r\n\'\'\'成对编程\'\'\'\r\n在XP所有的产品软件都是由两个程序员并排坐在一起,在同一台机器上共同完成的。这个实践保证了所有的产品代码都至少有一个其它的程序员进行了审视,而结果是更好的设计,更好的测试和更好的代码。\r\n\r\n让两个程序员去做“一个程序员的工作”看起来有些效率低下,但是实际上刚好相反。研究表明成对编程在让程序员们单独工作相同的时间内会得到更好的代码。这证明了:两个头脑加在一起比一个好得多!\r\n\r\n很多程序员在还没有尝试过的情况下就反对成对编程。这确实需要一些实践来做好它,而且你需要认真地实践数周以上的时间来看到结果。百分之九十的学习过成对编程的程序员都会喜欢这样,因此我们向所有的团队强烈推荐它。\r\n\r\n除开提供更好的代码和测试之外,成队也提供了知识在团队中间传递。当成对地程序员交换伙伴时,每个人都会从其它的某个人那里学到新的知识。程序员们在学习,他们的技术在提高,他们对团队和公司来讲变得更有价值。成对,即使它本身在XP过程之外实施,也是每个人的巨大成功。\r\n\r\n\'\'\'测试优先开发\'\'\'\r\n极端编程围绕着反馈,而在软件开发中,好的反馈需要好的测试。最优秀的XP团队实践“测试优先开发”,在一个很小的循环中增加一个测试,然后让它能够工作。几乎是轻而易举的,团队提供的代码接近100%都有测试程序覆盖着,在绝大多数情况下这是很重要的进步。(如果你的程序员已经提供了更多的现有测试程序,你会拥有更多的力量。将它们保存下来,他们只会提供帮助的!)\r\n\r\n仅仅写了测试程序还是不够的:你必须要运行它们。这里,极端编程也是极端的。这些“程序员测试”,或者说“单元测试”是一个完整的集合,每当程序员们发布任何代码到代码库的时候(成对的程序员通常每天发布两次或者更多次),每一个程序员测试必须能够正确的运行。每时每刻都是百分之百运行!这意味着程序员们可以立刻得到有关他们做得究竟如何的反馈。进一步说,这些测试提供了软件设计改进时无价的支持。\r\n\r\n\'\'\'设计改进\'\'\'\r\n极端编程在每一个迭代都关注于提供商业价值。为了在整个项目过程中完成这个目标,软件系统必须有良好的设计。可选择性可能会降低并且最终停滞。因此XP采用一种持续改进设计的过程,称为\'\'\'“重构”\'\'\',来自于Martin Fowler 的书名,“重构:改进现有代码的设计”。\r\n\r\n重构的过程关注在去掉重复(一个低劣设计的明确标志),以及提高代码的“内聚”,还有减少“耦合”。高内聚和低耦合在最近三十年以来被公认为是良好设计的特点。结果就是XP团队从一个好的简单的设计出发,并且总是让软件系统有一个好的简单的设计。这让他们能保持他们的开发速度,并且通常在实际上提高了项目开发速度。\r\n\r\n重构自然是通过全面的测试来提供有力的支持的,这些测试用来确认当设计改变的时候不会破坏系统中的任何东西。因此客户测试和程序员测试都是有效的评价因素。XP的实践是相互支持的:他们会比各自独立时更为强壮。\r\n\r\n\'\'\'持续集成\'\'\'\r\n极端编程队伍总是保持的系统完全地集成在一起。我们说每日建构版本是为弱者提供的:XP团队每天都要构建系统很多次。(一个40人的XP团队每天至少集成八到十次!)\r\n\r\n这个实践的好处可以通过回想你可能听说过的(或者是亲身参与过的)项目来了解:当系统构建是每周或以更低的频率进行时,通常会陷入“集成的地狱”,在那里所有东西都不能运行而且没有人知道为什么。\r\n\r\n极少进行集成会给软件项目带来一系列的问题。第一个,尽管集成是发行好的工作代码的条件, 但是团队并不去实践它,而且通常它被委派给那些对整个系统并不十分了解的人。第二,极少集成的代码通常是——我宁愿说总是——错漏百出。\r\n\r\n\'\'\'集体代码所有权\'\'\'\r\n在一个极端编程项目中,每一对程序员都可以在任何时候改进任何一处的代码。这意味着所有的代码在很多人的关注下获得更多的收益,这样就提升了代码质量并且减少了缺陷。这里还有另外一个重要的好处:当代码仅由单个人负责的时候,要求的特性往往会放到了错误的位置,因为一个程序员发现他需要一个特性但是那段代码却不归他管理。代码的所有者太忙乐而不能去增加这个特性,所以这个程序员只好把这个特性加进了这个特性本不应该存在的他自己的代码中。这导致了难看的,难于维护到代码,充斥着重复和低(差)的内聚。\r\n\r\n如果有人在他们所不理解的代码上进行盲目的修改时,集体代码所有权可能带来问题。XP通过两种关键技术来避免这类的问题:通过程序员测试来捕获错误,成对编程则表明在不熟悉的代码上工作的时候最佳途径是找一个这方面的专家作为伙伴。为了确保在需要是进行好的修改,这种实践将知识延伸到了整个团队。\r\n\r\n\'\'\'编码标准\'\'\'\r\nXP团队遵循一个公共的编码标准,因此系统中所有的代码看上去都像出自单独一个——非常有能力的——人之手。这个标准的规定并不重要:重要的是要让所有的代码看上去很相似,用来支持集体代码所有权。\r\n\r\n\'\'\'系统比喻\'\'\'\r\n极端编程团队对于程序如何运作形成一个共识,我们称之为“系统比喻”。在最佳状态时,系统比喻是关于程序如何运作的一个简单的灵魂描述,例如用“这个程序工作时就像一箱子蜜蜂,外出寻找花粉并带回蜂箱”作为一个基于代理的信息查询系统的描述。\r\n\r\n有些时候一个十分诗意的想象可能不会出现。在任何情况下,无论有没有生动的比喻,XP团队都会选用一个公共的命名系统来确保每个人都能理解系统是如何工作的,以及到哪里去找到你所需要的功能,或者找到你要增加功能的正确位置。\r\n\r\n\'\'\'可接受的步伐\'\'\'\r\n极端编程团队都会在这里很长的一段时间。他们努力的工作,并且在一个能够不断维持的步伐下。这意味着在有效的时候他们会加班工作,而且他们经常这样工作来保证每周都有最大的生产力。这恰当的解释了死亡竞赛式的项目既不会有生产力也不会创造有质量的软件系统。XP团队在这里是要胜利而不是要死亡。\r\n\r\n[h2]小结[/h2]\r\n极端编程是一种以简单性、交流、反馈和勇气为基本宗旨的开发纪律。它的做法是以有效的实践规则将整个团队紧密联系起来,通过充分的反馈使团队能随时知道自己目前的状况和恰当地调节实践规则以适应自己的特殊情况。\r\n\r\n以后还有一篇文章将讨论XP中的一些常见问题和变化。如果您有什么关注的问题,请记录下来给我们。我们将会尽量归入以后的文章中。\r\n\r\n[h2]参考档案[/h2]\r\n原始的 XProgramming 中关于这个主题的页面仍然可以用作您的参考。\r\n\r\n--------------------------------------------------------------------------------\r\n版权所有 ? 1999-2001, Ronald E Jeffries \r\n\r\n[主题分类]: [软件工程] | [极端编程]','BrokenDoor','2002-03-04 08:51:08','2002-03-04 08:51:08',0,'BrokenDoor',188),('成对编程','[h1]RUP?/XP 方针:成对编程[/h1]\r\nRobert C. Martin\r\nObject Mentor, Inc.\r\nRational 软件白皮书\r\n翻译整理:BrokenDoor 2002/3/4\r\n----\r\n \r\n[h2]简介[/h2]\r\n\r\n\'\'\'成对,概要说明\'\'\'\r\n------------------------------------------------------------\r\n成对编程是软件开发中两个人一起编写一个项目的一种技术。每个伙伴工作在同一台机器上,当一个程序员在写代码时,另一个伙伴在一旁观看,同时认真所写的代码。写代码者从战术上考虑具体实现,其伙伴则从战略上考虑整个程序。他们之间频繁的交换角色,这样将使得可以更快写完代码,并且减少错误,更重要的是:代码将至少有两个人非常清楚的掌握。\r\n\r\n\'\'\'成对的案例\'\'\'\r\n------------------------------------------------------------\r\n考虑一个典型的代码审视的工作。一个需要一人8小时开发的模块由8个人花一小时审视。也就是等于总共要花费16个工作人日。然而,审视者不能保障必需的时间去熟悉代码,而且他们的审视也相当的肤浅。单个人开发确实能非常熟悉该模块,但是可能太熟悉了以至于不能发现漏洞。\r\n\r\n对比成对编程的实践方法。如果这个模块需要两人合作8小时来开发,总共需16工作人日。然而,这种情况下,两个伙伴将会非常熟知这个模块的代码。在开发过程中所隐含的一些错误也将被另一个伙伴发现。\r\n\r\n成对编程的实践是简单的,但是是一种简单而有效的编写和审视代码方法。两人同时熟知代码,并且将错误漏洞出现在代码中的可能性大大减少。代码将有一个良好的结构。当然成对还有更多的益处:\r\n\r\n成对更有勇气:一个人不敢尝试的东西他的伙伴将有勇气去尝试并扼杀其原有的评估;\r\n\r\n成对能鼓励团队:由于代码不是一个人独立完成的,而将是属于整个团队所有。\r\n\r\n成对促使知识的传播:由于在开发的过程中不断的交换伙伴,而使每个成员将熟知系统的每个一个模块。\r\n\r\n成对能提高生产力:一个人在开发的过程中将会出现一段疲劳、消极的时期。如果双人变成,则可以相互促进,当一方疲劳时,他们可以交换角色。他们将能保持强度(比一个人工作强)。\r\n\r\n成对是一件有趣的事:和他人一起工作是一件有意义的,非常刺激而且简单的游戏。它将会提高工作满意度和提高士气。\r\n\r\n[h2]实践规则[/h2]\r\n\'\'\'成对\'\'\'\r\n------------------------------------------------------------\r\n成对开始于某一个程序员承担了一个任务的责任并且请求其他人帮助的时候。规则是:当你被请求提供帮助的时候,你必须说可以。这并不是说你需要立刻停下正在做的事情。这其实时说你必须商定好一个时间你能够提供帮助而另一个时间获得帮助作为回报。\r\n\r\n成对中的伙伴并不承担任务的责任。这个责任还是归任务所有者保留。并且成对中的伙伴也不保证说一定要和任务所有者一起直到任务完成。成队的伙伴指保证完成提供帮助。\r\n\r\n成对中的一个成员成为驱动者,而另外一个则在一旁观看。驱动者键入代码,运行编译器,运行测试程序,并继续任务。旁观者则检查每一个键入,每一个命令,每一个测试结果,并且提供帮助和建议。在所有的时间里每一个成员都被充分使用了。\r\n\r\n某些时候驱动者会更了解要完成什么工作,而旁观者则只是简单的跟随。而另外一些时候,旁观者将会替驱动者决定要做什么。有些时候驱动者失败了并且将键盘递给旁观者,然后两人互换角色。还有些时候,旁观者会要求拿过键盘并且互换角色。这些情况将在成队的过程中经常出现。\r\n\r\n\'\'\'交换成对\'\'\'\r\n------------------------------------------------------------\r\n成队的伙伴并不是长期固定的。一个典型的成对过程将仅仅持续半天左右。每一个伙伴都可以因为任何原因选择退出成对。当这种情况出现的时候,任务的所有者必须找到另外一个成对伙伴。这也可能意味着是该任务所有者回报帮助给上周的某一个伙伴的时候了,也可能他或她需要请求一个对当前特殊的问题有着合适经验的人提供帮助。\r\n\r\n这种成对的交换会形成系统的相关知识在整个开发队伍中的传播。在很短的时间内,每一个团队成员就将有在系统的几乎每一个部分工作过的经验了。这急剧地减少了项目重写的程度,并且让每一个程序员在处理整个系统的时候更有信心。\r\n\r\n\'\'\'集体代码所有权\'\'\'\r\n------------------------------------------------------------\r\n因为每个人都在为系统的不同模块工作,因此没有人拥有某一个特定的模块。这表明对系统的责任不会按照每个模块为基础分割开来。更好的方式是,整个团队拥有整个系统的集体责任。每一个团队成员都可以为任何原因签出并修改系统的任何一个模块。当一个双人组合修改模块X而导致了模块Y的单元测试失败的时候,这个组合将会直接修订模块Y。\r\n\r\n\'\'\'漫步和协作\'\'\'\r\n------------------------------------------------------------\r\n成对编程时一个非常热烈的交流形式。口头的对话经常会变成争论,局外人通常会有理解的问题。作为一个局外人,你也许会听到两人发出特别的单词好像:“分号”,或者“关闭花括号”。或者你可能只是听到一些不清楚的噜噜声作为程序员们同意或者不同意屏幕上出现的内容。俩人都忙碌于正在出现的代码中以至于很多交流都是无声的。肢体语言占了很重要的位置。一个成队的伙伴不需要出声询问就可以说出他的同伴什么时候对代码不满意。一个鬼脸,一声叹息,一阵不安——所有的集合起来都增加了伙伴之间的交流带宽。有些时候一个伙伴会抢过鼠标,而另一个则操作键盘。拿鼠标的人控制需要在模块中工作的位置。拿键盘的人控制在此位置修改和添加的内容。另外一些时候,一个伙伴可能在键入代码,而另外一个伙伴将预知一个需要的函数调用并且打开API文档中相应的说明页。\r\n\r\n当一个伙伴疲倦的时候,另外一个人可以接过手来,允许他或者她的伙伴休息一下来充当相对的角色。其它的时候,两个伙伴都会有高昂的精神面貌并且会经常的交换鼠标和键盘。\r\n\r\n总而言之,这里只有很少的规则和过程。真正需要约束的仅仅是两个伙伴都必须维持高昂的精神面貌并且俩人之间交流必须是热烈的。如果成对中的一个伙伴正在键入代码而另外一个家伙正看着窗外的话,则成对只是虚有其表。\r\n\r\n\'\'\'单独的一个程序员能做什么呢?\'\'\'\r\n------------------------------------------------------------\r\n你不可能在所有的时间内都保持成对。一些项目——那些选用极端编程(XP)(参考资料[1])——遵循的一个规则就是必须由成对完成所有产品代码。在这种情况下,在你没有成对时你可以去查看一下电子邮件,阅读一些有关新技术或者API的技术资料,看一下那些你不太熟悉的代码,或者跟投资者探讨一下当前的迭代状况或者未来的计划。实际上,总有一些适合的事情可以让一个程序员在没有找到伙伴的那几个小时里去做的。\r\n\r\n有一些项目对成对要求的没有那么严格。有一些会允许单独的程序员们去编写测试代码。还有一些允许单独的程序员们去编写抽象类和接口。也还有一些只是简单的允许程序员们决定什么时候最好需要成对。有一件事是很清楚的,无论如何——研究已经表明当实践成对编程的时候错误率会很显著地降低。\r\n\r\n\'\'\'有一些人不喜欢成对\'\'\'\r\n------------------------------------------------------------\r\n一些人对成对编程的概念感觉不适应。在我们的经验中,这些人实际上在尝试了一周左右后发现他们的不适应消失了,并且他们喜欢成对和发现它是很用处的。只有很少的人会继续不喜欢这个实践。因此,对大多数人来讲,尝试并且习惯它是一个很简单的问题。对于那些真正了尝试过并且依然感觉到不适应这个实践的人们,团队就必须去找到一些适合他们做的事情。\r\n\r\n[h2]设备,方便以及后勤[/h2]\r\n\r\n\'\'\'显示器和键盘的布置\'\'\'\r\n------------------------------------------------------------\r\n设备的布置对成功的成对实践是很重要的。如果伙伴们不能坐到彼此的旁边并且很快的交换键盘的话一个成对很难实施得很好。规则是:你必须能够来回的拿到键盘和鼠标而不需要交换座位。\r\n\r\n最好的安排通常是一个漂亮的长平板桌。将显示器放在中间然后正对着显示器放两把椅子。坐下来让显示器在你们之间。确保很容易能在你们之间挪动键盘和鼠标。同时确保在你拿到键盘的时候,你能够很舒适并且能够坐直。确保显示器能够让两个伙伴都看得清楚而不需要转动它。\r\n\r\n\'\'\'大房间\'\'\'\r\n------------------------------------------------------------\r\n为了便于交换成对的伙伴,一般都希望能够在一个类似棒球候补球员区的环境下工作。在一个房间里放置多个成对用的工作站。使用有轮子的椅子和油布或者瓷砖地板。排列工作站让成对的伙伴们都能面对面。这样做的目的是为了增加交流。有些时候最重要的交流就是那些偶然发生的。我们想让这种交流出现的几率能够增加。\r\n\r\n\'\'\'在角落里\'\'\'\r\n------------------------------------------------------------\r\n现今的许多小单间都将工作站放置到角落里。程序员们面对着角落坐下来在他或她的面前是一个显示器。当然这样会便于单人工作,但是在这种环境下成对编程几乎是不可能的。如果你有一个将工作站放在角落的小单间,那么在其他地方放置一些成对用的工作站——也许在一个会议室。在一个会议桌上使用一个笔记本电脑进行成对编程常常是很有效的方式。\r\n\r\n[h2]问题和关注[/h2]\r\n\'\'\'成对让生产力减半\'\'\'\r\n------------------------------------------------------------\r\n这种说法建立在以下的理由上,两个人在一个任务上一起工作会消耗两倍于一个人在同样的任务上工作的所花费的时间。这看上去合情合理,但这却并不是真实情况。根据研究(参考资料[2])表明很少的,即便有,生产力会在成对工作的情况下丧失。同样的研究证明了成对可以大大的降低错误率,以及程序代码的大小,同时极大地增加了工作的乐趣。\r\n\r\n\'\'\'成对伙伴间的争论\'\'\'\r\n------------------------------------------------------------\r\n任务的所有者有所有设计争论的最终决定权,但是处理争论的最好的方式是对两种设想都进行尝试并选择工作得最好的那种。\r\n\r\n\'\'\'专家\'\'\'\r\n------------------------------------------------------------\r\n传统的至理名言给出的建议是对某一个特殊领域有专长的程序员,例如数据库或者图形用户界面,应该独自在这些领域发挥作用。但是在一个成对编程的环境下,这些专家成为那些没有这方面特长的伙伴的最好的导师。程序员们可以签上一个不在他们的专长领域范围内的任务然后征求专家们的帮助。这样,专家的知识就开始在整个团队的范围内传播,极大的减少了项目反复的程序。\r\n\r\n\'\'\'噪音\'\'\'\r\n------------------------------------------------------------\r\n一个成对地伙伴可能在他们编程时产生噪音。一个坐满成对伙伴的大房间会保持频繁的低低的嗡嗡声。有人会感觉到这些噪音令人烦闷以及分散注意力。这并不能证明是一个重大的问题。如果你觉得这些噪音令人烦闷,你可以走到会客室坐一会儿。\r\n\r\n\'\'\'牛仔\'\'\'\r\n------------------------------------------------------------\r\n许多团队会发现他们是一到两个牛仔式编码者的足以自豪的拥有者。这些牛仔是一些比其他任何都能更快地完成任务,不能和其他人合作,并且任何人都不被允许(或者是如果允许的话,也没有能力)去阅读他们的代码。对于这些开发者最好的处理方法是让他们离开项目或者承担一个不需要他们编写产品代码的角色。也许他们能够编写一些临时的工具或者做一些疯狂折磨式的测试工作。\r\n\r\n\'\'\'习惯障碍和障碍形式\'\'\'\r\n------------------------------------------------------------\r\n有一些人使用QWERTY式的键盘。另一些人更习惯于DVORAK式的。一些人需要特制的键盘,鼠标,显示器,脚踏开关,等等,等等。一些人在编程时不能没有耳机和喧闹的音乐。另一些人必须在他们周围摆满空箱子。一些人喜欢用emacs编辑器。另外一些人喜欢VI。甚至还有一些人喜欢用WordPad.\r\n\r\n实际上,这些可以指出的障碍是数不清的。但是每一种障碍和每一个人都可以通过一些想法解决并且有办法进行折衷。一个让这些事情阻止他们的团队是不可能在他们尝试的任何努力中取得成功的。\r\n\r\n\'\'\'团队如何规划成对的计划?\'\'\'\r\n------------------------------------------------------------\r\n我们并不认为任务需要指定给一个双人组。更好的方式时每一个开发者需要承担一些任务的责任。我们喜欢非正式地成对。每一个开发者,从事他或她自己承担的责任,请求其他开发人员提供暂时的帮助。任务的所有者保持着所有权和责任。成对的伙伴仅仅是帮忙的人。\r\n\r\n每一个开发者必须在评估任务的时候计入他或她作为其他人的开发伙伴的时间。\r\n\r\n[h2]总结[/h2]\r\n成对编程是一种成功试验过的,令人满意的代码审查的替代方法。不仅如此,它还是一种编写软件系统的革新的途径。带来的好处也不仅限于生产力和质量,而且对一些像团队士气和精神风貌等方面带来好的影响。\r\n\r\n[h2]参考资料[/h2]\r\n(1) 解说极端编程(eXtreme Programming eXplained), Kent Beck, Addision Wesley, 2000.\r\n(2) 强调成对编程的案例,Laurie Williams, 犹他州立大学, 7/8月 IEEE 软件。\r\n\r\n----\r\n[主题分类]: [软件工程] | [极端编程]','BrokenDoor','2002-03-04 08:59:40','2002-03-04 08:59:40',0,'BrokenDoor',189),('CRC的使用简介','CRC 全称“Class-Responsibility-Collaboration”,是面向对象设计中的一种简单易行\r\n的快速设计方法。经过破门在公司项目的实践,感觉到设计过程的确简单易行,所以根据\r\nWard Cunningham 的一篇讲稿整理出一份简单介绍,贴出来与大家共享。\r\n\r\n翻译的Power Point讲稿可以在此下载:\r\n[url=ftp://www.clinux.org/pub/brokendoor/xp/firstCRC-cn.zip]firstCRC[/url]\r\n\r\n\'\'\'1。面向对象编程的四个阶段\'\'\'\r\n - 标识对象\r\n - 设计草案\r\n - 构造层次\r\n - 实现方法\r\n 其实现难度是按照由下到上的顺序递增的\r\n\r\n\'\'\'2.标识对象简介\'\'\'\r\n - 按照合作代理(对象)的行为进行模块估计\r\n - 定义特定对象的类\r\n - 在类的基础上分配责任(符合需求)\r\n\r\n\'\'\'3.一个设计方法\'\'\'\r\n - 根据经验和智慧做出决定\r\n - 用结构化的设计文档记录决定\r\n - 充分彻底的测试设计\r\n - 在实现的过程中维护和遵循设计\r\n\r\n\'\'\'4.设计表述(CRC)\'\'\'\r\n - 列举所有的新类\r\n - 定义类成员担负的责任\r\n - 通过分配的责任来描述合作关系\r\n\r\n\'\'\'5.CRC卡片介绍(使用实例Drawing Editor)\'\'\'\r\n 第一步:从已知的开始\r\n - 一个图由多个图片构成\r\n - 图片分成很多种类\r\n 第二步:推测支持者\r\n - 一个线可能连接到其他图片\r\n - 一个“智能”点完成这个工作\r\n 第三步:进行情景测试\r\n - 图片移动的时候依赖于定位器\r\n - 通过定位器改变顺序\r\n 第四步:尝试进行分组\r\n - 一个处理类似一个工具\r\n - 处理器是唯一的\r\n 第五步:重新分配责任\r\n - 选择保持在视图类中\r\n - 选择不会和图一起保存\r\n\r\n 第六步:为了清晰化而重写\r\n - 图片排序非常重要\r\n\r\n----\r\n这里有一篇kent在89年关于crc的论文[url=http://www.c2.com/doc/oopsla89/paper.html]kent89[/url]\r\n\'\'谢谢,有时间我会翻译一下。brokendoor 2002-3-4\'\'\r\n----\r\n[主题分类]:[软件工程] | [极端编程]','BrokenDoor','2002-03-04 09:04:33','2002-03-04 11:13:45',0,'BrokenDoor',190),('完成的感觉','[h1]幕间休息:——完成的感觉[/h1]\r\n--------------------------------------------------------\r\n\'\'\'摘自《XP Installed》 第61-63页 简单的翻译了一下,希望大家能够喜欢。\'\'\'\r\nXP 的嵌套式的设计和编程循环让项目保持在轨道上,并且提供了一个健康的不断完成的感觉。\r\n-----------------------------------------------------------\r\n大多数项目持续数月之久;有一些会持续数年。为了防止在无边无际地编码-即使是漂亮的优质代码-的持续打击下变得发狂,每一个项目都需要停顿。一个程序员可以获得的最好的停顿是一种完成的感觉。XP的设计循环提供了一个循环相套的节奏,每一个周期都有着它自己的完成时刻。\r\n\r\n成功的运行测试程序每个几分钟就给了程序员们一个完成的感觉。跟你的伙伴分享这点小小的快乐吧。完成一个任务每隔几个小时就提供了一个完成的感觉。跟所有的其他的程序员们分享这份感觉吧;休息一下;也许换一下伙伴。完成一个故事是一个重要的里程碑。每个人都得到成功的感觉。同所有的客户和程序员们分享吧;也许可以举行一个小小的仪式。\r\n\r\n完成一个迭代过程标志着完成了一些故事并且为下一次完成开启了一扇门。同整个团队共享这份快乐吧;确认一下是否准备好了比萨饼或者其他一些小的庆祝。\r\n\r\n每一次发布提供了一个重要的完成的感觉:新的商业价值已经在客户手中了。这是美好的一天!可以打开香槟了!\r\n\r\n这些都是重要的时刻。他们为工作加上了标记,使它们拥有一种进度和意义的感觉。没有这些时刻,工作就会变成苦差事,一个没有结尾的\'\'\'死亡竞赛\'\'\'。\r\n\r\n\'\'\'- 程序员们掌握节奏\'\'\'\r\n程序员们,每一天都创造自己的完成的感觉的责任。在一个时刻只考虑一个故事,从这个故事的任务中取出一个来进行工作。为这个任务编写一个你需要的测试。运行它,直到它能够运行。完成编码直到它能够完成工作,经常的运行所有的测试。当你正在为它工作的测试能够运行的时候,休息一下。在你的脑海中慢慢体会 - 又完成了一点。\r\n\r\n在一个时刻编写测试中的一个,为任务测试并且编码直到所有必需的测试能够运行。休息一下。任务完成了!让你自己感觉一下这个小小的胜利。从你的清单上划掉这个任务。感觉到一点点兴奋。任务完成了!\r\n\r\n代码是否已经定型并且可以发布了——不是全部完成了,只是已经可以运行所有的测试了?也许这是一个运行所有测试和发布一些代码的好时机。代码发布了!\'\'\'生活是美好的!\'\'\'\r\n\r\n在一个时刻为一个故事工作。当为故事编写的所有的测试能够运行时,休息一下。一个完整的故事完成了!这真是太好了。客户将会取回一个标记为完成的卡片。\'\'\'生活是很美好的!\'\'\'\r\n\r\n当一个故事完成的事后,这是一个明确地时候需要运行所有的测试并且发布你的代码。\r\n\r\n在代码发布的时候举行一个小的仪式。也许去找一个当你在柜台要求服务的时候敲打在它上面的小铃铛。当你成功地发布后重重地敲它一下。当其他人给这个铃铛一下重击地时候,给他们一点鼓励-轻轻的鼓掌,从容地举杯庆祝说“呀...耶!”。\r\n\r\n给项目加上标点,享受这些完成地时刻。在一个迭代周期结束时,通过将已经完成的故事交还给客户形成了一个小的成果。“它们已经完成了。”给你自己一点掌声-这很好!如果有一些故事没有完成,就让它呆着吧。确认先说明这些,因此你可以通过上面的贴纸标注关闭这个迭代周期。“这些故事没有完成,解释...解释。”停顿一下。“这里,”提交已经完成的一堆,“是我们已经完成的故事。”休息一下,给自己祝贺。\r\n\r\n客户们,你们也会为这些时刻感到满意。一些你要求的东西已经完成了。你的问题已经解决了一部分。已经咬到了一大口,并且你获得一些价值,一些你能够用的东西。\r\n\r\n庆祝这个时刻。程序员就像小动物一样,只是没有那么自然。我们需要持续的鼓励来保持动力。所以对我们说:“好的,程序员,很好。很好的程序员。”也许向我们扔一块骨头或者一个程序员餐像是一包泡面(译注:原文是a package of red licorice 意指红甘草精,可我不知道那是什么好东西,我们中国的程序员餐就是一包大块儿的泡面了:))。\r\n\r\n你的项目将会持续一段很长的时间。有时可能会更长。当这里有成就或完成的感觉时工作会变得轻松和愉快。提供这些时刻,享受它们。每天都成功,并且确保让所有人知道你每天都在成功。\r\n\r\n----\r\n[主题分类]:[软件工程] | [极端编程]','BrokenDoor','2002-03-04 09:21:16','2002-03-04 09:21:16',0,'BrokenDoor',191),('解析“极端”','原文(potian于2001/11/27 19:21粘贴) \r\n我认为极端编程更好 \r\n--------------------------------------------------------------------------------\r\n \r\n kent beck说了,如果一件事情好的话,那我们就走极端,让每个人、每时每刻来做,\r\n 意思就是极端化,把好处最大化,其他的解释都不通: \r\nSo why the \"extreme\" in the name?XP takes commonsense principles \r\nand practices to extreme levels. \r\n\r\n1.If ... are good, we\'ll .... all the time. \r\n2.If .... is good, everybody ..all the time. \r\n3.If ....is good, ...everybody\'s daily business \r\n4.If ..is good, ...always.. \r\n5.If ... is important,everybody.....all the time. \r\n6.If ....is important,..several times a day \r\n7.If .. is good,...realy realy short-seconds and minutes and hours... \r\n\r\n原文(notyy于2001/11/28 17:04粘贴) \r\n回复: 我认为极端编程更好 \r\n--------------------------------------------------------------------------------\r\n \r\n 先把portian摘抄的段落补齐吧,否则可惜了这么精彩的一段:) \r\n\r\nif code reviews are good,we\'ll review code all the time ---pair programming \r\n\r\nif testing is good,every body will test all the time ---unit test \r\n\r\neven the customer ---functional testing \r\n\r\nif design is good,we\'ll make it part of everybody\'s daily business ---refactoring \r\n\r\nif simplicity is good,we\'ll always leave the system with the simplest design \r\nthat supports its current functionality \r\n---the simpliest thing that could possibly work \r\n\r\nif architecture is important,everybody will work defining and refining the \r\narchitecture all the time ---metaphor \r\n\r\nif integration testing is import,then we\'ll integrate and test several times a day \r\n---continuous integration\r\n\r\nif short iterations are good,we\'ll make the iterations really,really \r\nshort--seconds and minutes and hours ,not weeks and months and years \r\n---the planning game \r\n\r\n愿意的确是把这些好的要素强调到极点,不过翻译成极限也很不错,xp还在继续发展和演化中,\r\n取其“无极限”的意思吧。 \r\n\r\n原文(notyy于2001/11/30 10:36粘贴) \r\n补足kentbeck的话: \r\n--------------------------------------------------------------------------------\r\n \r\n When I first articulated XP,I had the mental image of knobs on a control board ,\r\n each knob was a practice that from experience I knew worked well.I would turn all \r\n the knobs up to 10 and see what happend.I was a little surprised to find that \r\n the whole package of practices was stable,predictable,and flexible \r\n\r\nkent beck是经过实验,并取得成功后才开始推行xp并继续取得成功的。 \r\n\r\n----\r\n[主题分类]:[软件工程] | [极端编程]','BrokenDoor','2002-03-04 09:26:46','2002-03-04 09:27:23',0,'BrokenDoor',192),('XP-抄近路的诡计','[h1]XP:抄近路的诡计[/h1]\r\n--------------------------------------------------------------------------------\r\nDoug Rosenberg及Kendall Scott对于XP的质疑 \r\n原文(jyemii于2002/01/08 13:08粘贴) \r\n-------------------------------------------------------------------- \r\n[h2]介绍[/h2]\r\n\r\n终极制程(Extreme Programming (XP))提供一些有用的概念。我们相信强调测试及他们的指引原理是有重大的价值;这些原理在软件开发程序的发展上非常有用。但是不管如何;暧昧的主张(dubious claims)、明显的缺乏可达成性(scalability)、动听但是问题重重的口号及极端的(Xtremist)姿态几乎掩盖了良好的本质。 \r\n\r\nDoug曾经在OTUG(Object Technology User Group)中有过广泛的讨论。其中有些是相当有用的,有些则是愚蠢的,有些仍有问题亟待回答。Kendall花了相当长的时间详读Wiki网站上的文章。下面大多数的探讨XP的结构及程序(ritual)是依据这些交谈及研究。 \r\n\r\n---------------------------------------------------------------------- \r\n\'\'\'暧昧的主张\'\'\'\r\n\r\nKent Beck及其主要的追随者曾经定位XP是一种『轻量级(lightweight)』程序;这个开发程序可以产出较高品质;以及在一个更及时性的基础上;然后由更细节的程序所组成。(XP人(XPers )偏向归因这些所使用的术语如大设计(Big Design)<译注1>,我们在这整篇文章中也使用这个术语。)然而在这个『程序』的核心有一个相当大的漏洞:分析基本上以被抛出(tossed)。 \r\n\r\n让我们看看一些主张;XP追随者把跳过大设计的分析中『笨重(cumbersome)』的成分做了合理化。 \r\n\r\n---------------------------------------------------------------------- \r\n\'\'\'每周改变的需求 \'\'\'\r\n\r\n依据XP人的说法,处理那些变动的需求在需求的前置(upfront)分析至少有两个主要的缺点: \r\n*大设计寻求控制改变的机制,经由早期获得及一般性的一次解决所有的需求及架构。实际上多数的大设计方法有详细的结构承担必然发生的外部变动,但这些机制往往似乎是或多或少在程序中属于次要的。 \r\n\r\n*大设计视任何不确定情况是一种危机。如果有一些事情是我们不知道的,我们无法推理它们。 \r\n\r\n这些由Doug所接收到记录的言词,经与OTUG联系,其答复是:「你说前置(up-front)『 撷取需求(capture requirements)』,但坦白的说真的吓到我了,因为我从几哩外闻到『瀑布式』。」 \r\n\r\n甚至,XP阵营的感觉是客户对于其在项目中相要的只有一点点的概念。有一个信徒甚至宣称「一开始客户不可能了解他们真正所想要的。」甚至当客户当初指出他们的需求,他们在几周之后坚持改变这些需求,而有时是每天的改变。因此,在跳入程序撰写之前尝试冻结需求是没有意义的。 \r\n\r\n我们同意需求分析及撷取是充满困难及不确定性。但Doug曾经在许多业态中做过多个项目,其中他的客户或多或少控制避免如此的优柔寡断。不,在你开始构建你的系统之前你无需撷取所有个别的需求,但我们坚持某层次的前置分析可以解省你一路上许多时间。 \r\n\r\n有时在开始撰写程序代码之前要求客户精炼(refine)他们所了解的并指出他们想要的是有用的,客户希望从开发团对中获得一些训练(discipline):而同时要求客户提出一些训练也是全然合理的。如果客户真的对他们所想要的没有任何概念;当他们看到一些可执行的东西;雏形(以实际的程序代码建立的)是一个很好的技术可以帮助客户获得清晰的了解他们所想要的。那是与客户合作的一种良好分析的工作同时可以帮助客户精炼他们所了解的。 \r\n\r\n确实有这种情况;当开始撰写程序之后客户的需求改变了。我们假涉有任何的可能性,这些改变在下一构建循环中获得控制。若那是不可能的时候,你应当尽你最大的能力去做。许多XP技术在「尽你最大的能力去做」大概是相当的有价值的。 \r\n\r\n有人问Daug「如果你后来发现客户的需求已被曲解而修正需要从设计的基础改变你会怎么办?」真正的问题是,这种情况发生的频率有多高,而我们需要多辛苦事先避免产生这种情况?而这正是嘲笑『分析』程序为其本身付出太多时间。我们作分析以避免这种情况的产生。 \r\n\r\n---------------------------------------------------------------------- \r\n使用案例(use case)太复杂 \r\n\r\nXP建议你以『使用者故事』撷取需求。这是相对使用案例;XP人一般的感觉是使用案例只能在详尽的细节架构使用者的需求,在长长的格式中有太繁重的东西要去填入。引用Wiki网页诚实的传达XP群体对于使用案例感觉:「我的目标是维持介于企业(business)与开发之间策略权力(political power)的平衡。我曾看过的使用案例的应用太过复杂且正式(formal)以致于商业一方不想去接触使用案例。这导致开发一方询问所有的问题并写下来所有的回答并且承担所有结果的责任。商业一方简化成只坐在桌子的另一边并指指点点的。」 \r\n\r\n这是我们看这件事的方式。 \r\n\r\n一个使用案例是一系列的活动;其中一个活动者(actor)在一个系统中执行以达成特定的目标。关于其定义并没有特别的复杂,或太过正式。 \r\n\r\n使用案例是最有效说明使用者的观点;其中是以动词词组表达活动。这表示使用者需要有一个清晰的了解这一系列的活动是他期望依循的,那确实意味着客户是主动的参与使用案例的细节。如果所了解的不是这些,那么使用案例是太复杂需要精炼--你知道,就像程序代码迫切需要重整(refactoring)。 \r\n\r\n在我们的经验中,『分析瘫痪(paralysis)』在关连到使用案例塑模(modeling)至少可能有三种发生的理由: \r\n\r\n团队花费几周的时间构建精心制作精致的使用案例模式而无法据以设计。 \r\n\r\n团队空转于忧心是否使用任何或所有的UML构词(constructs)『include』、『extends』及/或『uses』。 \r\n\r\n团队浪费时间在长及复杂的使用案例样版(有趣的是,我们似乎或多或少同意XP人这方面的观点。)。 \r\n\r\nXP信徒显然指熟悉导致分析瘫痪的一类使用案例。我们说如果你以使用案例连接(in conjunction with)频繁的雏形法推导(derive),并且/或从旧有(legacy)文件(特别的,使用者手册)挖掘使用案例,而你仍高度全时间聚焦于你的客户,你非常有机会在你开始做之前指出你所需要做的,同时结果将是显著的一路安全的走下去。 \r\n\r\n--------------------------------------------------------------------- \r\n修复的成本曲线是平缓的 \r\n\r\nKent Beck曾经宣称改变程序代码中的臭虫的成本与改变设计臭虫的成本一样的,因为程序代码是设计。我们在后面会说明这个理论的基础上的愚蠢,但同时我想要指出由于Xtremists从图形吹嘘其分析,那是 导因为果(circular reasoning)。 \r\n\r\n其推论如下。如果我们在撰写程序之前并未作分析及设计,那么没人可以断言在我们开始撰写程序设计之前修复错误是比较便宜的--因为没有「在我们开始撰写程序之前」这件事情。迅速的,修复的成本曲线从对数变(logarithmic)成线性(linear)。 \r\n\r\n让我们稍微重新叙述: \r\n\r\n我们可以是软件开发为一持续系列的撰写程序、测试程序代码、拆解(ripping)程序代码、重新测试程序代码、重新撰写程序代码、重新测试程序代码如此不断的循环。 这些都是相同的动作,加上一些分析及设计交杂持续进行。因此,程序代码变动的成本是线性的与你何时发现需要改变没有关系。这类的导因为果的声音对我们而言就像...嗯,就像有人在推销一些东西。 \r\n\r\n直接的比较这些循环论法(circular arguments)是我们的经验;我们的经验中有许多错误瘫痪项目的方式是「我认为那是红色的(或可能是津贴),而你认为是蓝的(或可能是扣项)。」此种不明确说明的假设进入程序代码并且被证明其本身是潜伏的臭虫。当这些不明确的假设进入架构本身,我们主要看到的是诅咒并且重写(及重测试)的动作。 \r\n\r\n我们并不相信任何宣称任何事可以使得这项工作免费的。拆解并重写绝不可能是免费的。如果拆解并重写是『常态』的,也不可能是免费或便宜的。可能使得曲线异乎寻常的平坦,但仍然不视线性的。我仍未看到任何证明Barry Boehm所做的研究是虚假的,他的研究显示当你从分析移动到发行产品之间修正一个错误的成本是以指数递增。重复宣称成本曲线是不可思议的平缓并不能成为事实。 \r\n\r\n--------------------------------------------------------------------- \r\n明显缺乏可达成性(Scalability) \r\n让我们看看为什么XP相关一个项目时似乎不像可以达成并且成功;其中这些条件似乎尚未出现。 \r\n\r\n--------------------------------------------------------------------- \r\nPair Programming \r\n\r\n在理想的XP项目当中,开发者是成对的工作,而且也不是静态的成对:依据哪些事要做而谁知到怎么做,人们可能变换伙伴一天好几次。这个想法;当然;是立基于格言「两个头脑比一个好(two heads are better than one)」。就其本身而论,尝试去遵守这个原理是非常恐怖的。 \r\n\r\n但当你无法在一段有意义的时间内让你所有的开发者同在一个地方;在一个『牛栏』内(假设有一个可用的地方);会发生甚么事?事实上世上有许多开发者并不是真正喜欢这类的坚强的沟通及社交技能;而这些在XP架构下是很明确需要的;面对这个事实你要怎么办?当每一个人为每一件事情争功时,你如何掌控任何人的应负的责任? \r\n\r\n如我们在这本书所描述的,最好的方式包含在高阶及初阶人员之间实作一组检验及平衡,例如;我们建议比较没有经验的人审查系列的图形;这些开发者使用重要的OO专家产品。双人组程序设计显示出这个想法到一定程度,但双人组程序设计同时假设一对一配对总是可行的;而这个简单的说在许多背景中并不是实际可行的。 \r\n\r\n嗯--可能如果那是称为双人组分析、设计及程序设计,我们将会比较满意...。 \r\n\r\n关于双人组程序设计并没有任何事是天生邪恶的--还是可能获得一些利益--但双人组程序设计对我们而言看起来是意图补偿分析的缺口;因此强迫两个人检视他们所撰写的每一行程序代码。这类似强迫幼儿园小朋友走向餐厅时两两牵手因为你无法信任他们不会毫无目的的随意漫游。 \r\n\r\n以另一个方式来看:我们两个一对下棋天生的每一盘棋都一定输给Garry Kasparov,既不是伙伴系统也不是『详尽的测试』可以补偿前置规划的缺口。毕竟,Garry非常小心的规划他的策略。 \r\n\r\n--------------------------------------------------------------------- \r\n索引卡 \r\nXP一族倡议使用类别-责任-合作卡(Class-Responsibility-Collaboration (CRC))。目前;这些卡被重视并广泛的使用--但只限于相当小的规模。CRC卡的设计确实不是用来撷取特别的细节,而像我们做研究论文在我们发掘内在的知识之前使用都是不错的,它们是保持记录的佼佼者。而你如何期望在有一段距离在开发者之间传递索引卡? \r\n\r\n我们客户中之一有位主任建筑师花了许多时间与其它的程序设计师工作。事实上,他花了太多的时间以致于他没有足够的时间给他的新材料他需要做的,这使得他相当愿意参与获得一些他的设计文件。很不幸的,这家公司的开发者位于两岸,因此整个「每一个人在一个大房间中共享索引卡」的想法是有点距离的。使用E-mail传递 模块对他们而言将是较好的方式。同时,我们相信客户在下一版本的产品中使用塑模做更好的工作会是相当成功的, 同时透过提供更可视化于架构及设计他们将能够明显的降低他们的延迟次数。 \r\n\r\n我们看过非常少的开发成果而没有一些颇为严肃的议题需要除里。尤其是快速成长的公司;其中新项目的大小较之刚开始时更是快速的成长。我们建议使用一个好的可视化塑模工具把开发的工作放在显著强壮的基石上而不是做一串苏散四处漂浮的索引卡。 \r\n\r\n--------------------------------------------------------------------- \r\n缺乏责任性 \r\n\r\nXP拥户者坚持大设计趋于只是让人们;理论上;有特别的知识及技巧以执行确定的任务(你知道;这个团队必须包括类别库及一个架构设计师及一个技术撰写者等等)。于此,XP说「每一个人做每一件事,」以直接响应对于『大设计占便宜的事实是有些个别的人比别人较有资格做某些设计决策』的认知。但现在我们会相信开发者将都会立即变的热衷于必须真的以让新人可以独立了解的方式写下东西吗?(同时;不管如何;有好的设计者执行设计有甚么错吗?) \r\n\r\n事实上,如我们将在在本文后面探讨的,XP拥护者宣称适当的重整(refactoring)程序代码是或多或少自我文件化(self-documenting),而所有其它的文件形式太不可信赖而值得存在。这是他们对于『口头的传统(oral tradition)』太过于聚焦的部分合理化,同时他们认为保持东西是如此重度的依赖让所有的关键信息被维护在同一个地方。毕竟;程序代码外部及所有这些索引卡;并没有变成任何文件上的东西,对不对?但那只是没有务实的思考这是将为任何项目工作;而有更多的开发者聚在一个房间之内。不错;沟通管道的数量在人们加入项目时以指数方式增加,同时;我们在本书中倡议一个相当简易(minimalist)的方式,但XP的方式只是太过简易而无法在所有的项目中可用。 \r\n\r\n--------------------------------------------------------------------- \r\n一个XP替代方案:『聪明制程(Smart Programmers(SP))』 \r\n\r\n一般而言,多数我们的客户对于这种没有大小限制(scale)的解决方式没有太多的兴趣。不管如何;如果小规模(small-scale)解决方式是你所想要的,这里有一个Doug曾经经历过的;这是本文中的一个目的我们称之为『SP』。 \r\n\r\n如果你是靠自己的力量经营一家没有太多可冒险的资本的公司SP是非常有用的。它的基础理论是所有程序设计师中5%(或更少)做95%(或更多)的工作,而且只有只有这些(5%)程序设计师值得聘请。 \r\n\r\nSP的本质如下: \r\n\r\n只需聘请前面5%执行的人是你个别认识的,或你信任的前5%的人员。 \r\n\r\n让一个主任架构师(chief architect)非常小心的规划软件工作单元架构;如此单元(即UML包裹)之间有极小的耦合性(coupling)。 \r\n\r\n让主任架构师比对SP成员的特殊专长及经验。 \r\n\r\n让所有的SP程序设计师在家工作,在家中他们不会受干扰,除非他们明确的要求在一个共通的工厂中工作。 \r\n\r\n限制状况报告为半页,并透过E-mail每周传送一次。 \r\n\r\n让你的SP成员当他们认为他们已完成时导入渐进式建立测试。 \r\n\r\n限制(restrict)SP开发者在需要的时候只能透过E-mail或电话沟通。绝不要把所有的程序设计师同时带进一个房间内;除了在整合测试时,以及只有在他们的程序代码是完全的含入。 \r\n\r\n现在,你可以以这种方式建立非常大量的程序而只使用非常小的团队。Doug的经验指出生产力水准更高过于XP所举出的克赖斯勒薪资专案。 \r\n\r\n此外;生产力将比XP所产生的更高。不管如何,尝试让主任架构师跳过分析及前置规划,或做了一个坏的聘请的决定,你会在你手中产生一个灾难。我们绝不会麻烦的使之形式化或甚至命名,SP技术因为其没有大小限制及没有错误的限度。就我们来看像XP可能也如此装腔作势。 \r\n\r\n<译注2> \r\n\r\n--------------------------------------------------------------------- \r\n响亮但问题重重的口号 \r\n\r\n如果你想要的是一个立即让你难忘强而有力的口号,XP正是指引你一条路。毕竟,就如XP的训练现在已经很清楚,「软件也是...很难花费时间在没有意义的事情上,」这类的主题很容易变成一种口号。让我们看看一些XP人呼喊整体重新整合相关的关键惯用语(phrase)。 \r\n\r\n--------------------------------------------------------------------- \r\n只有四件关于软件重要的事情 \r\n\r\n这是最大的一个,XP存在的理由。这四件事是甚么?撰写程序、测试、倾听及设计(从前的重整(refactoring))。 \r\n\r\n喔,同时别忘掉:「这里所有的都是关于软件,任何人告诉你的与此不同都只是在推销东西。」 \r\n\r\n就如我们之前指出的,『分析』并没有使得时间缩减。(这可能是Beck在OTUG有些事情与某件事情:「我以真正的名称称呼分析:说谎。」)更重要的,既使,博学多闻的人知道关于软件恰巧有七件重要的事。(我们不想在此分享,但在我们的书中可以找到,如果先前你不是很有知识) \r\n\r\n尽管;严肃的如此热烈的宣称软件开发只有四种元素是有意义的;是极端的超越现实,甚至还有些事情称之为XP。 \r\n\r\n---------------------------------------------------------------------- \r\n原始程序代码就是设计 \r\n\r\n我们承认从这个得到相当大的刺激(kick),这不是最不重要的因为我们曾写个一个笑话「使用案例(use case)不是需求」;而在我们的书中有类似的。在Wiki的首页上中的评论像「当你重整,你是在进行细节的设计」,这就像我们将在另一本书中做的那至少有一个章节说明针对驳斥这类的废话。 \r\n\r\n重整是一种极为迷人的主题,我们希望在Martin Fowler的书中证实。我们确认那将提供我们许多有用的技术以改善我们的程序代码。但设计是设计,而撰写程序是撰写程序,把他们视为相同的一件事是愚蠢的。UML之神(好吧,三个其中之二,不管如何)基本上忽略初步的设计是很不好的,现在我们必须处理Xtremist狂热的扭曲细节设计的概念而超越所有的认知。 \r\n\r\n每次我们看到争论我们喜欢总结如「改变程序代码是那么的便宜;不管我们是否从设计做起。」我们都会感到胃痛。这正是我们要尝试指出是甚么导致的种感觉及去唠叨这件事。 \r\n\r\n在XP,『甚么(what)』描述是从使用者故事撷取。我们关心的是项目团队如何处理跨越『甚么』及『如何(how)』之间的差距。可见的理由之一是在XP中渐进式发展(increments)是如此的微小,对每一个渐进式发展阶段,介于『甚么』及『如何』之间的差距不仅必须跨越设计层次;那是很难满足的;同时包括程序代码层次。这表示设计错误及程序代码错误将被混杂(intermixed)。 \r\n\r\n不可避免的时间将花费在修复程序代码错误以便让程序可以执行及测试,而测试将暴露设计错误。设计一经改变,所有花费在修复程序代码错误及测试程序修复部分的精神及时间都将浪费,因为程序代码现在要被诅咒(ripped out)并取代。在新的程序代码当中也将有新的程序代码错误,而前面的步骤还会再重复。这看起来还是OK,因为程序设计师在程序设计中『获得乐趣』。 \r\n\r\n使用哪种方式并不是说无法达成--但对我们而言,哪似乎要完成工作需要浪费许多精力及时间。 \r\n\r\n如果我们没有尝试尽我们的可能做最好的事,所有的时间(而这应包括我们撰写程序代码之前),我们都是马马虎虎。如果我们认为马马虎虎的工作是OK,只要我们快速的工作(「喔,没关系,我们随后可以修改」),我们得到的是一堆垃圾。软件不是与其它的努力(endeavors)在这个观点上有不可思议的差异,不管你有多好的重整浏览器。 \r\n\r\n在你开始撰写程序代码之前只要证实设计是正确的,你对于项目审查会有最佳的概念,最好的是在初步层次(preliminary level)(以便确保没有人朝向错误的方向快速前进)及细节层次。然后你才开始撰写程序并曾测试获得回馈。 \r\n\r\n--------------------------------------------------------------------- \r\n做可能达成的最简单的事情 \r\n\r\n这个口号说你应该简化、简化、简化。 避免倾向与把你不真正需要的材料构筑入你的程序总是一件好事。但是,我们关心的是那很可能是尽力鼓励开发者把Scotch影带、泡泡糖、橡皮筋杂七杂八的东西随意放置在程序代码中;这种程序是由为充分小心的花时间定义一个坚固的架构所逐渐形成的。 \r\n\r\n我们最近有一个经验;其中我们经由反转工程(reverse engineering)的工具吸收一些『已完成(as-built)』的Java程序代码并且发现有些方法其名称向bugFix37。很不幸的,任何创造这个方法的人是做可以达成的最简单的事,那只是相当字面上的意义。(我们只能从它的搭挡程序设计师听到回响,欢兴鼓舞的说「嘿,我们正期待做可以达成的最简单的事,不是吗?」)按照纪录,这个有问题的项目不是以XP所建立的,但那是以没有正式的分析及设计所构筑的。 \r\n\r\nXP其它的指导原理并没有帮助如:如果你认为你可能并不需要的,你并不需要。这类事情有助于鼓励这类与世隔绝(insular)的相法;这种想法导致软件并没有解决任何位于外界人认为值得解决的问题。我们引用Ron Jeffries的话来加强这个概念:「一个开发者真正需要开始认真工作是直到她已开发她自己的内在品质的意识(sense),我不期望我的符合你的;我真正希望我们与他们有足够的接触;我们可以与他们讨论并使用我们不同的意识选择一个解决今日满足我们两者内在的尺寸的问题。」悲哀的,在XP除了程序代码每件事都是可视的,我们剩余的期望只是品质保证。 \r\n\r\n我们还认为一个系统的品质最好是经由耦合性(愈疏松愈好)、内聚力(愈紧密愈好)及完整性的衡量来反应,加上思考像每一类别加权(weighted)方法及子类别投入的数量作为好的衡量。参阅我们的书第5及8章关于至方面的作法(metrics)的更进一步信息。 \r\n\r\n--------------------------------------------------------------------- \r\nXtremist 故做姿态 \r\n\r\n从另一方面而言,XP人喜欢广泛的争辩关于是否『勇气(courage)』或『进取心(aggressiveness)』是比较正确的说明就处理这些麻烦(pesky)的付钱的人而言他们所处的位置。 \r\n\r\n从另一方面而言,XP人倾向迷失在新鲜的空气及说一些事如:「XP大师(Master)了解的如此深刻以致于他们无法被了解」 \r\n\r\nXP的花言巧语让我们觉得那是结合相当高程度的傲慢并且试图模糊使得变得很奇怪。 \r\n\r\n--------------------------------------------------------------------- \r\n准备、射击、瞄准 \r\n\r\n就如统一开发程序(Unified Process)描述的四个阶段(反复(iteration)、精细制作(elaboration)、建构(construction)及转换(transition));这些在在项目的每一个反复中执行,XP说的是「故事(stories)、测试(testing)、撰写程序代码(coding)及设计(design)」。强烈的与大设计比较;统一开发程序符号表示法(symbolizes),XP方法论提供『微量渐进式发展(nanoincrement)』,它的基础是不超过一周的渐进式开发,甚至是短到一天。更快、更快、更快! \r\n\r\n我们不反对找到软件开发程序更快速的方法--只要这种方式产生的结果不是「准备、射击、瞄准」。<译注3> \r\n\r\n由于拒绝花任何一些有意义的时间指出在开始『生产』之前应做甚么,并且坚持在一个进行中的基础下『以小的方式(in the small)』做大的工作(great work);从某种角度当烟幕消散时将神奇的产生整个系统被矫正,XP人似乎认为他们已找到银色子弹(silver bullet)<译注4>以反击大设计的假设:偏向于在细节部分陷入泥沼。 \r\n\r\n这是一个很明显的短视(short-sighted)方式。我们可以以分析及设计到一个非常可接受的层次降低失败的风险而无须把身体连同洗澡水抛弃。早期进入程序代码撰写并不代表没有风险;这个风险只是不同的本质(在某些情况可能更难以捉摸)。我们应该尝试最小化项目整体的风险层次,而不是部分的风险。 \r\n\r\n当Doug七年前开始教授OOAD,最通常的失败点是在 训练研讨会(training workshop);总是发生在从需求层次(使用案例)系统行为观点移动到一个细节设计层次(循序图/合作图)行为观点所做的努力。 尝试跳过这个阶段--在这本书中我们称之为跳过『甚么-如何(what-how)』的差距--从一个纯需求(pure requirements)观点到一个细节设计观点是异常的困难。人们总是发现的是经由增加动态模式(坚实的分析(robustness analysis))的『初始设计(preliminary design)』观点,他们持续能够让团队通过这个转换点。 \r\n\r\n我们仍然能够平衡渐进式开发的利益(可能使用一些较大的渐进式程序),严格的测试及其它可能被证明有用的技术,如双人组程序设计。以这种方式,我们保证我们不止将会总是拥有一个执行的方案(functioning program),同时我们可以让最好的开始是『一开始就朝正确的方向』,同时减少对以这种劳力密集(labor-intensive)方式重做及重测试的需要。 \r\n\r\n--------------------------------------------------------------------- \r\n文件是无用的 \r\n\r\n一个真正的Xtremist相信程序代码不只是设计同时是文件。『无情的重整(Merciless refactoring)』(另一个XP用语)将一直一直一直产生完全干净的程序代码;既使是最没有经验的开发者也能够达成。一个信徒杜撰了一个名词『极端的清澈(Extreme Clarity)』,其中他定义为「一个程序的属性就像程序代码展示每一个人需要知道的系统所有东西;立即上手;一目了然;非常的准确(accurate to six places)」 \r\n\r\n我们没有强辩这不是一个我们想要的结果。而就非程序代码(non-code)文件而言,维持与想象中的快速撰写程序代码机制同步的可能性不是真的吗?而口头的沟通比在多数项目中写下来的作用好不是真的吗?总而言之,「所有的文件要被怀疑是过期及主观的偏见」这些声音对我们而言就像一个无理的对文件的恐惧。 \r\n\r\n事实上,在一个开发成果的背景,够格的技术撰写者知道一些相关程序代码的东西将通常能够赶上开发者及分析者并且维持到目前为止。同时,有效的口头沟通是关键性的重点,但不能免除把数据写下来--为外部的人、为新人、为未来的参考者、为某些目前可能不是很明显的原因。就主观的偏见而言,嗯,所有的写下的都有某种的偏见,但软件文件设想是传达是甚么(what is),而不是可能是甚么(what could be),同时如果那不如此做,不是媒体的错误。 \r\n\r\n除了口头沟通任何事物的缺乏表示撰写程序代码的人必须回答问题。 \r\n\r\n依据历史观点,在近半世纪被无数次用作为『工作保障(job security)』的机制。在太多的案例中,这些人把文件放在他们的脑袋中(或者是团对把文件放在他们集体的脑袋中)在维护程序设计师出现时已是过去式了。 \r\n\r\n这里有一个Doug的故事 \r\n\r\n「我有一个程序设计师为我工作,负责我们的数据流图编辑。他的进度常常延迟。我们开会讨论这种情况。他说--我引用他的话而我记得非常清楚:『你不能让我更快,你不能让别人来帮助我,你不可以解雇我』他很有信心的说,因为所有的设计文件都在它的脑袋中。我非常震惊于他的说法,第二天我解雇了他。这是我做的决定中最好的一个。我以一个人取代他,这个人所写的程序代码非常好,而且随时把他所做的记入文件中。」 \r\n\r\n不管如何,为后人记录图表并不是十分重要的事。检视(reviewing)图表--并据以设计--在撰写程序代码之前是十分重要的事。如果你能让团队中的高级程序设计师检视(并修正)系列的图表中将要撰写程序代码的情节(scenarios),同时你在撰写程序代码之前已查核(verify)架构(静态模式)可以支持所有的情节,你将有一个比较轻松的撰写程序及测试的时光,同时你将使得后续要做的拆开程序代码、重新撰写程序代码及重新测试的工作降至最低。 \r\n\r\n而这里有从Beck所说的:「多数的人表达他们的恐惧;就是把CRC卡转换成数据库(Notes或Access)、Excel,或某些该死的项目管理程序。」因此我们现在看到XP人把客户视为不确定(考虑他们的需求时)并且恐惧(就持续追踪将要发生的事)。我们期待XP信徒(XPites)证实他们的『怀疑』如此XP可以假设拥有传说中的FUD(恐惧(Fear),不确定(Uncertainty),怀疑(Doubt))三位一体,如以往对微软的观感一般。 \r\n\r\n-------------------------------------------------------------------- \r\n询问程序代码 \r\n\r\n我们很高兴的承认程序设计还是有某一程度的『艺术』的成分加上『科学』的元素这个观点;这个观点是我们更想要聚焦的。但有些Xtremists的说法倾向于让像我们这类非信仰的人觉得XP或多或少有个人崇拜的现象。举例来说: \r\n\r\n「重组系统结构(Restructure the system)的基础是系统告诉你的系统想要被如何结构化。」 \r\n\r\n「程序代码要简化。」 \r\n\r\n「系统驾驭(ridding)我更甚于我驾驭系统。」 \r\n\r\n「程序代码异味(smell)是你程序代码当中某部分变糟的暗示(hint)。使用这个异味追踪问题。」 \r\n\r\n「询问程序代码。」 \r\n\r\n这个概念;很显然;是只要程序代码实现,便假设有一个神秘的沟通力量,而建立者义不容辞的倾听;小心的听;这个声音...你会非常想睡...啊,抱歉。 \r\n\r\n这些说法其根本是就Kent Beck而言所有的内容就是程序代码,整个程序代码,除了程序代码以外没有别的。设计代表『幻想(visions)』,分析代表『幻想的幻想(visions of visions)』,而方法论就是整体代表『幻想的幻想的幻想(visions of visions of visions)』 ,以及「当...幻想成真只会恶化问题』。只要开发者的思考是简化的--另一种说法--只要他们能够只写他们的程序代码而无须所有愚笨的前置材料--他们将「没有压力的工作、没有恐惧的工作并喜爱他们的任务及他们自己。」 \r\n\r\n有人要来一杯Kool-Aid吗? \r\n\r\n--------------------------------------------------------------------- \r\n结论 \r\n\r\nXP人喜欢抱怨是如何的没有其它的事。例如,当Doug在OTUG开始指出前置分析是多么好的事情,他得到不只一封的电子邮件询问「你写多少的程序代码,无论如何?」这意涵他写的程序不够多;在Xtremists的眼中不是够格的『真正程序设计师』; 拥有像水一样多的概念却说他不懂得UML的『扩充(extends)』建构式(construct)(我们的书的读者,忠实的OTUG人,已经到这个胡说八道的故事),但这不是重点。重点是XP的拥护者有一种龌龊的倾向羞辱我们是比较喜欢不终极(less extreme);但仍然高度的可运转(workable);尽量建立有品质的软件--而那是太差的,因为有一些好的要素(stuff)在其中。 \r\n\r\n可能有一天我们将看到一个更合理及平衡的开发程序形式。于此之际,我们同意一位在Wiki的仁兄所言「XP最引人注意的特性是它尝试驾驭(ride);而不是压制(quelling)在任何真正的程序设计师内心中深沈的要求,那就是要求开辟一条大道(urge to hack)。 \r\n\r\n于此之际,我想要以一个问题结束这篇文章。 \r\n\r\n假如你决定在你的项目中使用XP,而在六个月之后,你觉得这种方式并未符合你的期望。而没有写下任何东西--没有架构或设计文件及在开发者脑袋中没有项目的任何知识。你会怎么办? \r\n\r\nDoug Rosenburg:dougr@iconixsw.com \r\n\r\nKendall Scott:onSoftDocWiz@aol.com \r\n\r\n---------------------------------------------------------------------- \r\n<译注1>大设计亦即前置设计(upfont),相对于XP的其它开发程序;这些其它的开发程序在开始撰写程序代码之前将所有项目架构做完整的设计被XP追随者称之为大设计或前置设计。 \r\n\r\n<译注2>SP应是作者故意创造用以反讽XP的一个名词。 \r\n\r\n<译注3>对于这点Kent Beck及Martin Fowler在『Planning eXtreme Programming』一书中第三章有所说明。 \r\n\r\n<译注4>银色子弹亦即中文的万灵丹。 \r\n\r\nhttp://www.dotspace.idv.tw \r\n \r\n----\r\n[主题分类]: [软件工程] | [极端编程]\r\n','BrokenDoor','2002-03-04 09:39:18','2002-03-04 09:39:18',0,'BrokenDoor',193),('极端编程讨论区','Test First 是指在写一个类的时候先写测试,还是在写一组类的时候写一组测试?\r\n----\r\n在code之前,先写相关的测试,以测试来驱动code\r\n\r\n----\r\n[主题分类]: [软件工程] | [极端编程]','BrokenDoor','2002-03-04 09:47:48','2002-03-04 09:47:48',0,'BrokenDoor',194),('XP的实践规则','[h1]Extreme Programming (XP)实践[/h1]\r\nv 1.0\r\n整理: BrokenDoor 2002-3-4\r\n----\r\n[h2]1 为什么是XP[/h2]\r\n让我们来考虑一个传统的途径:用户组和开发组协商让一个分析员设计一个项目。在几周和几个月中,分析员和用户每天会面几个小时。分析员生产出一套文档,可能还包括象一个可视描述和用例之类。用户和项目经理(也可能是编程团队)回顾这些文档并且协商出一个发行版。程序员使用规范在几个月之后成长出一个系统,或多或少的实现了原来的想法。在结束的时候这通常是一个闭呼叫系统,当人们发现他们所遗漏的并意识到自从文档被写好以来什么都已经改变了。最后,用户加入进来作一个用户接受测试然后系统被发布。 \r\n\r\n通常整个过程所花费的时间比任何人所期望的都长,会遗漏一些特征,并且质量并不是用户想要的。更有甚着,文档也不再随日期更新。 \r\n\r\n问题总结:\r\n 不能完全理解用户需求(用户自己也经常不清楚自己需要什么)\r\n 用户的要求不断变化\r\n 技术更新速度很快\r\n 开发人员缺乏成功经验\r\n 开发小组不稳定\r\n 没有完整的测试设计\r\n\r\n----\r\n[h2]2 XP简介[/h2]\r\nXP全名Extreme Programming ,一种轻量级,灵活的方法。\r\nXP 规定了一组核心价值和方法,可以让软件开发人员发挥他们的专长:编写代码。XP 消除了大多数重量型过程的不必要产物,通过减慢开发速度、耗费开发人员的精力(例如干特图、状态报告,以及多卷需求文档)从目标偏离。\r\n在XP中,在用户vs程序员的角色中有一个基本的分隔。用户拥有*what you get*,而程序员拥有*what it costs*。这显示了谁能作出什么决定。 即用户做企业决策,程序员做技术决策。\r\n\r\n2.1 用户决定:\r\n* 范围:什么系统是必须作的。 \r\n* 优先级:对于企业价值什么是最重要的。 \r\n* 发行的组合:什么是必须在发行版中的,一定是有用的? \r\n* 发行的日期:什么时候需要发行? \r\n\r\n2.2 程序员决定:\r\n* 评估添加一个特征的时间 ,以及每个特征的风险 \r\n* 使用各种技术选项所花费的成本 :程序员解释程序选择的结果,但是用户作决定 \r\n* 过程:小组怎么样工作,团队怎么组织 \r\n* 细节时间表:在一个迭代中特征先开发风险最大的那一个特征可以减轻风险\r\n\r\n2.3 XP 的核心价值为:\r\n* 交流。 项目的问题往往可以追溯到某人在某个时刻没有和其他人一起商量某些重要问题上。使用 XP,不交流是不可能的事。\r\n\r\n* 简单。 XP 建议您总是尽可能围绕过程和编写代码做最简单的事情。按照 Beck 的说法,“XP 就是打赌。它打赌今天最好做些简单的事...而不是做更复杂但可能永远也不会用到的事。”\r\n\r\n* 反馈。 更早和经常来自客户、团队和实际最终用户的具体反馈意见为您提供更多的机会来调整您的力量。反馈可以让您把握住正确的方向,少走弯路。\r\n\r\n* 勇气。 勇气存在于其它三个价值的环境中。它们相互支持。需要勇气来相信一路上具体反馈比预先知道每样事物来得更好。需要勇气来在可能暴露您的无知时与团队中其他人交流。需要勇气来使系统尽可能简单,将明天的决定推到明天做。而如果没有简单的系统、没有不断的交流来扩展知识、没有掌握方向所依赖的反馈,勇气也就失去了依靠。 \r\n\r\n----\r\n[h2]3 XP的十二种实践方法: [/h2]\r\n* 重新划分(Refactoring) \r\n* 系统比喻(Metaphor) \r\n* 简单设计(Simple design) \r\n* 一周40小时 (40-hour week) \r\n* 编码标准(Coding standards) \r\n* 持续集成(Continuous integration) \r\n* 成对编程(pair programming) \r\n* 集体代码所有权(Collective ownership) \r\n* 现场客户(On-site customer) \r\n* 规划策略(Planning game) \r\n* 小发行版(Small releases) \r\n* 测试(Testing)\r\n\r\n3.1 规划策略\r\n有些人会指责 XP 是一种美其名的剽窃,只是一群牛仔在没有任何规则的情况下将一个系统拼凑在一起。错。XP 是为数不多的几种承认您在开始时不可能事事通晓的方法之一。无论是用户还是开发人员都是随着项目的进展过程才逐步了解事物的。只有鼓励和信奉这种更改的方法才是有效方法。状态限定方法忽视更改。而 XP 则留心更改。它倾听所用的方法就是*规划策略*,一个由 Kent Beck 创造的概念。\r\n这一方法背后的主要思想是迅速地制定粗略计划,然后随着事物的不断清晰来逐步完善。规划策略的产物包括:一堆索引卡,每一张都包含一个客户素材,这些素材驱动项目的迭代;以及对下一两个发行版的粗略计划,如 Kent Beck 和 Martin Fowler 在他们的 Planning Extreme Programming 中描述的那样。让这种形式的计划得以发挥作用的关键因素是让用户做企业决策,让开发小组做技术决策。如果没有这一前提,整个过程就会土崩瓦解。\r\n\r\n3.2 系统比喻\r\n体系结构是做什么用的?它提供了系统各种组件以及它们是如何交互的画面 -- 一种映射,可以让开发人员了解新的代码部分适合放在哪里。\r\nXP 中的系统比喻与大多数方法称作的体系结构差不多。比喻为团队提供了一致的画面,他们可以用它来描述现有系统的工作方式、新部件适合的位置,以及它们应该采取的形式。\r\n重要的是要记住,关键要让每个人理解系统是如何组合在一起的,而不是美丽的比喻。有时您就是无法想到一个好的比喻。想到时就太好了。 \r\n\r\n3.3 测试\r\n在 XP 中有两种测试: \r\n1. 单元测试 \r\n2. 验收测试 \r\n开发人员在他们编写代码的同时编写单元测试。客户在他们定义了素材后编写验收测试。单元测试及时告诉开发人员系统在某一点上是否*工作*。验收测试告诉团队系统是否执行用户希望它执行的操作。\r\n假设团队使用的是如 Java 这样的面向对象语言,开发人员在为一些方法编写代码之前为每种有可能失败的方法编写单元测试。然后他们编写足够的代码使之能通过测试。有时人们会发现这有点奇怪。答案很简单。编写测试首先为您提供: \r\n* 一组可能最完整的测试 \r\n* 可能能工作的最简单的代码 \r\n* 代码意图的明确景象 \r\n开发人员只有在通过所有单元测试后才可以将代码检入到源代码资源库中。单元测试使开发人员有信心相信他们的代码能够工作。这为其他开发人员留下线索,可以帮助他们理解最早的开发人员的意图(实际上,这是我们看到过的最好的文档)。单元测试还给了开发人员勇气重新划分代码,因为测试失败可以立刻告诉开发人员存在错误。应该将单元测试自动化,并提供明确的通过/失败结果。xUnit 框架做到的远不止这些,因此大多数 XP 小组都使用它们。\r\n用户负责确保每个素材都有验收测试来确认它们。用户可以自己编写测试、可以征募组织中的其他成员(例如 QA 人员或业务分析员)编写它们,也可以将这两种方法结合起来。测试告诉他们系统是否具有应该具有的那些特性,以及是否可以正确工作。理想情况下,用户在迭代完成之前就应该写好迭代中那些素材的验收测试了。应该将验收测试自动化,并要经常运行来确保开发人员在实现新特性时没有破坏任何现有的特性。通常情况下,客户需要来自开发团队的某些帮助来编写验收测试。我们对一个项目开发一个可重用的自动验收测试框架,可以让用户在简单编辑器中输入他们的输入和所期望的输出。框架将输入转换成 XML 文件、运行文件中的测试,然后为每个测试显示*通过*或*失败*。客户喜欢这一做法。\r\n不是所有验收测试都必须在所有情况下通过。问题是验收测试帮助客户衡量项目*完成*的情况如何。它们还可以让客户获悉有关某些事物是否可以发行的决定。\r\n\r\n3.4 重构\r\n重构是在不更改功能性的前提下对代码加以改进。XP 小组在进行重构时毫不手软。\r\n开发人员重构有两个重要时机:实现特性之前和之后。开发人员尝试确定更改现有代码是否可以让新特性的开发更容易。他们查看刚刚写好的代码,看是否有方法可以对它进行简化。例如,如果他们认为有抽象的机会,就会进行重构来从具体实现中除去重复的代码。\r\nXP 建议您应该编写可能运行的最简单的代码,但同时也建议您应该不断学习。重构让您将学到的知识加入到代码中,同时又不会破坏测试。它使您的代码简练。这意味着它可以存在相当长的时间、为以后的开发人员引入更少问题,并为他们指引正确的方向。\r\n\r\n3.5 成对编程\r\n使用 XP,成对的开发人员编写所有产品代码。这种方式听上去好象缺乏效率。Martin Fowler 说,*当人们说成对编程降低生产力时,我回答,\'那是因为大多数耗费时间的编程部分是靠输入来完成的。\'*实际上,成对编程无论在经济还是其它方面都提供了许多好处: \r\n* 所有设计决策都牵涉到至少两个人。 \r\n* 至少有两个人熟悉系统的每一部分。 \r\n* 几乎不可能出现两个人同时疏忽测试或其它任务。 \r\n* 改变各对的组合在可以在团队范围内传播知识。 \r\n* 代码总是由至少一人复查。 \r\n研究还显示成对的编程实际上比单独编程更有效。\r\n\r\n3.6 小发行版\r\n发行版应该尽可能地小,同时仍然提供足够的企业价值以证明它们值得。\r\n只要觉得有意义就可以发布系统。这样就尽可能早为用户提供了价值(请记住,今天的钱比明天的钱来得值钱)。小发行版将为开发人员提供具体的反馈意见,告诉他们哪些符合客户需要,哪些不符合客户需要。然后,小组可以将这些经验教训包括在其下一发行版的规划中。\r\n\r\n3.7 简单的设计\r\nXP 的诽谤者说该过程忽略了设计。事实不是这样。问题是重量型方法建议您做的不过是提前完成大部分琐碎的设计任务。这就象是拍一张静态的地平线的照片,静止不动,然后尝试画一张如何到达那里的完美的地图。XP 说设计不应该在事物将保持不变的前提下预先仓促进行。XP 认为设计非常重要,因此应该是一个持续的事务。我们总是先尝试使用能够工作的最简单的设计,然后随着现实的不断显现来更改它。\r\n什么是可能工作的最简单的设计?它是符合以下条件的设计: \r\n* 运行所有测试 \r\n* 不包含重复代码 \r\n* 明确陈述程序员对所有代码的意图 \r\n* 包含尽可能最少的类和方法 \r\n对简单设计的需求并不是说所有设计都很小,也不表示它们是无足轻重的。它们只不过需要尽可能简单,但是仍能工作。不要包括不使用的额外特性。我们称这样的事物为 YAGNI,表示*您将不需要它(You Aren\'t Going to Need It)。*不要让 YAGNI 破坏您成功的机会。\r\n\r\n3.8 集体代码所有权\r\n小组中的任何人都应该有权对代码进行更改来改进它。每个人都拥有全部代码,这意味着每个人都对它负责。这种技术可以让人们对部分代码进行必要的更改而不用经过代码拥有者个人的瓶颈。每个人都负责这一事实消除了无代码所有权所带来的混乱。\r\n*每人拥有所有代码*与*没人拥有代码*的说法并不一样。没人拥有代码时,人们可以随处进行破坏而不必负任何责任。而 XP 说,*如果是您破坏的,应该您来弥补。*我们有一些必须在每次集成之前和之后运行的单元测试。如果您破坏了某些事物,您要负责进行修补,无论它位于代码的哪一部分。这需要极端规则。可能这是名称中带有*极端*的另一个原因。\r\n\r\n3.9 持续的集成\r\n经常进行代码集成可以帮助您避免集成梦魇。XP 团队在一天中集成了代码几次,每次都在所有单元测试对系统运行后执行。\r\n传统方法工作方式如下:编写大量代码后执行一次大爆炸式的集成,然后花费相当长的时间来改正问题。这种笨拙的形式的确使项目速度减缓。大爆炸式的集成给团队立即带来大量问题,并且这些问题通常都有几百种可能的原因。\r\n如果经常进行集成,任何特定集成失败的原因都会非常明显(以前运行过测试,因此错误一定是新事物犯下的)。使用这种方法,当遇到问题时,可能的原因就相当有限。修改起来更容易,花的时间少得多,使团队保持最快速度前进。\r\n\r\n3.10 现场客户\r\n要使功能最理想,XP 小组需要在现场有一位客户来明确素材,并做出重要的企业决策。开发人员是不允许单独做这些事情的。让客户随时在场可以消除开发人员等待决策时出现的瓶颈。\r\nXP 不会假装素材卡是开发人员交付必要代码所需的唯一指示。素材是对以后在客户和开发人员之间填写细节的对话的一项承诺。与将所有要求写在一个静态文档中不同,其思想是进行面对面的交流,减少产生误解的机会。\r\n我们发现让客户在现场是可能最好的一种情形,但这不是解决问题的唯一方案。底线是客户必须随时在需要回答问题和根据企业价值为团队提供指示时有空。如果客户并非在现场专职陪伴团队的情况下就能做到这些,那很好。如果能和团队待在一起,这会更方便,但只是建议而已。\r\n\r\n3.11 编码标准\r\n拥有编码标准有两个目的: \r\n* 防止团队被一些例如事物没有以最大速度发展这种无关紧要的愚蠢争论搞得不知所措。 \r\n* 它支持其它方法。 \r\n如果没有编码标准,重新划分代码会更加困难,按应当的频度交换对更困难,快速前进也更困难。目标应该是团队中没有人辨认得出是谁写的哪一部分代码。以团队为单位对某一标准达成协议,然后遵守这一标准。目标不是创建一个事无巨细的规则列表,而是提供将确保您的代码可以清晰交流的指导方针。编码标准开始时应该很简单,然后根据团队经验逐步进化。不要预先花费太多时间。创建能够工作的最简单标准,然后逐步发展。\r\n\r\n3.12 一周 40 小时\r\nKent Beck 说他希望*...每天早晨都感到有活力有激情,每天晚上都感到疲惫而满足。*一周 40 小时工作可以让您做到这一点。确切的小时数并不重要,重要的是原则。长时间地持续工作会扼杀工作绩效。疲劳的开发人员会犯更多错误,从长期来说,将比按*正常*时间表进行的开发慢得多。\r\n即使开发人员可以在长时间很好工作,这也不意味着他们应该这样。最终他们会厌倦,会离开他们的工作,或者产生影响他们工作绩效的非工作问题。如果您打乱了人们的生活,将会尝到它所带来的恶果。加班并不是解决项目问题的答案。实际上,它是更大问题的症状。如果您要走向灭亡,就无药可救了。\r\n\r\n----\r\n[h2]4 XP过程中的各个阶段[/h2]\r\n作为一个软件开发过程,XP中计划,设计,编码和测试各阶段包括的内容比较简洁,容易实施。\r\n\r\n4.1 计划\r\n* User stories的编写 \r\n* 识别需求方面 \r\n* 开发计划的制定 \r\n* 经常构造版本 \r\n* 版本控制 \r\n* Load Factor因子的确定 \r\n* 将项目分解为各个迭代期 \r\n* 每个迭代期开始时制定计划 \r\n* 人员集中 \r\n* 站着开每日晨会 \r\n* 当实施遇到困难时及时修正 \r\n\r\n4.2 测试\r\n* 所有代码均需进行单元测试 \r\n* 发行之前所有代码必须通过单元测试 \r\n* Bug发现后应马上测试  \r\n\r\n4.3 编码\r\n* 始终获得用户的支持 \r\n* 代码的书写必须按照规范 \r\n* 所有代码均采用配对开发 \r\n* 一次只能有一对开发人员进行发行 \r\n* 代码经常集成 \r\n* 代码共享 \r\n* 将优化放在最后 \r\n* 不要加班 \r\n\r\n4.4 设计 \r\n* 简单化 \r\n* 采用编程规范 \r\n* 设计时使用CRC卡片 \r\n* 使用Spike Solution 方法 \r\n* 不要过早添加新功能 \r\n* 尽可能保持程序的简洁性 \r\n\r\n----\r\n[h2]5 相关资料[/h2]\r\n Extremeprogramming: http://www.extremeprogramming.org/\r\n XPdeveloper: http://http://www.xpdeveloper.com/\r\n Xprogramming: http://www.xprogramming.com/\r\n Junit: http://www.junit.org/\r\n\r\n----\r\n[主题分类]: [软件工程] | [极端编程]','BrokenDoor','2002-03-04 10:00:35','2002-03-04 10:00:35',0,'BrokenDoor',195),('使用 Translator 模式构建更好的网站','[h1]使用 Translator 模式构建更好的网站[/h1]\r\n作者:Donald S Bell IBM 的 IT 专家 \r\n----\r\n本文介绍 Translator 模式,并说明如何在 JSP 技术和 servlet 环境中使用 Translator 模式。读完本文以后,您将能够利用本文提供的代码示例成功实现这一模式。\r\n----\r\n在使用 JSP 文件和 servlet 构建 Web 应用程序时,应用程序的界面多半会是 HTML。浏览器翻译后的 HTML 就是一个大型字符串。构成应用程序的业务对象只有少数属性为字符串,其余属性则为日期、数字甚至其他业务对象。在构建 Web 应用时,如何将业务对象所包含的信息转换为浏览器可识别的 HTML 是个大问题。几乎每个应用程序都会以 HTML 格式收集信息,而这些信息又会作为字符串发送给服务器。因此现在还存在如何将所提交的信息转换为业务对象可识别的值这一问题。\r\n\r\nTranslator 模式通过提供一个与 JSP 文件、servlet 和业务对象协同工作的 Translator 对象解决了这两个问题。Translator 对象将三个不同对象结合在一起,从而使每个对象都专用于完成一项给定的任务。Translator 对象之所以可充当这个纽带,是因为它封装了要完成的全部转换逻辑。JSP 文件与 Translator 对象通信,专用于显示信息。这使 JSP 文件变得比较“干净”,即 JSP 文件中几乎没有 Java 代码。servlet 专门处理业务对象的持久性和屏幕之间的导航流。有了 servlet 专门处理这些任务,JSP 文件就几乎不需要 Java 代码了,从而使 JSP 文件变得更加“干净”。\r\n\r\n[h2]更详细一点[/h2]\r\n如前所述,Translator 模式由三个基本部分组成,分别是专用的 Translator 对象、servlet 和 JSP 文件。\r\n\r\nJSP 文件的唯一职责就是充当用户界面类。这是可能的,因为 JSP 文件从 Translator 对象获取预先格式化好的字符串值(稍后讨论)。JSP 文件应包含尽可能少的 Java 代码,因为负责开发 JSP 文件的网页设计者通常对 Java 编程语言知之甚少,或者干脆就一无所知。使内嵌在 JSP 文件中的 Java 代码尽可能达到最少,这样就使 JSP 文件更像纯 HTML 页面。与整篇都纠缠着 Java 代码的 JSP 文件相比,纯 HTML 页面的修改要容易得多。\r\n\r\nTranslator 对象是一种专用的类,它类似于 MVC 模式中的模型 (model) 类。Translator 对象将业务对象与 JSP 文件中的显示域联系起来。网页设计者将调用 Translator 对象的一个 getter 方法在 JSP 文件中显示动态信息。Translator 对象将返回一个预先格式化好的字符串,因此网页设计者需要做的全部工作就是将它发送到一个输出流中。Translator 对象能够提供此信息,因为它在内部变量中存储着需要显示的全部值。这些变量是由 syncGuiToModel() 和 processForm() 方法设置的。这两个方法专门处理屏幕和 Translator 之间的信息同步。小组中的 Java 开发人员负责构建这个 Translator 对象。\r\n\r\n最后,servlet 专用于处理导航流和业务对象的持久性。当 servlet 接收到提交表单时,它将获得 Translator 对象的一个实例,并使用 processForm() 方法将对表单的分析委派给 Translator 对象。在表单的分析完成以后,servlet 就会让 Translator 对象使用 syncModelToGui() 方法将业务对象的值同步为表单中所提交的值。在成功转换所提交的值并将它们设置到业务对象上之后,servlet 将对业务对象执行持久化,并向网页访问者显示确认页。\r\n\r\n[h2]给我显微镜[/h2]\r\n下面我们仔细查看 Translator 模式的三个部分:JSP 文件、servlet 和 Translator 对象。(本文的示例遵循的是 Servlet 2.1 规范和 JSP 1.0 规范。这些示例是在 WebSphere 3.02 和 WebSphere 3.5 环境下构建和测试的。)\r\n\r\n\'\'\'JSP 文件\'\'\'\r\n使用 Translator 模式的典型 JSP 输入表单如下所示:\r\n[no]\r\n<%@ page extends=\"com.ibm.igs.ispkcm.translator.JspBase\"\r\n import=\"com.ibm.developerworks.translatorpattern.LoanTranslator,\r\n Java.util.Hashtable\"%>\r\n\r\n<%\r\n LoanTranslator ltLoan = LoanTranslator.getInstance(request);\r\n Hashtable htErrors = ltLoan.getErrors();\r\n%>\r\n\r\n\r\n\r\n<%= displayErrors(htErrors) %>\r\n\r\n <%= hightLightErrors(ltLoan.BORROWER_LAST_NAME, htErrors) %>Borrower Last Name:\r\n \"\r\n value=\"<%= ltLoan.getBorrowerLastName() %>\">\r\n\r\n\r\n\r\n[/no]\r\n \r\n在 Translator 模式中,所有表单都是 JSP 文件,而非 HTML 文件,所以输入域的值可以是动态的。这一点很重要,因为我们网站的访问者是实实在在的人,他们会犯输入错误。比让网站通知您它不接受您的输入更糟糕的唯一一件事情是,让它通知您它不接受您在某个域中输入的内容,并要求您重新键入其他 20 个域,因为某个程序员正忙于检查股市报价,没有时间来提高输入表单的用户友好性。在 Translator 模式中,输入表单的每个输入域的值都是动态设置的,因此如果因存在输入错误而需要向网站访问者重新显示输入页,他们就会看到突出显示的错误,但其他输入项仍然保留。 \r\n\r\n请记住,JSP 文件是由对 Java 代码知之甚少或一无所知的网站设计者编写和维护的。鉴于这个原因,我们希望 JSP 文件包含尽可能少的 Java 代码。但我们在上一段的说明听起来好像需要编写大量的 Java 代码。该 JSP 文件示例只有少量 Java 代码,但它们主要位于表达式 (<%= x %>) 中。它们能够使用这些众多的功能,因为 JSP 文件从它的超类 com.ibm.igs.ispkcm.translator.JspBase 中继承了这些代码,并将大量代码放在 Translator 对象中。\r\n\r\n在此 JSP 文件中,要注意的第一点是它有一个 page 指令标记。这是因为它需要继承一个超类,并需要导入两个类。JSP 文件继承了超类 com.ibm.igs.ispkcm.translator.JspBase,因为 JspBase 包括一些很好的实用函数,它使得 JSP 文件可包含更少的代码。该 JSP 文件所用的主要实用函数是 displayErrors() 和 highLightErrors()。该 page 指令导入 LoanTranslator 和 Hashtable,因为 JSP 文件中引用了这两个类,导入这两个类是为了以后在此 JSP 代码中引用这两个类时不必使用它们完全限定的类名。以下代码显示了 import 语句的一个示例:\r\n[no]\r\n<%@ page extends=\"com.ibm.igs.ispkcm.translator.JspBase\"\r\n import=\"com.ibm.developerworks.translatorpattern.LoanTranslator,\r\n Java.util.Hashtable\"%>\r\n[/no]\r\n\r\nJSP 文件中第一行真正的 Java 代码获取 Translator 对象的一个实例,然后获取一个 Hashtable,其中存储着属于 Translator 对象的那个实例的错误。因为 JSP 文件(在编译后)是一个 servlet,所以它是一个无状态的服务对象。Translator 对象将在特定 JSP 文件或 servlet 的不同往返之间维护必要的状态信息。状态信息应仅限于网站访问者输入的值和要向网站访问者显示的任何处理错误。因为 Translator 对象的每个实例都与一个特定的网站访问者相关联,所以 JSP 文件调用 Translator 对象的 getInstance(HttpServletRequest) 方法。由于为该方法传递的是一个 HttpServletRequest 对象,所以该方法将能够检索与该网站访问者的 HttpSession 相关的 Translator 实例。\r\n[no]\r\n<%\r\n LoanTranslator ltLoan = LoanTranslator.getInstance(request);\r\n Hashtable htErrors = ltLoan.getErrors();\r\n%>\r\n[/no]\r\n \r\n\r\n在此 JSP 文件示例中,网站访问者将在表单的顶部看到所有处理错误。用来显示这些错误消息的 HTML 是使用 <%= displayErrors(htErrors) %> 表达式输出的。displayErrors() 方法是从 JSP 文件的超类 JspBase 中继承而来的。有了 displayErrors(),用于显示错误消息的所有逻辑都被集中在一起,从而简化了维护工作。\r\n\r\n下面这段代码模板适用于表单上的每个输入域:\r\n[no]\r\n<%= hightLightErrors(ltLoan.BORROWER_LAST_NAME, htErrors) %>Borrower Last Name:\r\n\"\r\n value=\"<%= ltLoan.getBorrowerLastName() %>\">\r\n[/no] \r\n\r\nhighLightErrors() 是从 JSP 文件的超类 JspBase 中继承而来的。如果某个输入域有错误,该方法将突出显示该输入域的标签。该方法接收两个参数:String 和Hashtable。该 Hashtable 是其中存储着从 Translator 的实例检索而来的错误的 Translator。String 是正在检查其是否有错误的输入域的名称。如果存在与该域相关的错误,highLightErrors() 就会返回突出显示此输入域的标签的 HTML。\r\n\r\n在此代码模板中,须注意的重要一点是:INPUT 标记的 name 属性是由一个表达式设置的,该表达式使用 LoanTranslator 对象的 BORROWER_LAST_NAME 常量。因为在 JSP 文件中引用此域名时使用了一个常量,所以 Translator 对象和 servlet 的调试变得更加容易。使用常量更为容易,因为无论何时开发人员更改此域的名称,他们都会获得一个编译错误,而非运行时错误。查找编译错误要容易得多,因为编译器会立即指出错误,而运行时错误到调试和测试期间才能被发现。\r\n\r\n有关此代码模板的最后一个(也是最重要的一个)注意事项是:INPUT 标记的 value 属性是由一个表达式设置的,该表达式使用了 Translator 的一个 getter 方法。value=\"<%= ltLoan.getBorrowerLastName() %> 这行代码是此模式最重要的部分之一,因为它就是使输入域的值缺省为网站访问者最初输入的值的代码。通过将此值缺省设置为网站访问者最初输入的值,访问者就能看到他最初输入的内容,并很容易地修正他的错误。这节省了网站访问者的时间,并能使其获得更好的用户体验。\r\n\r\n\'\'\'servlet\'\'\'\r\n下面是一个典型的简化 servlet:\r\n[code]\r\npublic void doPost(HttpServletRequest request, HttpServletResponse response)\r\n{\r\n // 缺省设置是使用户返回输入页。\r\n String sRedirect = LOAN_JSP;\r\n\r\n // 获取 Translator 的正确实例\r\n LoanTranslator ltTrans = LoanTranslator.getInstance(request);\r\n\r\n // 现在有了 Translator 的一个实例\r\n ltTrans.processForm(request);\r\n\r\n // 获取 Loan 的正确版本的逻辑\r\n Loan lnTheLoan = null;\r\n if (ltTrans.isNew () == true)\r\n {\r\n // 创建新 Loan\r\n }\r\nelse\r\n {\r\n // 获得现有的 loan\r\n }\r\n // Sync the Loan object values to values in the submitted form.\r\n ltTrans.syncModelToGui(lnTheLoan);\r\n\r\n // 确保未出现任何错误\r\n if (ltTrans.hasErrors() == false)\r\n {\r\n // 提交 Loan 信息,然后将重定向设置为正确的尾随页\r\n sRedirect = LOAN_CONFIRMATION;\r\n }\r\n\r\n // 将网站访问者重定向为当前工资。\r\ntry {\r\n response.sendRedirect(sRedirect);\r\n }\r\n catch (Exception e)\r\n {\r\n // 错误逻辑\r\n }\r\n}\r\n[/code]\r\n \r\nservlet 的主要用途是控制 JSP 文件之间的导航流以及对业务对象执行持久化。此 servlet 的代码很简单。 \r\n\r\nservlet 执行的第一个操作就是从 HttpServletRequest 中获取 Translator 对象的一个实例。 \r\n随后 servlet 使用 processForm() 方法将对所提交的 HTML 表单的处理委派给 Translator。 \r\n在 Translator 分析表单之后,servlet 将确定是否需要从第二存储中创建或检索业务对象(示例中的 Loan)。 \r\n在 servlet 拥有业务对象的一个实例之后,servlet 就会调用 Translator 对象的 syncModelToGui()。syncModelToGui() 随后将网站访问者提交的全部值转换为业务对象可识别的值。 \r\n在 Translator 完成值的同步之后,servlet 将检查当试图转换网站访问者输入的值时,Translator 是否记录了任何错误。 \r\n如果没有记录任何错误,servlet 就会将网站访问者重定向到确认页(通常是另一个 JSP 文件,它同样能显示来自 Translator 的值)。 \r\n如果记录了错误,servlet 就将网站访问者重定向到输入表单,这样他就可以修正错误。\r\n\r\n\'\'\'Translator 对象\'\'\'\r\n因为 Translator 对象是 JSP 文件、servlet 和业务对象之间的联系纽带,所以要求它是有状态的,并且要求它在 HTTP 请求(或线程)之间维护状态。为了符合这个标准,Translator 对象需要起到类似伪孤子 (pseudo singleton) 那样的作用。Translator 类有五个主要部分,另外还有一个前面未曾提及的 Object Translator 类库。 \r\n* getInstance() \r\n* syncGuiToModel() \r\n* 若干 getter 方法 \r\n* processForm() \r\n* syncModelToGui() \r\n* Object Translators 库 \r\n\r\n为了调用 Translator 对象的一个实例,调用程序必须调用静态方法 getInstance(HttpServletRequest)。getInstance() 方法将确定是否应返回 Translator 的一个新实例,或者是否应从 HttpSession 中重用某个实例。该方法通过查看定制参数 action 来实现这一点。此参数是随 HTTP 请求(例如, http://localhost/registerLoan.jsp?action=new)一起传递的。下面的样例代码段显示了 getInstance() 的内容:\r\n[code]\r\npublic static LoanRegistrationTranslator getInstance(HttpServletRequest request)\r\n{\r\n // 声明返回值变量。\r\n LoanRegistrationTranslator lrtRV = null;\r\n\r\n // HttpSession 是必需的,因此在此处将它提取出来。\r\n HttpSession session = request.getSession();\r\n\r\n // 从 request 对象中检索 action 参数。\r\n String sAction = parseString(request, ACTION);\r\n\r\n // 确定我们要返回哪种 Translator。\r\n if (ACTION_PROCESS.equals(sAction) == true)\r\n {\r\n // 因为 action 参数被设置为 process,这表示我们正在处理一个现有的\r\n // Translator,所以从 HttpSession 中将这个 translator 提取出来。\r\n lrtRV = (LoanRegistrationTranslator)\r\n session.getValue(HttpSessionValueKeys.LOAN_REGISTRATION_TRANSLATOR);\r\n }\r\n else if (sAction == null || \"\".equals(sAction) == true ||\r\n ACTION_NEW.equals(sAction) == true)\r\n {\r\n // 由于未设置或根本未传递 action,所以缺省操作是创建一个新的 translator。\r\n // 另一种可能是 action 为 \"new\"\r\n lrtRV = new LoanRegistrationTranslator();\r\n session.putValue(HttpSessionValueKeys.LOAN_REGISTRATION_TRANSLATOR, lrtRV);\r\n }\r\nelse\r\n {\r\n // 由于 action 不满足前面的任何检查,即 action 值是位于辅助存储器中的\r\n // 一个现有 Loan 的 ID,所以这次创建一个 LoanRegistrationTranslator,\r\n // 其值被预设为已保存的 loan 中的值。\r\n lrtRV = new LoanRegistrationTranslator(sAction);\r\n session.putValue(HttpSessionValueKeys.LOAN_REGISTRATION_TRANSLATOR, lrtRV);\r\n }\r\n\r\n // 返回 Translator 对象的一个实例。\r\n return lrtRV;\r\n}\r\n[/code] \r\n\r\n对于要在 JSP 文件中显示的每个业务对象值,Translator 都提供了一个 getter 方法。这些 getter 方法由 JSP 文件调用。必须在 JSP 文件中显示的每个业务对象属性都有一个 getter 方法。getter 方法总是返回一个 String。返回的 String 值已被预先格式化,以便直接在 JSP 文件中显示。预先格式化 String 是为了使 JSP 文件中的 Java 代码尽可能少。对这些值的格式化改为在 syncGuiToModel() 中进行。\r\n\r\nTranslator 使用 processForm() 清除以前显示的错误,并从提交的表单中分析此信息。当 servlet 接收到一个提交的表单时,它就会将对该表单的处理委托给 Translator。在本委托期间,Translator 分析提交表单的值,并将这些值分别存储在 String 变量中。这些存储变量随后通过 syncModelToGui()(由 servlet 调用)转换为业务对象的值。\r\n\r\nsyncGuiToModel() 和 syncModelToGui() 是两个类似的方法,顾名思义,其中一个方法按某个方向对值执行同步,而另一个方法按相反的方向执行同步。syncGuiToModel() 从业务对象的属性中提取这些值,并使用 Object Translator 预先格式化每个属性值。Object Translator 将值预先格式化为要在屏幕上显示的值。随后,它将 Translator 的对应 String 变量设置为这个值。syncModelToGui() 执行的操作相同,但方向相反。下面是从典型的 syncGuiToModel() 中摘出的一小段代码:\r\n[code]\r\nDoubleTranslator dtDouble = new DoubleTranslator();\r\nString sTemp = dtDouble.translate(loan.getInterestRate());\r\nsetInterestRate(sTemp);\r\n[/code]\r\n\r\n为了使转换代码具有最大的可重用性,并为整个站点提供一种共同的转换,syncGuiToModel() 和 syncModelToGui() 使用的都是 Object Translator 类。Object Translators 与 Translator 对象联系得如此紧密,以致于几乎可将它们看作是 Translator 对象的规则。Object Translator 类是一个简单的类,它的唯一用途就是将一种数据类型转换为格式化字符串,以及将格式化字符串转换为它的数据类型。下面是一个很简单的 Object Translator 类的代码:\r\n[code]\r\npublic class DoubleTranslator extends ObjectTranslator\r\n{\r\n public String translate(double doubleValue)\r\n {\r\n return Double.toString(doubleValue);\r\n }\r\n\r\n public double translate(String stringToBeTranslated) throws Exception\r\n {\r\n double dRV = 0.0;\r\n\r\ntry {\r\n Double dbDouble = Double.valueOf(stringToBeTranslated);\r\n dRV = dbDouble.doubleValue();\r\n }\r\n catch(Exception e)\r\n {\r\n Exception eTranslation =\r\n new Exception(\"Please enter a numeric value like 1.0 or 1.25\");\r\n throw eTranslation;\r\n }\r\n\r\n return dRV;\r\n }\r\n}\r\n[/code] \r\n\r\n当这个样例 Object Translator 将 double 转换为格式化的 String 时,它只需调用 Double.toString()。这个方法可实现更强大的功能,例如,可以添加几行代码,使得当格式化类似 1000.25 这样的大 double 值时,可预格式化这个值,以便显示为 1,000.25。\r\n\r\n对于 DoubleTranslator.translate(String),须注意的重要一点是,它会发出一个可读性很好的异常,而不是标准的 Java.lang.NumberFormatException 异常。JSP 文件将此异常的消息直接显示给网站访问者,因此,让网站的普通访问者很容易地理解该方法发出的异常是非常重要的。\r\n\r\n[h2]小结[/h2]\r\n使用 Translator 模式框架的优点很多,不仅可以降低网站的成本,而且可以提高用户的满意度。由于不同组件都只执行专门的任务,因而网站的构建成本降低了。这些专门任务分配给生产小组,如 HTML 小组或 Java 程序员小组。因为 Translator 模式的 ObjectTranslators 在整个网站重用,所有全部格式化和分析都是以相同的方式进行的。因为每项任务都以相同的方式完成,所以网站访问者就能够以一致的方式查看整个网站的信息。这进一步提高了用户的满意度。\r\n\r\n[h2]参考资源[/h2]\r\n下面的 developerWorks 教程可帮助您进一步了解 servlet 和 JSP 文件:\r\nBuilding Java HTTP servlets\r\nhttp://www-105.ibm.com/developerWorks/education.nsf/java-onlinecourse-bytitle/0EE353D3449DB625862569530047CD1A?OpenDocument\r\nBuilding servlets with session tracking\r\nhttp://www-105.ibm.com/developerWorks/education.nsf/java-onlinecourse-bytitle/80CC54124F0ABE25862569B300554AFB?OpenDocument\r\nIntroduction to JavaServer Pages technology\r\nhttp://www-105.ibm.com/developerWorks/education.nsf/java-onlinecourse-bytitle/882707E838C672A185256770004BDE72?OpenDocument\r\n\r\n[h2]作者简介[/h2]\r\nDonald Bell 是 IBM 全球服务中心的 IT 专家,他为客户提供有关基于 Web 的技术应用指导。可以通过 bellds@us.ibm.com 与他联系。\r\n\r\n----\r\n转自: http://61.144.28.245/hjc/web/doc/lang/57.html\r\n----\r\n[主题分类]:[设计模式]\r\n','BrokenDoor','2002-03-04 11:08:26','2002-03-04 11:11:22',0,'BrokenDoor',196),('与大虾对话 - 领悟设计模式',' CSDN - 技术频道 - 文档中心 - Delphi \r\n标题 与大虾对话: 领悟设计模式 programlover(转贴) \r\n关键字 设计模式 ,C++,DELPHI \r\n出处 http://bbs.qilu.tv/topic_show.cgi?id=2197&h=1&bpg=3&age=30 \r\n\r\n[h1]与大虾对话: 领悟设计模式[/h1]\r\n--Template Method / Visitor \r\n\r\n(译者按) 本文根据发表在CUJ Expert Forum上的两篇文章编译而成。C/C++ User\'s Journal是目前最出色的C/C++语言专业杂志,特别是在C++ Report闭刊之后,CUJ的地位更加突出。CUJ Expert Forum是CUJ主办的网上技术专栏,汇集2000年10月以来C++社群中顶尖专家的技术短文,并免费公开发布,精彩纷呈,是每一个C/C++学习者不可错过的资料。由Jim Hyslop和Herb Sutter主持的Conversation系列,是CUJ Expert Forum每期必备的精品专栏,以风趣幽默的对话形式讲解C++高级技术,在C++社群内得到广泛赞誉。译者特别挑选两篇设计模式方面的文章,介绍给大家。设计模式方面的经典著作是GoF的Design Patterns。但是那本书有一个缺点,不好懂。从风格上讲,该书与其说是为学习者而写作的教程范本,还不如说是给学术界人士看的学术报告,严谨有余,生动不足。这一点包括该书作者和象Bjarne Stroustrup这样的大师都从不讳言。实际上Design Pattern并非一定是晦涩难懂的,通过生动的例子,一个中等水平的C++学习者完全可以掌握基本用法,在自己的编程实践中使用,得到立竿见影的功效。这两篇文章就是很好的例证。本文翻译在保证技术完整性的前提下作了不少删节和修改,以便使文章显得更紧凑。 \r\n\r\n---------------------------------------------------------- \r\n人物介绍: \r\n\r\n我 --- 一个追求上进的C++程序员,尚在试用期,聪明但是经验不足。 \r\n\r\nWendy --- 公司里的技术大拿,就坐在我旁边的隔间里,C++大虾,最了不起的是,她是个女的!她什么都好,就是有点刻薄, 我对她真是又崇拜又嫉妒。 \r\n---------------------------------------------------------- \r\n\r\n[h2]I. Virtually Yours -- Template Method模式 [/h2]\r\n\r\n我在研究Wendy写的一个类。那是她为这个项目写的一个抽象基类,而我的工作就是从中派生出一个具象类(concrete class)。这个类的public部分是这样的: \r\n[code]class Mountie { \r\npublic: \r\nvoid read( std::istream & ); \r\nvoid write( std::ostream & ) const; \r\nvirtual ~Mountie(); \r\n[/code]\r\n很正常,virtual destructor表明这个类打算被继承。那么再看看其protected部分: \r\n[code]protected: \r\nvirtual void do_read( std::istream & ); \r\nvirtual void do_write( std::ostream & ) const; \r\n[/code]\r\n也不过就是一会儿的功夫,我识破了Wendy的把戏:她在使用template method模式。public成员函数read和write是非虚拟的,它们肯定是调用protected部分do_read/do_write虚拟成员函数来完成实际的工作。啊,我简直为自己的进步而飘飘然了!哈,Wendy,这回你可难不住我,还有什么招数?尽管放马过来... 突然,笑容在我脸上凝固,因为我看到了其private部分: \r\n[code]private: \r\nvirtual std::string classID() const = 0; \r\n[/code]\r\n这是什么?一个private纯序函数,能工作么?我站了起来, \r\n\r\n“Wendy,你的Mountie类好像不能工作耶,它有一个private virtual function。” \r\n\r\n“你试过了?”她连头都不抬。 \r\n\r\n“嗯,那倒是没有啦,可是想想也不行啊?我的派生类怎么能override你的private函数呢?” 我嘟囔着。 \r\n\r\n“嗬,你倒是很确定啊!”Wendy的声音很轻柔,“你怎么老是这也不行,那也不行的,这几个月跟着我你就没学到什么东西吗?小菜鸟。” \r\n\r\n真是可恶啊... \r\n\r\n“小菜鸟,你全都忘了,访问控制级别跟一个函数是不是虚拟的根本没关系。判断一个函数是动态绑定还是静态绑定是函数调用解析的最后一个步骤。好好读读标准的3.4和5.2.2节吧。” \r\n\r\n我完全处于下风,只好采取干扰战术。“好吧,就算你说的不错,我也还是不明白,何必把它设为private?” \r\n\r\n“我且问你,倘若你不想让一个类中的成员函数被其他的类调用,应当如何处理?” \r\n\r\n“当然是把它设置为private的,” 我回答道。 \r\n\r\n“那么你去看看我的Mountie类实现,特别是write()函数的实现。” \r\n\r\n我正巴不得逃开Wendy那刺人的目光,便转过头去在我的屏幕上搜索,很快,我找到了: \r\n[code]void Mountie::write(std::ostream &Dudley) const \r\n{ \r\n Dudley << classID() << std::endl; \r\n do_write(Dudley); \r\n} \r\n[/code]\r\n嗨,最近卡通片真是看得太多了,居然犯这样的低级失误。还是老是承认吧:“好了,我明白了。classID()是一个实现细节,用来在保存对象时指示具象类的类型,派生类必须覆盖它,所以必须是纯虚的。但是既然是实现细节,就应该设为private的。” \r\n\r\n“这还差不多,小菜鸟。”大虾点了点头,“现在给我解释一下为什么do_read()和do_write()是protected的?” \r\n\r\n这个问题并不难,我组织了一下就回答:“因为派生类对象需要调用这两个函数的实现来读写其中的基类对象。” \r\n\r\n“很好很好,”大虾差不多满意了,“不过,你再解释解释为什么我不把它们设为public的?” \r\n\r\n现在我感觉好多了:“因为调用它们的时候必须以一种特定的方式进行。比如do_write()函数,必须先把类型信息写入,再把对象信息写入,这样读取的时候,负责生成对象的模块首先能够知道要读出来的对象是什么类型的,然后才能正确地从流中读取对象信息。” \r\n\r\n“聪明啊,我的小菜鸟!”Wendy停顿了一下,“就跟学习外国口语一样,学习C++也不光是掌握语法而已,还必须要掌握大量的惯用法。” \r\n\r\n“是啊是啊,我正打算读Coplien的书...” \r\n\r\n(译者注:就是James Coplien 1992年的经典著作Advanced C++ Programming Style and Idioms)\r\n\r\n大虾挥了挥她的手,“冷静,小菜鸟,我不是指先知Coplien的那本书,我是指某种结构背后隐含的惯用法。比如一个类有virtual destructor,相当于告诉你说:‘嗨,我是一个多态基类,来继承我吧!’ 而如果一个类的destructor不是虚拟的,则相当于是在说:‘我不能作为多态基类,看在老天的份上,别继承我。’” \r\n\r\n“同样的,virtual函数的访问控制级别也具有隐含的意义。一个protected virtual function告诉你:‘你写的派生类应该,哦,可是说是必须调用我的实现。’而一个private virtual function是在说:‘派生类可以覆盖,也可以不覆盖我,随你的便。但是你不可以调用我的实现。’” \r\n\r\n我点点头,告诉她我懂了,然后追问道:“那么public virtual function呢?” \r\n\r\n“尽可能不要使用public virtual function。”她拿起一支笔写下了以下代码: \r\n[code]class HardToExtend \r\n{ \r\npublic: \r\nvirtual void f(); \r\n}; \r\nvoid HardToExtend::f() \r\n{ \r\n// Perform a specific action \r\n} \r\n[/code]\r\n“假设你发布了这个类。在写第二版时,需求有所变化,你必须改用Template Method。可是这根本不可能,你知道为什么?” \r\n\r\n“呃,这个...,不知道。” \r\n\r\n“由两种可能的办法。其一,将f()的实现代码转移到一个新的函数中,然后将f()本身设为non-virtual的: \r\n[code]class HardToExtend \r\n{ \r\n// possibly protected \r\nvirtual void do_f(); \r\npublic: \r\nvoid f(); \r\n}; \r\nvoid HardToExtend::f() \r\n{ \r\n// pre-processing \r\ndo_f(); \r\n// post-processing \r\n} \r\nvoid HardToExtend::do_f() \r\n{ \r\n// Perform a specific action \r\n} \r\n[/code]\r\n然而你原来写的派生类都是企图override函数f()而不是do_f()的,你必须改变所有的派生类实现,只要你错过了一个类,你的类层次就会染上先知Meyers所说的‘精神分裂的行径’。” (译者注:参见Scott Meyers,Effective C++, Item 37,绝对不要重新定义继承而来的非虚拟函数)\r\n\r\n“另一种办法是将f()移到private区域,引入一个新的non-virtual函数:” \r\n[code]class HardToExtend \r\n{ \r\n// possibly protected \r\nvirtual void f(); \r\npublic: \r\nvoid call_f(); \r\n}; \r\n[/code]\r\n“这会导致无数令人头痛的问题。首先,所有的客户都企图调用f()而不是call_f(),现在它们的代码都不能编译了。更有甚者,大部分派生类都回把f()放在public区域中,这样直接使用派生类的用户可以访问到你本来想保护的细节。” \r\n\r\n“对待虚函数要象对待数据成员一样,把它们设为private的,直到设计上要求使用更宽松的访问控制再来调整。要知道由private入public易,由public入private难啊!” \r\n\r\n(译者注:这篇文章所表达的思想具有一定的颠覆性,因为我们太容易在基类中设置public virtual function了,Java中甚至专门为这种做法建立了interface机制,现在竟然说这不好!一时间真是接受不了。但是仔细体会作者的意思,他并不是一般地反对public virtual function,只是在template method大背景下给出上述原则。虽然这个原则在一般的设计中也是值得考虑的,但是主要的应用领域还是在template method模式中。当然,template method是一种非常有用和常用的模式,因此也决定了本文提出的原则具有广泛的意义。) \r\n\r\n---------------------------------------------------------------- \r\n[h2]II. Visitor模式[/h2]\r\n我正在为一个设计问题苦恼。试用期快结束了,我希望自己解决这个问题,来证明自己的进步。每个人都记得自己的第一份工作吧,也都应该知道在这个时候把活儿做好是多么的重要!我亲眼看到其他的新雇员没有过完试用期就被炒了鱿鱼,就是因为他们不懂得如何对付那个大虾...,别误会,我不是说她不好,她是我见过最棒的程序员,可就是有点刻薄古怪...。现在我拜她为师,不为别的,就是因为我十分希望能达到她那个高度。 \r\n\r\n我想在一个类层次(class hierarchy)中增加一个新的虚函数,但是这个类层次是由另外一帮人维护的,其他人碰都不能碰: \r\n[code]class Personnel \r\n{ \r\npublic: \r\nvirtual void Pay ( /*...*/ ) = 0; \r\nvirtual void Promote( /*...*/ ) = 0; \r\nvirtual void Accept ( PersonnelV& ) = 0; \r\n// ... other functions ... \r\n}; \r\n\r\nclass Officer : public Personnel { /* override virtuals */ }; \r\nclass Captain : public Officer { /* override virtuals */ }; \r\nclass First : public Officer { /* override virtuals */ }; \r\n[/code]\r\n我想要一个函数,如果对象是船长(Captain)就这么做,如果是大副(First Officer)就那么做。Virtual function正是解决之道,在Personnel或者Officer中声明它,而在Captain和First覆盖(override)它。 \r\n\r\n糟糕的是,我不能增加这么一个虚函数。我知道可以用RTTI给出一个解决方案: \r\n[code]void f( Officer &o ) \r\n{ \r\nif( dynamic_cast(&o) ) \r\n/* do one thing */ \r\nelse if( dynamic_cast(&o) ) \r\n/* do another thing */ \r\n} \r\n\r\nint main() \r\n{ \r\nCaptain k; \r\nFirst s; \r\nf( k ); \r\nf( s ); \r\n} \r\n[/code]\r\n但是我知道使用RTTI是公司编码标准所排斥的行为,我对自己说:“是的,虽然我以前不喜欢RTTI,但是这回我得改变对它的看法了。很显然,除了使用RTTI,别无它法。” \r\n\r\n“任何问题都可以通过增加间接层次的方法解决。” \r\n\r\n我噌地一下跳起来,那是大虾的声音,她不知道什么时候跑到我背后,“啊哟,您吓了我一跳...您刚才说什么?” \r\n\r\n“任何问...” \r\n\r\n“是的,我听清楚了,”我也不知道哪来的勇气,居然敢打断她,“我只是不知道您从哪冒出来的。”其实这话只不过是掩饰我内心的慌张。 \r\n\r\n“哈,算了吧,小菜鸟,”大虾斜着眼看着我,“你以为我不知道你心里想什么!”她把声音提高了八度,直盯着我,“那些可怜的C语言门徒才会使用switch语句处理不同的对象类型。你看:” \r\n[code]/* A not-atypical C program */ \r\nvoid f(struct someStruct *s) \r\n{ \r\nswitch(s->type) { \r\ncase APPLE: \r\n/* do one thing */ \r\nbreak; \r\ncase ORANGE: \r\n/* do another thing */ \r\nbreak; \r\n/* ... etc. ... */ \r\n} \r\n} \r\n[/code]\r\n“这些人学习Stroustrup教主的C++语言时,最重要的事情就是学习如何设计好的类层次。” \r\n\r\n“没错,”我又一次打断她,迫不及待地想让Wendy明白,我还是有两下子的,“他们应该设计一个Fruit基类,派生出Apple和Orange,用virtual function来作具体的事情。 \r\n\r\n“很好,小菜鸟。C语言门徒通常老习惯改不掉。但是,你应该知道,通过使用virtual function,你增加了一个间接层次。”她放下笔,“你所需要的不就是一个新的虚函数吗?” \r\n\r\n“是的。可是我没有权力这么干。” \r\n\r\n“因为你无权修改类层次,对吧!” \r\n\r\n“您终于了解了情况,我们没法动它。也不知道这个该死的类层次是哪个家伙设计的...” 我嘀嘀咕咕着。 \r\n\r\n“是我设计的。” \r\n\r\n“啊...,真的?!这个,嘿嘿...”,我极为尴尬。 \r\n\r\n“这个类层次必须非常稳定,因为有跨平台的问题。但是它的设计允许你增加新的virtual function,而不必烦劳RTTI。你可以通过增加一个间接层次的办法解决这个问题。请问,Personnel::Accept是什么?” \r\n\r\n”嗯,这个...” \r\n\r\n“这个类实现了一个模式,可惜这个模式的名字起得不太好,是个PNP,叫Visitor模式。” \r\n\r\n(译者注:PNP,Poor-Named Pattern, 没起好名字的模式)\r\n\r\n“啊,我刚刚读过Visitor模式。但是那只不过是允许若干对象之间相互迭代访问的模式,不是吗?” \r\n\r\n她叹了一口气,“这是流行的错误理解。那个V,我觉得毋宁说是Visitor,还不如说是Virtual更好。这个PNP最重要的用途是允许在不改变类层次的前提下,向已经存在的类层次中增加新的虚函数。首先来看看Personnel及其派生类的Accept实现细节。”她拿起笔写下: \r\n[code]void Personnel::Accept( PersonnelV& v ) \r\n{ v.Visit( *this ); } \r\n\r\nvoid Officer::Accept ( PersonnelV& v ) \r\n{ v.Visit( *this ); } \r\n\r\nvoid Captain::Accept ( PersonnelV& v ) \r\n{ v.Visit( *this ); } \r\n\r\nvoid First::Accept ( PersonnelV& v ) \r\n{ v.Visit( *this ); } \r\n[/code]\r\n“Visitor的基类如下:” \r\n[code]class PersonnelV/*isitor*/ \r\n{ \r\npublic: \r\nvirtual void Visit( Personnel& ) = 0; \r\nvirtual void Visit( Officer& ) = 0; \r\nvirtual void Visit( Captain& ) = 0; \r\nvirtual void Visit( First& ) = 0; \r\n}; \r\n[/code]\r\n“啊,我记起来了。当我要利用Personnel类层次的多态性时,我只要调用Personnel::Accept(myVisitorObject)。由于Accept是虚函数,我的myVisitorObject.Visit()会针对正确的对象类型调用,根据重载法则,编译器会挑选最贴切的那个Visit来调用。这不相当于增加了一个新的虚拟函数了吗?” \r\n\r\n“没错,小菜鸟。只要类层次支持Accept,我们就可以在不改动类层次的情况下增加新的虚函数了。” \r\n\r\n“好了,我现在知道该怎么办了”,我写道: \r\n[code]class DoSomething : public PersonnelV \r\n{ \r\npublic: \r\nvirtual void Visit( Personnel& ); \r\nvirtual void Visit( Officer& ); \r\nvirtual void Visit( Captain& ); \r\nvirtual void Visit( First& ); \r\n}; \r\n\r\nvoid DoSomething::Visit( Captain& c ) \r\n{ \r\nif( femaleGuestStarIsPresent ) \r\nc.TurnOnCharm(); \r\nelse \r\nc.StartFight(); \r\n} \r\n\r\nvoid DoSomething::Visit( First& f ) \r\n{ \r\nf.RaiseEyebrowAtCaptainsBehavior(); \r\n} \r\nvoid f( Personnel& p ) \r\n{ \r\np.Accept( DoSomething() ); // 相当于 p.DoSomething() \r\n} \r\n\r\nint main() \r\n{ \r\nCaptain k; \r\nFirst s; \r\n\r\nf( k ); \r\nf( s ); \r\n} \r\n[/code]\r\n大虾满意地笑了,“也许这个模式换一个名字会更好理解,可惜世事往往不遂人意...”。 \r\n\r\n----\r\n[主题分类]: [设计模式]','BrokenDoor','2002-03-04 11:27:11','2002-03-04 11:27:11',0,'BrokenDoor',197),('中文:错误','[中文:错误t]\r\n[XP:测试t]\r\n[ddd这dd:dd]','浆糊','2002-03-04 13:14:56','2002-03-04 13:41:11',0,'BrokenDoor',198),('2002年2月27日的会议纪要','WebPM - v1.0 - 会议纪要 - 2002-2-28 16:04\r\n----\r\nCopyLeft (l) 2001 Softme Studio\r\nBrokenDoor 2002-3-4 15:10\r\n----\r\n\r\n\'\'\'1. 说明\'\'\'\r\n----\r\n主题: WebPM 1.0 重要会议\r\n时间: 2002-2-27 晚 7:30 - 10:20\r\n参加人员: 全体WebPM开发小组成员以及用户\r\n实到人员: 扫地的癞蛤, 浆糊, takaka, brokendoor, scaler\r\n\r\n\'\'\'2. 实际讨论的主题\'\'\'\r\n----\r\n2.1 关于WebPM的发展战略\r\n将WebPM 的主要需求归纳到以下三个方面:\r\n1)\'\'\'信息管理\'\'\': 主要依赖wiki提供支持.\r\n2)\'\'\'实时交流\'\'\':[no]理想状态是要有一个网络的虚拟工作室,现在先从MeetingRoom和WhiteBoard开始。[/no]\r\n3)\'\'\'软件过程支持\'\'\': 主要依赖于工作流(workflow)进行支持。\r\n\r\n根据目前的情况,除非有足够的人员加入,WebPM Wiki 子项目在v1.2的开发完成后,进入暂停阶段。小组将集中精力投入其他子项目的基础开发工作,务求尽快的实现WebPM的整体框架。\r\n\r\n小组成员基本上同意WebPM Wiki v1.2发布后,投入[webpm_net]子项目的开发。\r\n\r\n2.2 如何解决文档客户文档的问题\r\n当前的wiki内容组织还需要花比较多的精力,因此这个任务需要大家的支持。要齐心协力才能建设一个内容充实,有自己特色的网站。所以每个成员都有义务为wiki网站出力。\r\n但是我们原则依然是“宁缺勿滥”,必须保证信息和资源都得到有效的利用。\r\n\r\n2.2 关于WebPM开发资源的管理\r\n网络项目最关键的问题是如何持续发展,WebPM 发展到今天已经初具成效。但是依然任重而道远。有很多热心的朋友希望能够为WebPM提供帮助,但是不得其门而入。而又有很多老朋友和成员因为资源的不足而无法为WebPM提供有效的贡献。因此,会议对项目成员的加入条件和管理章程作了一定的讨论,以期明确成员的义务和权利,明确项目小组的一些组织和交流的问题。\r\n具体的结论,请看[WebPM.成员章程]。\r\n\r\n\'\'\'3. 总结\'\'\'\r\n----\r\n我们已经取得了进步,WebPM的最初目标是正确的。我们也获得了一些热心朋友的帮助。我们必须充分使用所有可能的资源,抓紧时间,赶快行动。\r\n\r\nWebPM 口号:\'\'\'[big]做最好的中文自由软件开发平台![/big]\'\'\'\r\n\r\n\r\n\'\'\'4. 相关资源\'\'\'\r\n----\r\n[url=mailto:webpm-subscribe@topica.com]加入[/url]WebPM 邮件列表\r\n\r\n----\r\n分类: [WebPM] | [WebPM 小组会议]\r\n\r\n参考: [webpm_wiki] ','BrokenDoor','2002-03-04 15:44:32','2002-07-17 13:35:33',0,'172.16.1.215',199),('WebPM.成员章程','----WebPM - 成员章程 - v1.0\r\n----CopyLeft (l) 2001 Softme Studio\r\nBrokenDoor 2002年3月4日 15:48\r\n----\r\n\'\'\'1. 说明\'\'\'\r\n----\r\n网络项目最关键的问题是如何持续发展,WebPM 发展到今天已经初具成效。但是依然任重而道远。有很多热心的朋友希望能够为WebPM提供帮助,但是不得其门而入。同时又有很多老朋友和成员因为资源的不足而无法为WebPM提供有效的贡献。因此,本文对WebPM项目成员的加入条件和管理作了一定的约束,以明确成员的义务和权利,明确项目小组的一些组织和交流的问题。\r\n\r\n\'\'\'2. WebPM 宗旨\'\'\'\r\n----\r\nWebPM 的英文全称是 (Project Management On Web),是由浩然软件工作室(Softme Studio)发起的自由软件平台。其主要目标是为中文自由软件的开发者、使用者和推广者提供基于互联网的开放式管理平台环境。\r\n\r\nWebPM 的主要需求可以归纳到以下三个方面:\r\n1)\'\'\'信息管理\'\'\': 主要依赖wiki提供支持.\r\n2)\'\'\'实时交流\'\'\':[no]理想状态是要有一个网络的虚拟工作室,现在先从MeetingRoom和WhiteBoard开始。[/no]\r\n3)\'\'\'软件过程支持\'\'\': 主要依赖于工作流(workflow)进行支持。\r\n\r\nWebPM 口号:\'\'\'[big]做最好的中文自由软件开发平台![/big]\'\'\'\r\n\r\n\r\n\'\'\'3. WebPM 成员章程\'\'\'\r\n----\r\n对于WebPM成员的要求,我们原则依然是“宁缺勿滥”。WebPM 成员章程对WebPM成员提出一定的要求,其目标是能保证WebPM项目的正常进度和持续发展。 \r\n3.1 WebPM 成员必须支持WebPM宗旨,同心协力向WebPM的最终目标前进。加入WebPM项目的成员自动成为Softme Studio成员。\r\n\r\n3.2 WebPM 成员有义务保持与其他成员的联系,需要加入邮件列表并注册webpm wiki 用户,至少每周通报个人状态。如果连续一个月没有任何联系的成员将会被认定自动退出,重新加入必须遵循章程中有关成员加入的约定。\r\n\r\n3.3 WebPM 成员有义务参加WebPM项目小组会议,如有特殊情况不能参加,需要提前通知WebPM项目小组或者任何一个其他可以参加小组会议的成员。\r\n\r\n3.4 WebPM 成员接受任务后,必须提供必要的投入保证。有义务在发布计划会议中说明的准确的投入点折算。\r\n\r\n3.5 WebPM 成员有义务为工作室网站提供支持和服务,并且有义务向工作室提供真实的联系方法。\r\n\r\n\'\'\'4. 申请加入\'\'\'\r\n----\r\n申请加入WebPM成员必须支持WebPM宗旨并履行本章程中规定的义务。新申请的成员必须\'\'\'至少参加一次WebPM小组会议并承担和完成至少一项具体的任务\'\'\',才能够成为正式成员。\r\n\r\n\'\'\'5. 相关资源\'\'\'\r\n----\r\nWebPM 邮件列表: [url=mailto:webpm-subscribe@topica.com]加入[/url]\r\nWebPM 工作室网站: [url=http://www.softme.org]softme.org[/url]\r\n\r\n----\r\n分类: [WebPM]\r\n\r\n参考: [2002年2月27日 会议记录] ','BrokenDoor','2002-03-04 16:58:07','2002-03-04 16:58:07',0,'BrokenDoor',200),('JDO','[Java Data Objects (JDO)|http://forte.sun.com/services/quiz/jdo.html] is a forthcoming specification for providing transparent \r\npersistence — the ability to provide transparent mapping and persistence for \r\nJava objects via traditional data stores. \r\nJDO is being developed under the Sun Community Process. \r\n\r\nMore information about JDO can be found at:\r\n\r\n[JDO Public Access Web Site |http://access1.sun.com/jdo/]\r\n\r\n[Technical Articles |http://forte.sun.com/ffj/articles/index.html]\r\n\r\n[使用JDO的一个实例]\r\n----\r\n\'\'\'相关连接:\'\'\'\r\n\r\n[castor]/[使用说明|http://castor.exolab.org/jdo.html]/[下载|http://castor.exolab.org/download.html]\r\n\r\n[http://www.onjava.com/|http://www.onjava.com/] --上也有JDO/JDBC/SQLJ专栏\r\n\r\n[JDO的相关讨论|http://www.sys-con.com/java/articleprint.cfm?id=1302]\r\n\r\n[http://access1.sun.com/jdo/|http://access1.sun.com/jdo/]\r\n','takaka','2002-03-05 00:25:17','2002-03-06 17:04:59',0,'takaka',201),('linux 用户管理','参考:\r\n[http://www.linuxaid.com.cn/support/fomslist.jsp?i=43|http://www.linuxaid.com.cn/support/fomslist.jsp?i=43]\r\n','BrokenDoor','2002-03-05 11:08:39','2002-03-05 18:10:38',0,'浆糊',202),('什么是SVG',' \'\'\'什么是SVG? \'\'\'\r\n\r\n  SVG(Scalable Vector Graphic)是一个标准开放的矢量图像格式.它使你设计的网页可以更加精彩,更加细致.使用简单的文本命令,SVG甚至可以做出诸如色彩线性变化,自定义置入字体,透明,动态效果,虑镜效果等各式常见的图像效果. \r\n  SVG图像是基于XML(可扩展标识语言--未来的网络语言)的应用,并由W3C组织的SVG开发组负责详细的研究和开发.\r\n----\r\n分类:[webpm_net]|[SVG]\r\n','takaka','2002-03-05 21:20:14','2002-03-11 17:21:40',0,'takaka',203),('JWIKI ???????????','在这里编辑文dfsdafdsafsa','ymruan','2002-03-11 17:51:30','2002-03-11 17:51:30',0,'ymruan',210),('scaler','[user=scaler]','浆糊','2002-03-12 09:26:37','2002-03-12 12:51:50',0,'BrokenDoor',211),('为什么','why??','scaler','2002-03-12 09:30:26','2002-03-12 09:30:26',0,'scaler',212),('SVG与SWF的对比','  SVG(Scalable Vector Graphics,可增量矢量图形)是W3C组织最新制定的网络矢量图形标准,是作为XML的一个子集提出的。由于它系出名门,加之人们不满原先一统天下的网络矢量图形标准——SWF(Flash动画格式)的一些不足之处,因此它一问世便受到广泛关注,Sun, Adobe等公司都表示将全力支持SVG。业界人士纷纷把它视为取代SWF格式的希望之星,其追捧程度直逼年Flash有过之而无不及。 \r\n  那么,SVG真的有那么强大吗?下面就让我们来看一下SVG与SWF的对决吧。 \r\n   \'\'\'文件大小\'\'\' \r\n  对于网络矢量图形来说,最基本的要求就是在储存信息不变的情况下文件要尽可能小,否则在网络上进行传输就相当困难了。那么SVG和SWF哪个更小呢?我作了以下实验。 \r\n  我在Adobe Illustrator 9.0中作了一个由紫到橙,由椭圆到六角星的Blend,接着我又在该图中加入了一段文字,最后我向图中导入了一幅640×480的真彩BMP位图,并在每次操作后将图像分别存为SVG,SVGZ和SWF,其大小见表1,由于该图中有矢量图形,文字和位图,因此我相信能比较准确的反映这两种格式对储存同样的各类图形信息所需的空间比。     \r\n  从以上的结果中,我们可以看到在储存性能上,SWF储存同样的图形所用的空间比SVG要小得多,那么难道SVG就这么不堪一击吗?非也,前面我们已经说到SVG格式是一种文本格式,而所有的文本格式都由一个共同的特点,就是压缩比特别高。表1中的第二栏的SVGZ格式就是SVG的压缩格式,也可以由Illustrator 9.0生成。它是采用了Winzip的LZW压缩算法对SVG进行压缩后产生的文件格式(其实质就是一个zip文件,你甚至可以用Winzip把里面的SVG文件重新解压出来,不信你试试?)SVGZ格式也可以直接被浏览器浏览。从表1中可以发现SVGZ的大小就与SWF差不多了,大约只大5%-10%,由于网上发布时所用格式一般都是SVGZ,因此虽然SWF在文件大小上略胜一筹,但SVG/SVGZ还是具有相当的竞争力的。 \r\n   \'\'\'整合性和易学性 \'\'\'\r\n  以前Flash能够一统网络矢量图的天下,很重要的一点就是因为它可以用action很方便的与其它web元素交互,因而能够很好的与web页面整合。那么SVG又做得怎样呢?呵呵,其实对于SVG来说已经没有什么整合问题了,因为它本身就是web页的一部分,听起来有点金大侠的无剑胜有剑的感觉吧。因为SVG是XML的子集,所以它能够完全融入web页面中。你可以在SVG里使用所有的web页元素,甚至使用CSS, DHTML, VRML, DOM, XSL, JavaScript等各种W3C标准。由于这种无缝性,在未来当你需要在XML页面的某处加上一个图形时,你也许不再是链接一个JPG或GIF图片,而是直接在该处用SVG写出一个图形来!!这是多么令人期待的应用啊!因此在整合性方面我认为SWF完全不能同SVG匹敌。另外由于SVG是XML的子集,所以它与Html一样,也是一种标记语言,这样对于熟悉Html的人来说,学习SVG将会是件非常容易而令人愉快的事。 \r\n   \'\'\'可修改性\'\'\' \r\n  Flash一旦输出成SWF文件就无法修改了,除非你拥有原始的fla文件,虽然现在已经有一些工具可以从SWF中提取出各种元素,但仍不能进行完全的修改。这样虽然可以保护著作权,但对于重用和更新SWF就显得困难了。如果你觉得某个SWF中场景很好想借用,或者你想更改SWF里某一段,可是你没有原始fla,对不起,没有任何办法。可是SVG就不一样,它是文本格式,只要你用记事本打开它,里面所有的秘密你就可以看得一清二楚,就像阅读Html源码一样。你可以很容易的从中学习别人制作SVG的技巧,如果你想偷懒的话,也可以直接copy一段你想要的SVG源码放到你的作品中去(这样做之前不要忘了取得作者的同意哟),至于修改什么,更是不在话下,用记事本就行了,当然随着SVG的流行,会有更多更好用的修改SVG的软件出现的。不过由于SVG的这种特性,使得它和Html一样,源码很难保密,这点可能有些重视知识产权的人会感到不满的。 \r\n   \'\'\'公开性和支持度\'\'\' \r\n  SWF是半公开的文件格式,其标准的制定权在Macromedia公司。所以对SWF的第三方支持比较少,到目前只有swish, swift 3D等少数几个软件。而SVG是w3c制定的公开格式,任何公司都可以参与该SVG标准的制定,因此使得该标准更加科学和强大,同时参加制定标准的公司也都会很乐意支持SVG格式。任何公司也都可以采用该格式设计自己的SVG软件,因此就像现在的Html软件一样,未来也会有相当多的软件去支持SVG格式,有竞争才有发展,在激烈的竞争下,SVG软件的易用性一定会大大超过Flash。由于SVG的完全公开性,我相信它未来的发展潜力和支持度应该会大大超过SWF。 \r\n   \'\'\'画面质量\'\'\' \r\n  画面质量也是衡量网络矢量图形一个重要的因素,如果画质不好,即使技术再先进,支持度再高也不可能被推广。但从我对从Illustrator中分别输出的SWF和SVG文件的比较来看(SWF采用Flash Player 5.0浏览,SVG采用Adobe SVG Viewer 1.0浏览),两者的画质几乎一样好,完全无法区分优劣。所以在这一点上,双方打成平手。不过由于SVG是一种公开格式,因此未来将会有多个SVG浏览器出现,在各个不同的浏览器中,SVG的表现可能不会完全一致,就像VRML在不同浏览器中的表现不同一样。 \r\n  以上我们从5个方面比较了SWF和SVG的性能,从比较中可以发现SVG确实是一种相当先进,有前途的网络矢量图形格式,在各项指标上都不输给SWF,而且还具有自己独特的优势,因此在未来的一两年内,可能会有很大的发展。如果Macromedia不能很好面对它的挑战,改进Flash技术的话,SVG就完全有可能取代Flash成为网络图形新霸主。不过它目前的问题就是软件支持还比较少,使用的人还不多,但由于它的公开性,这种情况很快就会改善。所以像我一样喜爱Flash技术的朋友们,一定要多多留心SVG的发展,以免将来SVG大潮到来时被它所抛弃呀 \r\n\r\n\r\n \r\n','takaka','2002-03-05 21:22:20','2002-03-05 21:22:20',0,'takaka',204),('将 XML 转换成 SVG','来自[developerWorks 中国网站 |http://www-900.ibm.com/developerWorks/index.shtml]\r\n[中文原文|http://www-900.ibm.com/developerWorks/education/xml/transforming-xml/xmltosvg/index.shtml] / [英文原文|http://www-900.ibm.com/developerWorks/education/xml/transforming-xml/xmltosvg/index_eng.shtml]\r\n\r\nDoug Tidwell\r\n计算机传道士,developerWorks XML 小组\r\n发表:2000 年 1 月\r\n更新:2001 年 3 月\r\n\r\n\r\n教程的第一部分显示了如何将 XML 文档转换成 HTML。我们使用各种 XML 源文档(技术手册、电子表格数据、商务信函,等)并将它们转换成 HTML。沿此下去,演示了利用 XSLT 和 XPath 标准进行的各种操作。在这部分中,我们将使用“万维网联盟”新推出的“可伸缩向量图形(SVG)”将几种原始文档转换成图形。\r\n\r\n\'\'\'原始文档\'\'\'\r\n对于转换,我们将使用 6 种源文档中的 2 种:某些电子表格数据和莎士比亚十四行诗。原始组中的其它文档不容易转换成 SVG;我们将在以后讨论其原因。继续之前,让我们看一下这两篇文档以及想如何转换它们。\r\n\r\n\'\'\'销售图\'\'\'\r\n这里有一个销售图文档,用 SVG 格式表示的柱形图:\r\n[img]http://www-900.ibm.com/developerWorks/education/xml/transforming-xml/xmltosvg/columnchart.jpg[/img]\r\n\r\n这里看到的每件东西都是用 XSLT 样式表和原始 XML 文件创建的。如果更改 XML 源码中的图、标题和地区名称,则可以通过将样式表应用到更新的 XML 文档来重新生成柱形图。如果想查看生成该柱形图的 XML 源码,请参阅[附录 A|http://www-900.ibm.com/developerWorks/education/xml/transforming-xml/xmltosvg/appendixa.shtml] - 样本 XML 文档。\r\n\r\n\'\'\'莎士比亚十四行诗\'\'\'\r\n本文档是逐行表示的,在每行开始指出押韵格式。SVG 文件使用各种 SVG 元素(以后有更多元素)来重新创建原始 HTML 转换的外观和感觉。\r\n[img]http://www-900.ibm.com/developerWorks/education/xml/transforming-xml/xmltosvg/sonnet.jpg[/img]\r\n\r\n可以在[附录 A|http://www-900.ibm.com/developerWorks/education/xml/transforming-xml/xmltosvg/appendixa.shtml] - 样本 XML 文档中找到创建本文档的 XML 源码。\r\n\r\n\'\'\'饼图\'\'\'\r\n最后,我们将讨论将销售图文档转换成用 SVG 格式表示饼图的样式表。由于在 XSLT 和 XPath 中没有我们要使用的三角函数(历史悠久的正弦和余弦),这会使转换更困难。这意味着不得不编写扩展函数,向 XSLT 处理器添加一些新功能。\r\n\r\n我们的劳动成果如下:\r\n[img]http://www-900.ibm.com/developerWorks/education/xml/transforming-xml/xmltosvg/piechart.jpg[/img]\r\n\r\n\'\'\'可伸缩向量图形\'\'\'\r\n在构建样式表之前,让我们先讨论目标标记语言。这里将要使用的 SVG 规范是于 2000 年 11 月 2 日候选推荐的,可以在 W3C 网站上找到它。要查看该示例,将使用 Adobe SVG 浏览器插件,可以在 Adobe 站点上找到它。\r\n\r\nSVG 是一种描述 XML 中二维图形的语言。使用 SVG 元素描述文本、轨迹(直线和曲线集)和图像。一旦定义了那些图像,则可以使用各种感兴趣的方式对它们进行剪裁、转换和操纵。除此之外,可以通过指定事件处理程序来定义交互式和动态功能,并且可以使用“文档对象模型(DOM)”来修改文档的元素、属性和特性。最后,因为 SVG 使用直线、曲线、文本和其它图元来描述图形,所以可以将 SVG 图像按比例缩放到任何精度。\r\n\r\n这是前面柱形图的放大示例:\r\n[img]http://www-900.ibm.com/developerWorks/education/xml/transforming-xml/xmltosvg/enlargement2.jpg[/img]\r\n如您所见,缩放文档并不影响图像的质量。如果要将传统图形(GIF 或 JPEG 文件)放大到这样的尺寸,则图像将变得颗粒状并且难以辨认。SVG 的另一个好处是从一开始就可以容易地创建 SVG 文件。\r\n\r\n这里将讨论 SVG 的一些基本元素,但是不会过于深入。SVG 规范中充满了说明该语言能力的样本。 \r\n\r\n\'\'\' 元素\'\'\'\r\n要用 SVG 定义形状,使用 元素。path 包含一些命令,它们告诉 SVG 描绘器移动到特定点、绘制直线或绘制曲线到特定点,并且闭合和填充该轨迹。大多数 SVG 元素,包括 ,都具有一个使用 CSS 特性定义如何描绘该元素的可选 style 属性。\r\n\r\n这里有一个包含样本 元素的 SVG 文档: \r\n[code]\r\n \r\n\r\n[/code]\r\n\r\n','takaka','2002-03-05 21:41:10','2002-03-05 21:41:10',0,'takaka',205),('基于XML的可升级矢量图像(SVG)浅析','SVG是基于XML的专门为网络而设计的图像格式。本文给出了SVG的几个简单例子,并与其它矢量图形格式VML、PDF、SWF进行比较,展示了 SVG的优点和美好前景。\r\n一、什么是SVG \r\nSVG(Scable Vector Graphics,可升级矢量图像)是一种基于XML的开放的矢量图形描述语言。SVG图像是与XML1.0兼容的文档,SVG元素是指示如何绘制图像的一些指令,阅读器(Viewer)解释这些指令,把SVG图像在指定设备上显示出来。使用SVG可以在网页上显示出各种各样的高质量的矢量图形,支持很多您想象得出的功能:几何图形、动画、渐变色、滤镜效果等。最关键的是,它是完全用普通文本来描述的!也就是说,这是一种专门为网络而设计的基于文本的图像格式。\r\n\r\n1999年2月,SVG草案出台,经过不断地修改更新,最终形成了第一份实验性的实现规范。2001年7月,W3C正式发布了SVG图像格式建议书,这就是SVG1.0规范。目前,该规范是被提议的推荐标准,到8月底将成为W3C的正式推荐标准。W3C对SVG的解释是:SVG是一种使用XML来描述二维图像的语言。它允许3种形式的图像对象存在,分别是矢量图形、点阵图像和文本。各种图像对象能够组合、变换,并且能修改其样式,也能够定义成预处理对象。文本是XML名字空间中的有效字符,这些字符能被作为SVG图像的关键字而存留在搜索引擎中。SVG的功能包括嵌套变换、路径剪裁、透明度处理、滤镜效果以及其他扩展,同时,SVG支持动画和交互,也支持完整的XML的DOM接口。任何一种SVG图像元素都能使用脚本来处理类似于鼠标单击、双击以及键盘输入等事件。因为同Web标准兼容的缘故,SVG还能够在同一个Web页面里凭着继承自XML的名字空间等特性来完成一系列交互操作。\r\n\r\n二、SVG都有哪些优点\r\n\r\n基于XML标准\r\n  XML是公认的下一代网络标记语言,拥有无穷的生命力。SVG在最开始设计的时候就基于XML,这使得它具有一种先天的优势,并且同HTML、CSS、DOM、XSL、JavaScript、CGI一样,成为新的标准。 \r\n高质量的图像\r\n  由于基于矢量,使得SVG图像的质量得到大大的提高。放大、缩小以及各种特效都比位图的表现要好,在打印的时候,完全可以以印刷质量输出图片。SVG图像在客户端动态绘制,用户可以随意调整图像的一些参数而不会导致图像模糊。SVG图像的大小只与图形的复杂程度有关,而与图形的具体尺寸无关。 \r\n灵活易用的文件格式\r\n  SVG主要由3个部分组成:矢量图形、位图和文字。由于SVG文件是以文本的形式(XML)存放的,更改起来是非常方便的。也就是说,可以不用任何图像处理工具,仅仅用记事本就可以生成一个SVG图像!在页面运行的过程中,我们也可以对很多部分做修改。而其中的图形描述又可以被任何人重复的使用。 \r\n支持交互和动画\r\n  SVG支持SMIL(synchronized multimedia integration language),使得用户可以自由的同SVG中的元素完成一些交互的动作,从而完成既定的目标,这一点在目前单独依靠图片是完成不了的,需要由网页中的Script语句来实现。 \r\n支持字符查找\r\n  查找\"图片\"中的字符,在SVG中成为可能。而这在其它格式的图片文件中则是不可思议的?! \r\n支持Xlink 和Xpointer\r\n这意味着我们可以在SVG文档之间制作超链接,这使我们拥有一种能力,可以制作一个完全由SVG构成的WEB站点!这个站点可以包含图片、文本以及拥有与用户进行交互的能力。Andrew Watt就制作了世界上第一个这样的全SVG站点(http://www.svgspider.com) .当然你首先得要安装一个SVG的阅读器,推荐使用Adobe公司的Adobe SVG Viewer 2.0 ,但它只能用在MS Windows和MacOS上。使用一个合适的Java虚拟,Apache的Batik viewer可以运行在任何平台上。\r\n看到这么多优点,是不是觉得不可思议?好,下面我们从几个小例子着手,揭开SVG的神秘面纱。\r\n\r\n三、SVG的几个简单例子 \r\n任何人可以利用一个记事本来创建和编辑SVG图像,但有时这样做会很复杂。现在有越来越多的工具开始支持SVG编码,可以减轻我们的工作。比如:从Adobe Illustrator 9.0和CorelDraw9开始就可以制作极度复杂的SVG图形。虽然SVG的语法和格式仍是XML规范的一部分,但SVG有其自己的一些基本概念、SVG的渲染模型、SVG数据类型与坐标系设置等,详细内容请参照参考资料。\r\n\r\n一个最简单的例子:[code] \r\n\r\n\r\n\r\n\r\nHello World!\r\n\r\n\r\n\r\n[/code] \r\n\r\n\r\n例1 一个SVG的基本图形例子\r\n\r\nSVG文档(通常以后缀.svg存放)总是以根元素开始。和标记内是SVG的图像描述语句。我们可以定义一个视口坐标系和用户坐标系,缺省的情况下两者是一致的,度量单位也相同,如果属性值没有带单位,则使用用户坐标系的长度单位-像素(px)。大多数情况下,用户坐标系的原点处在视口的左上角,X轴的正向朝右,Y轴的正向朝下,即如果不进行坐标变换,一切渲染都是以初始坐标系为准。例1中的SVG首先画了一个矩形,然后写了一段文字,接着利用路径元素画了一个三角形,最后显示效果如图1所示: \r\n\r\n\r\n\r\n图1 在浏览器中显示例1的结果\r\n\r\nSVG提供了一种通用的路径式元素(path),可以用来创建庞大复杂的图像对象,像电子设计、流程图、统计绘画等领域有大量固定的符号,SVG不可能全部囊括。SVG规范允许用户定义自己的符号,可以将自定义的符号创建、重用、发布而不需要其他额外的手段,更不需要一个什么委员会来批准注册,这种自由灵活的风格更加扩展了SVG的功能。\r\n\r\nSVG提供的另一个很重要的功能是超级链接。在HTML网页中,图像和链接是分离的,图像作为外部文件而存在,链接则在HTML中说明,这样虽然有灵活和可重用的优点,却不易管理。而Flash的SWF矢量格式则相反,图像中内嵌链接,两者成为一个整体,虽然方便,但却不能重用。SVG则综合了两者的优点,其超级链接以明文的形式内嵌于文档内部,在形式上是一个整体,而且也有利于修改。由于SVG是基于XML的,象\"xlink\" 和 \"xpointer\"等都是XML特有的,所以SVG就自然而然获得了XML所定义的链接的好处和功能。\r\n\r\n把例1稍做修改,对那个黑三角加上一个超级链接,如例2所示: \r\n......\r\n\r\n\r\n\r\n......\r\n\r\n \r\n\r\n\r\n例2 超级链接的例子\r\n\r\n当鼠标指针移到黑三角上时就变成了手的形状,状态栏上也显示了此链接所指向的URL。例2只是一种常见的情况,实际上SVG中超级链接标志符的定义格式有3种: \r\n\r\n通过SVG元素的\"id\"属性对元素进行链接与标识。如somfile.svg#someplace。 \r\n使用与XML兼容的\"xpointer\"。如somefile.svg#xpointer(id(\"someplace\"))。 \r\n使用SVG的\"viewBox\"说明。\r\n\r\nSVG作为一种适用于网络的图像格式,不仅仅在于它的体积小、易修改、可缩放等与普通矢量图形一样的优点,还在于它添加有针对网络的交互功能。SVG图像可以内嵌交互定义。单独的一个SVG文件和一个客户端的SVG解释器便可以完成网页中链接、动画、交互等大部分功能。与Flash的SWF格式基于\"帧\"的二进制数据流不同,SVG是完全基于ASCII字符的文本。例3是一个交互的例子。 \r\n[code] \r\n\r\n\r\n\r\n\r\n \r\n\r\n[/code] \r\n \r\n\r\n\r\n例3 SVG利用