??xml version="1.0" encoding="utf-8" standalone="yes"?>国产亚洲人成在线影院,亚洲午夜在线播放,亚洲特级aaaaaa毛片http://m.tkk7.com/zlsunnan/category/5660.html世界L反反覆覆错错落落地飘?来不及叹?生活不是q_^淡E从从容容的东?不能攑ּzh-cnTue, 27 Feb 2007 12:09:06 GMTTue, 27 Feb 2007 12:09:06 GMT60成ؓ一个好的系l分析员http://m.tkk7.com/zlsunnan/archive/2006/08/28/66158.html☆蓝色梦想☆☆蓝色梦想☆Mon, 28 Aug 2006 05:41:00 GMThttp://m.tkk7.com/zlsunnan/archive/2006/08/28/66158.htmlhttp://m.tkk7.com/zlsunnan/comments/66158.htmlhttp://m.tkk7.com/zlsunnan/archive/2006/08/28/66158.html#Feedback0http://m.tkk7.com/zlsunnan/comments/commentRss/66158.htmlhttp://m.tkk7.com/zlsunnan/services/trackbacks/66158.html 如何成ؓ一个好的系l分析员
truelyg的设计定义:设计的过E就是将事务处理抽象成计机模型的过E?
1. 首先要明白设计远比编E重要?
2. qx注重训练自己的思维严}性和从全局考虑问题的能力。徏立冷静思考问题的处事态度?
3. 设计Ӟ其是数据库设计Ӟ不要完全被规矩约束,设计好比作诗Q懂得韵律是对的Q但完全被韵 律所束缚Q就作不出好诗了?
4. 多做设计Q经常ȝ自己的不之处和成功之处Q向他hh?
5. 专门L别h设计的漏z和不Q也是提高自p计水q的重要手段?
Q记住:q个好方法不要顺便外传,自己知道p了,d-:Q?
6. l验是重要的Q但如果观念老化而不善于ȝ提高Q所谓的l验成为束~自p步的枷锁?
7. 学好数学特别是理论数学如数学分析、运{学、数学模型等。多玩策略性经营游戏也是有益的。推?《帝国时代》和《模拟首?000》以及《大富翁4》。(但不要沉陷在里面Q?
8. Ҏ目情况和开发^台工L特点定最佳的设计Ҏ。模块化设计Ҏ和面向对象设计。两U设 计方法的l合使用?
9. 复杂无序的q程用模块化的方法进行分解,但要注重事务间的联系Qƈ且用开攄眼光去设计?
10. 设计时对严}性、灵zL、开发效率、客戯求四个方面做衡量取舍?
11. 设计时还要根据整个工E的q度安排和客户对软g的要求而决定是否设计得_灉|和严谨?
12. 复杂而无条理是最p的设计Q简单实用ƈ不一定是最好的Q但一定不是最坏的。(不要说我h哟)
13. 训练自己良好的表达能力,能用清晰明确而且单的描述表达q基本思\?
14. 在一个项目中建立l一的系l分析模式和文档模板Q同Ӟ一个项目中必须臛_有一个hҎ个系l?设计q行查和q行全局的考虑?
再谈如何成ؓ一个好的系l分析员Q?

bylsfboy

pȝ分析员基本功Q?

好的pȝ分析员都是从优秀的程序员中生的Q坚实的~程功底、丰富的l验是今后做pȝ分析的基?
没有对系l本w进行过透彻剖析q,很难领会到其中一些难以言q的_֍。但q不{于好的E序员就能够 成ؓ好的pȝ分析员?

合理的知识结构。语a能力、文字表达能力、技术的全面性等是对pȝ分析员的基本要求。比如说c/s? 层开发,如果仅仅对netscape公司的品熟悉还不够Q还需要了解比如微软等产品Qƈ且要了解他们中 生历?发展思\Q技术优劣,以应付各U穷q猛打的提问。但更重要的是,q是你ؓ应用定制技术要?的前提?

pȝ分析员思想Q?

全局观念是系l分析员必须具备的观c如果系l分析员设计时太注重l节Q往往会陷入在某个问题上纠 ~不清的泥潭。(93q_我论文指D师的一席话影响了我随后几年对Y件开发的理解----今后计算Z 来快Q多写几行代码少写代码无关紧要,最重要的是整体Q一开始就错了Q某个部份编得再好,也是 没有用的Q?

d隑ֺ的预能?

pȝ分析员要具备快速的d隑ֺ预测能力以及具备快速确定开发小lh员构成和d划分的能力。(?这条归为思想Q而不是能力)昆虫自然会长出翅膀Q而思想却需要长期的润。要做到q点Q需要大?的思考、学习。设计远比编E重要。当今Y件业的发展,各种开发工L出现Q编E已l不是什么问题, E序员的工作某种E度上讲是将别h现成的东西拼凑堆砌v来。系l分析员要清楚的认识刎ͼ现在大多?E序员没有学会怎么L体的了解一个系l,有些甚至不了解编E(q不是说他们不会写代码)。可视化 的开发工具加五花八门的控ӞE序员可以偷Ҏ了。(q可不是夸大Q我好几q的理工作Q接触过?量的E序员)Z技术,跛_框架。基于现有技术结合用户需求思考问题,设计时蟩出框架?

pȝ分析员思想Q?

pȝ分析员要有面向用L思想。系l分析员应当有能力将自己扮演成用P来了解要交付的项目看h 想什么样式,感觉想什么,从而了解用Lxq挑选出合理部䆾d发。从q个意义上说Q系l分析员 才能获得有意义的见解dg的开发组成员。系l分析员头脑中要寚w目结局有一个清楚的认识Qƈ?证项目不偏离方向。系l分析员要有Ҏ于技术,高于技术思考问题的思想。纯_的E序员通常Ҏl结 果考虑的不是很多,当一U新的技术在市场上出现时Q他们对能否按时交付的考虑比较少Q而强烈希?他们的计划能够徏立在新的技术之上。因此,pȝ分析员的x和行动要象一个用P又要能够站在技?的高度,成ؓ真正的用戗程序员之间的代a人?

pȝ分析员的关键

获得信Q。系l分析员最重要的素质是获得信QQ这是成ZUpȝ分析员的关键。成熟最为关键。成?可以为整个项目组提供正确的支?能够理解技术怎样才能解决用户的需求?

pȝ分析员的准备工作

l一的各U文档模式,q其中包括今后Y件变量、字D命名规则。我推荐用pb制定的规则做基础Q通过?造成为适合自n实用的标准。统一的文档管理。统一的分析Y件。比如说roseQuml太规范,国内的Y?理水^Ҏ用不上,只不q尽量应用,你自己对pȝ分析的理解有好处Q?Ҏ是思想的放映,在具体方法上׃多说了。我托h从u$a弄到几本书,用于面向对象pȝ开发的?用》、《面向对象的分析》、《项目管理》等都是很不错的Q推荐大家看看?

我在拙作"在中国没有h懂计机"里发了点牢骚Q听说挨了部份hQ习惯性的Q骂。其实,bbs本来是 发泄的地方,在这里从来就|有有内容的文章?

自从"l纳?登陆深圳后,大家更着g从宏观看中国的it业了。中国itq棵树Q说实在的,长到今天 实在是不Ҏ。一些h提出?反对微Y霸权"的口P不少人呼唤中?谷"的出现。微软的成功不是技 术的成功Q更多的是商业运作的成功。中国itq棵树能长多高,取决于他所植根于的土壤。而现在的事实是,q片土壤实在是太贫瘠了!如果按我们现在的思\和搞法,是长不成大树Q更别指望能l出"??Q?谷"q样丰硕的果实。如果说Q我们的软g技术落后美国十q_我们的硬件制造技术则落后国 二十q_我们的管理水q后美国至三十年。而最l决定发展速率的恰恰是我们的死I──低劣的管?水^。低劣的理水^的Ş成的原因有着深厚的背景和多方面的原因?

pȝ分析工作是解决一个问题的工作,目标是将一个对计算机应用系l的需求{化成实际的物理实?其中 复杂复杂在实际的面太多.在系l分析过E之中注意问以下的问?可能会所q行的系l分析设计工作有 帮助.

1)您所完成的系l目的是什?注意不是功能要求,而是目的.也就是ؓ什么要、ؓ什么要C?

2Q您所完成的系l有哪些斚w参与Q各斚w的初h什么?那些人可能在pȝ中v重要作用Q他?会采取什么样的态度Q你对他们有多少影响力?

3Q您的系l是否有一个明的评h标准Q最好从参与的各斚w都进行考虑?

4Q你的系l设计思想是什么?是否能够得到各方面的认可?

5Q你对参与系l设计开发的人员了解吗?他们的特长在哪里Q是否愿意与你合作,Z么?你对他们?_的媄响力吗?

6Q你的系l开发计划是否完善?你的计划表有明确的阶D吗QQ何一阶段都应该怎样完成Q如何对q一 阶段完成的情况进行评P

7Q你Ҏ采用的系l开发方法以及工h否熟悉?你的夥伴是否熟悉Q?

8Q你所完成的系l是否有原型Q计机的或者物理的?

以上的几个问题都是在pȝ分析以及pȝ规划时涉及到的,供各位参考?

pȝ分析工作是解决一个问题的工作,目标是将一个对计算机应用系l的需求{化成实际的物理实?其中 复杂复杂在实际的面太多.在系l分析过E之中注意问以下的问?可能会所q行的系l分析设计工作有帮助

1)您所完成的系l目的是什?注意不是功能要求,而是目的.也就是ؓ什么要、ؓ什么要C。在考虑pȝ目的Ӟ我更多的侧重于系l的最l目标考虑Q因Z个系l不可能一下子完美Qؓpȝ留些 余地?

2Q您所完成的系l有哪些斚w参与Q各斚w的初h什么?那些人可能在pȝ中v重要作用Q他?会采取什么样的态度Q你对他们有多少影响力?中国it行业的失败之一是?太年?Q一定要有领导的 支持Q否则完蛋。不要认己对他们会有多少影响力,即便有,也要可能的认ؓ是决{者再影响?们。在中国Q一个技术员Q你老几Q说到这里我很悲哀。哪些h在系l中起重要作用ƈ弄清楚他们的?度,q点十分关键?

3Q您的系l是否有一个明的评h标准Q最好从参与的各斚w都进行考虑。不知道q样说对不对Q在p?l徏设之前,对你的程序员、对你的领导要有臛_不同的两U评仗?

4Q你的系l设计思想是什么?是否能够得到各方面的认可。如果高明,寚w对{对E序员都采用引导Q?得到认可的最好办法,是让他们认可他们自qx。(我力图这样做Q但做得不好Q系l分析员有一 点要学会韬光LQ忍Q?

5Q你对参与系l设计开发的人员了解吗?他们的特长在哪里Q是否愿意与你合作,Z么?你对他们?_的媄响力吗?软g发展C定的E度Q不是编E,不是数学Q而是理?

6Q你的系l开发计划是否完善?你的计划表有明确的阶D吗QQ何一阶段都应该怎样完成Q如何对q一 阶段完成的情况进行评P

7Q你Ҏ采用的系l开发方法以及工h否熟悉?你的夥伴是否熟悉Q事实上Q不是每U好的工具都?使用Q也q不一定都要他们熟l掌握。提醒诸位一句,当你方案做得可以不依赖某个E序员,你在E序 员面前就无信daQ因Z此程序员受到更大的生存压力。我坚决不在公司使用rose?

8Q你所完成的系l是否有原型Q计机的或者物理的?

以上的几个问题都是在pȝ分析以及pȝ规划时涉及到的,供各位参考?

q文章很好,我的话是Q?需求分析实际应该是问题分析"。含义是pȝ要解决的是问题。而不是用h?的需求。经常发现系l完成后Q客戯"我的问题q没有解?。可是,需求分析稿上的目标都搞定了?

既然是问题分析,所以,熟悉目标pȝ的知识就是必要的。甚臻I可以_一个好的系l分析员也应该是 好的业务专家?

我很高兴在这里遇到许多分析高手,可以交流分析中的问题。我赞同从来的观炏V在中国作分析重要的?人气Q因Z国的企业U信息系l的在很大程度上可以说ƈ非确有需求,而是q于某种压力。用户在 很多时候考虑的不是系l的长远发展Q而只是短期的成果Q要求开发单位在很短的时间内完成一个很大的 pȝ的开发,没有旉对系l进行周密的分析Q在q种情况下,很多开发商׃_分析,_设计,快q?入编码阶D,q样的系l的生命周期肯定不会很长。说了这么多Q只是想_pȝ分析员确实应是业务和 理专家Qƈ且需要有很好的语al织能力Q他需要根据问题域中存在的问题d力说服用P引导用户 需求,毕竟Q我们是专家Q如果让用户늝d赎ͼpȝ不会是成功的pȝ。(当然了,q要建立在用?是可引导的前提下Q本人拙见?

在理解和分析用户的需求时Q应说服用户明白Q徏立计机应用pȝq不是简单地用计机代替手工?
作,它更应该是管理思想的一ơ革命,是现用户模式的一ơ升华和提高。如果系l不能高于现实,开发的pȝ长期陷入需求的反复修改Q其软g的生命周期也短了?

针对我对您的问题的理?试着作如下一般?理论性的回复:

需求分?您可以采用usecasedriven的方法进行需求分?在明需求分析的基础?定需要采用的pȝ分析Ҏ(l构?面向对象/构g?应用您的开发团队所定采用的分?设计Ҏ,q行pȝ分析.Ҏ您所采用的分析方?依次或反复进行系l设?建模.



☆蓝色梦想☆ 2006-08-28 13:41 发表评论
]]>
写出高质量Y?/title><link>http://m.tkk7.com/zlsunnan/archive/2006/08/18/64259.html</link><dc:creator>☆蓝色梦想☆</dc:creator><author>☆蓝色梦想☆</author><pubDate>Fri, 18 Aug 2006 01:27:00 GMT</pubDate><guid>http://m.tkk7.com/zlsunnan/archive/2006/08/18/64259.html</guid><wfw:comment>http://m.tkk7.com/zlsunnan/comments/64259.html</wfw:comment><comments>http://m.tkk7.com/zlsunnan/archive/2006/08/18/64259.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/zlsunnan/comments/commentRss/64259.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/zlsunnan/services/trackbacks/64259.html</trackback:ping><description><![CDATA[1. 你们的项目组使用源代码管理工具了么?<br /><br />  MVMQ应该用。VSS、CVS、PVCS、ClearCase、CCC/Harvest、FireFly都可以。我的选择是VSS?br /><br />  2. 你们的项目组使用~陷理pȝ了么Q?br /><br />  MVMQ应该用。ClearQuest太复杂,我的推荐是BugZilla?br /><br />  3. 你们的测试组q在用Word写测试用例么Q?br /><br />  MVMQ不要用Word写测试用例(Test CaseQ。应该用一个专门的pȝQ可以是Test ManagerQ也可以是自己开发一个ASP.NET的小|站。主要目的是Track和Browse?br /><br />  4. 你们的项目组有没有徏立一个门L站?<br /><br />  MVMQ要有一个门L站,用来放Contact Info、Baselined Schedule、News{等。推荐Sharepoint Portal Server 2003来实玎ͼ15分钟搞定。买不vSPS 2003可以用WSS (Windows Sharepoint Service)?br /><br />  5. 你们的项目组用了你能买到最好的工具么?<br /><br />  MVMQ应该用量好的工具来工作。比如,应该用VS.NET而不是Notepad来写C#。用Notepad写程序多半只是一U炫耀。但也要考虑到经费,所以说是“你能买到最好的”?br /><br />  6. 你们的程序员工作在安静的环境里么Q?br /><br />  MVMQ需要安静环境。这Ҏ端重要,而且要保证每个h的空间大于一定面U?br /><br />  7. 你们的员工每个h都有一部电话么Q?br /><br />  MVMQ需要每Z部电话。而且电话最好是带留a功能的。当Ӟ上这么一套带留言电话pȝ开销不小。不q至每Z部电话要有,千万别搞得经常有人站h喊:“某某某电话”。《h件》里面就强烈谴责q种做法?br /><br />  8. 你们每个人都知道Z问题应该找谁么?<br /><br />  MVMQ应该知道。Q何一个Feature臛_都应该有一个OwnerQ当ӞOwner可以l箋Dispatchl其他h?br /><br />  9. 你遇到过有h说“我以ؓ…”么Q?br /><br />  MVMQ要消灭“我以ؓ”。Never assume anything?br /><br />  10. 你们的项目组中所有的人都坐在一起么Q?br /><br />  MVMQ需要。我反对Virtual TeamQ也反对Dev在美国、Test在中国这U开发方式。能坐在一起就最好坐在一P好处多得不得了?br /><br />  11. 你们的进度表是否反映最新开发进展情况? <br /><br />  MVMQ应该反映。但是,应该用Baseline的方法来理q度表:l护一份稳定的ScheduleQ再l护一份最新更攏VBaseline的方法也应该用于其它的Spec。Baseline是变更管理里面的一个重要手Dc?br /><br />  12. 你们的工作量是先由每个h自己估算的么Q?br /><br />  MVMQ应该让每个׃。要从下而上估算工作量,而不是从上往下分z。除非有其他原因Q比如政MQ务工期固定等?br /><br />  13. 你们的开发h员从目一开始就加班么?<br /><br />  MVMQ不要这栗不要一开始就搞疲x。从目一开始就加班Q只能说明项目进度不合理。当Ӟ一些对日Y件外包必d天加班,那属于剥削的范畴?br /><br />  14. 你们的项目计划中Buffer Time是加在每个小d后面的么Q?br /><br />  MVMQ不要。Buffer Time加在每个Q务后面,很容易轻易的p消耗掉。Buffer Time要整D늚加在一个Milestone或者checkpoint前面?br /><br />  15. 值得再多׃些时_?5%做到100%?br /><br />  MVMQ值得Q非常值得。尤其当目后期人困马乏的时候,要坚持。这会给产品带来质的区别?br /><br />16. 登记新缺hQ是否写清了重现步骤Q?br /><br />  MVMQ要。这属于Dev和Test之间的沟通手Dc面寚w沟通需要,详细填写Repro Steps也需要?br /><br />  17. 写新代码前会把已知缺陯决么Q?br /><br />  MVMQ要。每个h的缺陷不能超q?0个或15个,否则必须先解册的bug才能l箋写新代码?br /><br />  18. 你们对缺L轻重~急有事先的约定么Q?br /><br />  MVMQ必L定义。Severity要分1??Q约定好Q蓝屏和Data LostSev 1QFunction ErrorSev 2Q界面上的算Sev 3。但q种U定可以Ҏ产品质量现状适当q行调整?br /><br />  19. 你们Ҏ见不一的缺h三国会议么?<br /><br />  MVMQ必要有。要有一个明的决策q程。这cM于CCB (Change Control Board)的概c?br /><br />  20. 所有的~陷都是q记的人最后关闭的么?<br /><br />  MVMQBug应该由Opener关闭。Dev不能U自关闭Bug?br /><br />  21. 你们的程序员厌恶修改老的代码么?<br /><br />  MVMQ厌恶是正常的。解x法是l织Code ReviewQ单独留出时间来。XP也是一个方法?br /><br />  22. 你们目l有Team Morale Activity么?<br /><br />  MVMQ每个月都要搞一ơ,吃饭、唱歌、Outing、打球、开卡丁车等{,一定要有。不要剩q些钱?br /><br />  23. 你们目l有自己的Logo么?<br /><br />  MVMQ要有自qLogo。至应该有自己的Codename?br /><br />  24. 你们的员工有印有公司Logo的T-Shirt么?<br /><br />  MVMQ要有。能增强归属感。当ӞT-Shirt要做的好看一些,最好用80支的来做。别没穿几次q破烂烂的?br /><br />  25. ȝ理至每月参加次目l会?br /><br />  MVMQ要的。要让team member觉得高层xq个目?br /><br />  26. 你们是给每个Dev开一个分支么Q?br /><br />  MVMQ反寏VBranch的管理以及Merge的工作量太大Q而且Ҏ出错?br /><br />  27. 有h长期不Check-In代码么?<br /><br />  MVMQ不可以。对大部分项目来_最多两三天应该Check-In?br /><br />  28. 在Check-In代码旉填写注释了么Q?br /><br />  MVMQ要写的Q至一两句话,比如“解决了Bug No.225”。如果往高处拔,q也做“配|审计”的一部分?br /><br />  29. 有没有设定每天Check-In的最后期限?<br /><br />  MVMQ要的,要明Check-In Deadline。否则会Build Break?br /><br />  30. 你们能把所有源码一下子~译成安装文件吗Q?br /><br />  MVMQ要的。这是每日编译(Daily BuildQ的基础。而且必须要能够做成自动的?br /><br />31. 你们的项目组做每日编译么Q?br /><br />  MVMQ当然要做。有三样东西是Y仉?产品开发必备的Q?. bug management; 2. source control; 3. daily build?br /><br />  32. 你们公司有没有积累一个项目风险列表?<br /><br />  MVMQ要。Risk Inventory。否则,下个目开始的时候,又只能拍脑袋分析Risk了?br /><br />  33. 设计简单越?br /><br />  MVMQ越单越好。设计时候多一句话Q将来可能就带来无穷无尽的烦恹{应该从一开始就勇敢的砍。这叫scope management?br /><br />  34. 量利用现有的品、技术、代?br /><br />  MVMQ千万别什么东襉K自己Coding。BizTalk和Sharepoint是最好的例子Q有q两个作为基Q可以把L提高很多。或者可以尽量多用现成的Control之类的。或者尽量用XMLQ而不是自己去Parse一个文本文Ӟ量用RegExpQ而不是自׃头操作字W串Q等{等{。这是“Y件复用”的体现?br /><br />  35. 你们会隔一D|间就停下来夯实代码么Q?br /><br />  MVMQ要。最好一个月左右一ơ。传adq初Windowsl在Stevb的命令下停过一个月增强安全。BtwQ“夯”这个字念“hang”,W一声?br /><br />  36. 你们的项目组每个人都写Daily Report么?<br /><br />  MVMQ要写。五分钟够了,?0句话左右Q告诉自己小l的Z天我q了什么。一则ؓ了沟通,二则鞭策自己Q要是游手好闲一天,自己都会不好意思写的)?br /><br />  37. 你们的项目经理会发出Weekly Report么?<br /><br />  MVMQ要。也是ؓ了沟通。内容包括目前进度,可能的风险,质量状况Q各U工作的q展{?br /><br />  38. 你们目l是否至每周全体开会一ơ?<br /><br />  MVMQ要。一定要开会。程序员讨厌开会,但每个礼拜开会时间加h臛_应该?时。包括team meeting, spec review meeting, bug triage meeting。千万别大家闷头写code?br /><br />  39. 你们目l的会议、讨论都有记录么Q?br /><br />  MVMQ会前发meeting request和agendaQ会中有责主持和记录Q会后有责发meeting minutesQ这都是effective meeting的要炏V而且Q每个会议都要Ş成agreements和action items?br /><br />  40. 其他部门知道你们目l在q什么么Q?br /><br />  MVMQ要发一些Newsflashl整个大l织。Show your team’s value。否则,当你坐在甉|里面Q其他部门的人问Q“你们在q嘛”,你回{“ABC目”的时候,别h全然不知Q那U感觉不太好?br /><br />  41. 通过Emailq行所有正式沟?br /><br />  MVMQEmail的好处是免得抵赖。但也要避免矫枉q正Q最好的Ҏ是先用电话和当面_然后Email来确认?br /><br />  42. 为项目组建立多个Mailing Group<br /><br />  MVMQ如果在AD+Exchange里面Q就建Distribution List。比如,我会建ABC Project Core TeamQABC Project Dev TeamQABC Project All TestersQABC Project Extended Team{等。这样发起Email来方便,而且能让该收到email的h都收到、不该收C被骚扰?br /><br />  43. 每个人都知道哪里可以扑ֈ全部的文档么Q?br /><br />  MVMQ应该每个h都知道。这叫做知识理QKnowledge ManagementQ。最方便的就是把文档攑֜一个集中的File ShareQ更好的Ҏ是用Sharepoint?br /><br />  44. 你做军_、做变化Ӟ告诉大家原因了么Q?br /><br />  MVMQ要告诉大家原因。Empower team member的手D之一是提供够的informationQ这是MSF一开的几个原则之一。的如此,tell me why是h之常情,tell me why了才能有understanding。中国h做事喜欢搞限Ӟ限制信息Q似乎能够看到某一份文件的人就是有w䆾的h。大错特错。权威、权力,不在于是不是能access information/dataQ而在于是不是掌握资源?br /><br />  45. Stay agile and expect change<br /><br />  MVMQ要q样。需求一定会变的Q已l写好的代码一定会被要求修改的。做好心理准备,对change不要抗拒Q而是expect change?br /><br /> 46. 你们有没有专职的软g试人员Q?br /><br />  MVMQ要有专职测试。如果h手不够,可以peer testQ交换了试。千万别自己试自己的?br /><br />  47. 你们的测试有一份ȝ计划来规定做什么和怎么做么Q?br /><br />  MVMQ这是Test Plan。要不要做性能试Q要不要做Usability试Q什么时候开始测试性能Q测试通过的标准是什么?用什么手D,自动的还是手动的Q这些问题需要用Test Plan来回{?br /><br />  48. 你是先写Test Case然后再测试的么?<br /><br />  MVMQ应该如此。应该先设计再编E、先test case再测试。当Ӟ事情是灵zȝ。我有时候在做第一遍测试的同时补上test case。至于先test case再开发,我不喜欢Q因Z习惯Q太ȝQ至于别人推荐,那试试看也无妨?br /><br />  49. 你是否会为各U输入组合创建测试用例?<br /><br />  MVMQ不要,不要搞边界条件组合。当心组合爆炸。有很多test case工具能够自动生成各种边界条g的组??但要x楚,你是否有旉去运行那么多test case?br /><br />  50. 你们的程序员能看到测试用例么Q?br /><br />  MVMQ要。让Dev看到Test Case吧。我们都是ؓ了同一个目的走Ch的:提高质量?br /><br />  51. 你们是否随便抓一些h来做易用性测试?<br /><br />  MVMQ要q么做。自q自己写的E序界面Q怎么看都是顺眼的。这叫做审美疲劳??臭的看久了也׃臭了Q不方便的永久了也就习惯了?br /><br />  52. 你对自动试的期望正么Q?br /><br />  MVMQ别期望太高。依我看Q除了性能试以外Q还是暂时先忘掉“自动测试”吧Q忘掉WinRunner和LoadRunner吧。对于国内的软g试的现状来_只能“矫枉必过正”了?br /><br />  53. 你们的性能试是等所有功能都开发完才做的么Q?br /><br />  MVMQ不能这栗性能试不能被归到所谓的“系l测试”阶Dc早早ҎQ早L升天?br /><br />  54. 你注意到试中的杀虫剂效应了么Q?br /><br />  MVMQ虫子有抗药性,Bug也有。发现的新Bug来少是正常的。这时候,最好大家交换一下测试的areaQ或者用用看其他工具和手法,又会发C些新bug了?br /><br />  55. 你们目l中有h能说Z品的当前整体质量情况么?<br /><br />  MVMQ要有。当老板问vq个产品目前质量如何QTest Lead/Manager应该负责回答?br /><br />  56. 你们有单元测试么Q?br /><br />  MVMQ单元测试要有的。不q没有单元测试也不是不可以,我做q没有单元测试的目Q也做成功了??可能是oq,可能是大安是熟手的关系。还是那句话QY件工E是非常实践、非常工E、非常灵zȝ一套方法,某些Ҏ在某些情况下会比另一些方法好Q反之亦然?br /><br />  57. 你们的程序员是写完代码就扔过墙的么?<br /><br />  MVMQ大忌。写好一块程序以后,即便不做单元试Q也应该自己先跑一跑。虽然有了专门的试人员Q做开发的Z不可以一Ҏ试都不做。微软还有Test Release Document的说法,E序太烂的话Q测试有权踢回去?br /><br />  58. 你们的程序中所有的函数都有输入查么Q?br /><br />  MVMQ不要。虽然说做输入检查是write secure code的要点,但不要做太多的输入检查,有些内部函数之间的参C递就不必查输入了Q省点功夫。同L道理Q未必要l所有的函数都写注释。写一部分主要的就够了?br /><br />  59. 产品有统一的错误处理机制和报错界面么?<br /><br />  MVMQ要有。最好能有统一的error messageQ然后每个error message都带一个error number。这P用户可以自己Ҏerror number到user manual里面ȝ看错误的具体描述和可能原因,像SQL Server的错误那栗同PASP.NET也要有统一的Exception处理。可以参考有关的Application Block?br /><br />  60. 你们有统一的代码书写规范么Q?br /><br />  MVMQ要有。Code Convention很多Q搞一份来发给大家可以了。当Ӟ要是有FxCopq种工具来检查代码就更好了?br /><br />61. 你们的每个h都了解项目的商业意义么?<br /><br />  MVMQ要。这是Vision的意思。别把项目只当成工作。有时候要想着自己是在Z国某某行业的信息化作先驱者,或者时不时的告诉team memberQ这个项目能够ؓ某某某国安门每q节省多多百万的U税人的钱,q样有动力了。^凡的事情也是可以有个崇高的目标的?br /><br />  62. 产品各部分的界面和操作习惯一致么Q?br /><br />  MVMQ要q样。要让用戯得整个程序好像是一个h写出来的那样?br /><br />  63. 有可以作为宣传亮点的Cool Feature么?<br /><br />  MVMQ要。这是增强团队凝聚力、信心的。而且Q“一俊遮百丑”,有亮点就可以掩盖一些问题。这P对于客户来说Q会感觉产品从质量角度来说还是acceptable的。或者说Qcool feature或者说亮点可以作ؓ质量问题的一个事后I补措施?br /><br />  64. 可能羃短品的启动旉<br /><br />  MVMQ要q样。Y件启动时_Start-Up timeQ是客户Ҏ能好坏的第一印象?br /><br />  65. 不要q于注重内在品质而忽视了W一眼的外在印象<br /><br />  MVMQ程序员Ҏ犯这个错误:太看重性能、稳定性、存储效率,但忽视了外在感受。而高层经理、客h相反。这两方面要兼顾Q协调这些是PM的工作?br /><br />  66. 你们Ҏ详细产品功能说明书做开发么Q?br /><br />  MVMQ要q样。要有设计才能开发,q是必须的。设计文档,应该说清楚这个品会怎么q行Q应该采取一些讲故事的方法。设计的时候千万别ȝ节,别钻到数据库、代码等具体实现里面去,那些是后面的事情Q一步步来不能着急?br /><br />  67. 开始开发和试之前每个人都仔细审阅功能设计么?<br /><br />  MVMQ要做。Function Spec review是用来统一思想的。而且Qreviewq以后Ş成了一致意见,来再也没有人可以说“你看,当初我就是反对这么设计的Q现在吃苦头了吧?br /><br />  68. 所有h都始l想着The Whole Image么?<br /><br />  MVMQ要q样。项目里面每个h虽然都只是在刉一片叶子,但每个h都应该知道自己在刉的那片叶子所在的树是怎么样子的。我反对软g蓝领Q反对过分的把Y件制造看成流水线、R间。参见第61条?br /><br />  69. Dev工作的划分是单纯U向或横向的么?<br /><br />  MVMQ不能单U的Ҏ功能模块分,或者单U根据表现层、中间层、数据库层分。我推荐q么做:首先Ҏ功能模块分,然后每个“层”都有一个Owner来Review所有h的设计和代码Q保证consistency。?br /><br />  70. 你们的程序员写程序设计说明文档么Q?br /><br />  MVMQ要。不q我听说微Y的程序员1999q以前也不写。所以说Q写不写也不是绝对的Q偷懒有时候也是可以的。参见第56条?br /><br />  71. 你在招h面试时让他写一D늨序么Q?br /><br />  MVMQ要的。我最喜欢让h做字W串和链表一cȝ题目。这U题目有很多循环、判断、指针、递归{,既不偏向q于考算法,也不偏向q于考特定的API?br /><br />  72. 你们有没有技术交讲座?<br /><br />  MVMQ要的。每一两个C拜搞一ơ内部的Tech Talk或者Chalk Talk吧。让l员之间分n技术心得,q笔花钱送到外面d训划?br /><br />  73. 你们的程序员都能专注于一件事情么Q?br /><br />  MVMQ要让程序员专注一件事。例如说Q一个部门有两个目?0个hQ一U方法是?0个h同时参加两个目Q每个项目上每个人都?0%旉Q另一U方法是5个h去项目AQ?个h去项目BQ每个h?00%在某一个项目上。我一定选后面一U。这个道理很多h都懂Q但很多领导实践h把属下当成可以L拆分的资源了?br /><br />  74. 你们的程序员会夸大完成某工作所需要的旉么?<br /><br />  MVMQ会的,q是常见的,其会在目后期夸大做某个change所需要的旉Q以ơ来抵制change。解决的Ҏ是坐下来慢慢,掉E序员的逆反心理Q一起分析,q把估算旉的颗_度变小?br /><br />  75. 量不要用Virtual Heads<br /><br />  MVMQ最好不要用Virtual Heads。Virtual heads意味着resource is not secureQshared resource会降低resource的工作效率,Ҏ增加出错的机会,会让一心二用的人没有太多时间去review spec、review design。一个dedicated的hQ要两个只能投入50%旉和精力的人。我是吃q亏的:7个part time的testerQ发现的Bug和干的活Q加hq不如两个full-time的。参见第73条?3条是针对E序员的Q?5条是针对Resource Manager的?br /><img src ="http://m.tkk7.com/zlsunnan/aggbug/64259.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/zlsunnan/" target="_blank">☆蓝色梦想☆</a> 2006-08-18 09:27 <a href="http://m.tkk7.com/zlsunnan/archive/2006/08/18/64259.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>23U设计模式的代码?/title><link>http://m.tkk7.com/zlsunnan/archive/2006/08/17/64022.html</link><dc:creator>☆蓝色梦想☆</dc:creator><author>☆蓝色梦想☆</author><pubDate>Wed, 16 Aug 2006 16:45:00 GMT</pubDate><guid>http://m.tkk7.com/zlsunnan/archive/2006/08/17/64022.html</guid><wfw:comment>http://m.tkk7.com/zlsunnan/comments/64022.html</wfw:comment><comments>http://m.tkk7.com/zlsunnan/archive/2006/08/17/64022.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/zlsunnan/comments/commentRss/64022.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/zlsunnan/services/trackbacks/64022.html</trackback:ping><description><![CDATA[package lq.test;<br /><br />import java.io.*;<br />import java.util.*;<br /><br />//*********创徏型模?**************<br /><br />//factory method 1<br />//1具体的构造算法,?构造出的具体品由子类实现<br />interface Product {<br />}<br /><br />//或者我也提供一个工厂的接口Q由q个抽象cLl承?br /><br />abstract class Factory {<br />abstract public Product fmd();<br /><br />//我认个方Ҏ的存在是Q是对FactoryMethodҎ的补?br />//例如可以为生成的对象赋|计算为生成对象应付何|前后的日?br />//且这些都是公用的Q生成品的最主要法q是在FactoryMethod中,<br />//q个Ҏ只是赯助作用,q也是一U思维ҎQ将具体的算法实现在一个方法中<br />//而我不直接调用此ҎQ而用另外的一个方法封装它Q等C更灵zȝ效果Q?br />//子类需实现的内ҎFactoryMethod<br />//此方法是一个TemplateMethod<br />public Product creat() {<br />Product pd = null;<br /><br />System.out.println("before operation");<br /><br />pd = fmd();<br /><br />System.out.println("end operation");<br /><br />return pd;<br />}<br />}<br /><br />class Product1 implements Product {<br />}<br /><br />class Factory1 extends Factory {<br />public Product fmd() {<br />Product pd = new Product1();<br />return pd;<br />}<br />}<br /><br />//FactroyMethod 2<br />//q种方式单实?br />interface Producta {<br />}<br /><br />interface Factorya {<br />Producta create();<br />}<br /><br />class Producta1 implements Producta {}<br /><br />class Factorya1 implements Factorya {<br />public Producta create() {<br />Producta pda = null;<br />pda = new Producta1();<br />return pda;<br />} <br />}<br /><br />//AbstractFactory<br />//AbstractFactory与FactoryMethod的不同在于AbstractFactory创徏多个产品<br />//感觉此模式没有什么大?br /><br />//当然可以q有更多的接?br />interface Apda {}<br /><br />interface Apdb {}<br /><br />interface Afactory {<br />Apda createA();<br />Apdb createB();<br />}<br /><br />class Apda1 implements Apda {}<br /><br />class Apdb1 implements Apdb {}<br /><br />//有几个接口就有几个对应的Ҏ<br />class Afactory1 implements Afactory {<br />public Apda createA() {<br />Apda apda = null;<br />apda = new Apda1();<br />return apda;<br />}<br /><br />public Apdb createB() {<br />Apdb apdb = null;<br />apdb = new Apdb1();<br />return apdb;<br />}<br />}<br /><br />//Builder<br />//一个品的生成分ؓ生成部g和组装部Ӟ不同的品每个部件生成的方式不同<br />//而组装的方式相同Q部件的生成抽象成接口方法,而组装的Ҏ使用一个TemplateMethodҎ<br /><br />interface Cpda {}<br /><br />class Cpda1 implements Cpda {}<br /><br />interface BuilderI {<br />void buildPart1();<br />void buildPart2();<br /><br />void initPd();<br />Cpda getPd();<br />}<br /><br />abstract class BuilderA implements BuilderI {<br />Cpda cpda;<br /><br />public Cpda getPd() {<br />initPd();<br /><br />//对对象的内容q行讄<br />buildPart1();<br />buildPart2();<br /><br />return cpda;<br />}<br />}<br /><br />class Builder extends BuilderA {<br />public void buildPart1() {<br />System.out.println(cpda);<br />}<br /><br />public void buildPart2() {<br />System.out.println(cpda);<br />}<br /><br />public void initPd() {<br />cpda = new Cpda1();<br />}<br />}<br /><br />//一个简单的生成产品的实?br />//1<br />abstract class Fy {<br />public abstract void med1(); <br /><br />static class Fy1 extends Fy {<br />public void med1() {<br />}<br />}<br /><br />public static Fy getInstance() {<br />Fy fy = new Fy1();<br />return fy;<br /><br />//Fy fy = new Fy1() {//q种匿名内部cL静态的Q!<br />//public void med1() {<br />//}<br />//};<br />//return fy;<br />}<br />}<br /><br />//2<br />interface Pdd {}<br /><br />class Pdd1 implements Pdd {}<br /><br />abstract class Fya {<br />public static Pdd getPd() {<br />Pdd pdd = new Pdd1();<br />return pdd;<br />}<br />}<br /><br />//Prototype 在java中就是cloneQ又包含深拷贝和拷?br />class CloneObja {<br />public CloneObja MyClone() {<br />return new CloneObja();<br />}<br />}<br /><br />class CloneObjb {<br />public CloneObjb MyClone() throws Throwable {<br />CloneObjb cobj = null;<br />cobj = (CloneObjb) pcl(this);<br />return cobj;<br />}<br /><br />//深度拯法<br />private Object pcl(Object obj) throws Throwable {<br />ByteArrayOutputStream bao = new ByteArrayOutputStream(1000);<br />ObjectOutputStream objo = new ObjectOutputStream(bao);<br />objo.writeObject(obj);<br /><br />ByteArrayInputStream bai = new ByteArrayInputStream(bao.toByteArray());<br />ObjectInputStream obji = new ObjectInputStream(bai);<br /><br />Object objr = obji.readObject();<br />return objr;<br />} <br />}<br /><br />//Singleton<br />//一个类只有一个对象,例如一个线E池Q一个cache<br />class Singleton1 {<br />public static Singleton1 instance = new Singleton1();<br /><br />private Singleton1() {<br />}<br /><br />public static Singleton1 getInstance() {<br />return instance;<br />}<br />}<br /><br />class Singleton2 {<br />public static Singleton2 instance;<br /><br />private Singleton2() {<br />}<br /><br />//public static Singleton2 getInstance() {<br />//if (instance == null) {<br />//instance = new Singleton2();<br />//}<br />//<br />//return instance;<br />//}<br /><br />public static Singleton2 getInstance() {<br />synchronized(Singleton2.class) {<br />if (instance == null) {<br />instance = new Singleton2();<br />}<br />}<br /><br />return instance;<br />}<br />}<br />//**********l构型模?*********<br /><br />//Adapter<br />//基本Ҏ有两U,一U是使用引用一U用?br />//不W合标准的接口{成符合标准的接口Q接口的修改主要是参数的增减Q?br />//q回值类?当然q有Ҏ?br />//感觉q就是封装的另一U表CŞ式,装有用Ҏ装(在方法中调用功能Ҏ)Q?br />//用类装(先传入功能方法所在的cȝ对象Q通过调用此对象的功能Ҏ)<br /><br />//使用引用的Ş?br />class Adapteea {<br />public void kk() {}<br />}<br /><br />interface Targeta {<br />String vv(int i, int k);<br />}<br /><br />class Adaptera implements Targeta{<br />Adapteea ade;<br /><br />public Adaptera(Adapteea ade) {<br />this.ade = ade;<br />}<br /><br />public String vv(int i, int k) {<br />//具体的业务方法实现在Adaptee中,q个Ҏ<br />//只vC接口转换的作?br />//调用此方法是通过引用<br />ade.kk();<br />return null;<br />}<br />}<br /><br />//使用l承形式?br />class Adapteeb {<br />public void kk() {}<br />}<br /><br />interface Targetb {<br />String vv(int i, int k);<br />}<br /><br />class Adapterb extends Adapteeb implements Targetb {<br />public String vv(int i, int k) {<br />//调用此方法是通过l承<br />kk();<br />return null;<br />}<br />}<br /><br />//Proxy<br />interface Subject {<br />void request();<br />} <br /><br />class realSubject implements Subject {<br />public void request() {<br />//do the real business<br />}<br />}<br /><br />class Proxy implements Subject {<br />Subject subject;<br /><br />public Proxy(Subject subject) {<br />this.subject = subject;<br />}<br /><br />public void request() {<br />System.out.println("do something");<br /><br />subject.request();<br /><br />System.out.println("do something");<br />}<br />}<br /><br />//Bridge<br />//感觉是多态的实现<br /><br />interface Imp {<br />void operation();<br />}<br /><br />class Cimp1 implements Imp {<br />public void operation() {<br />System.out.println("1");<br />}<br />}<br /><br />class Cimp2 implements Imp {<br />public void operation() {<br />System.out.println("2");<br />}<br />}<br /><br />class Invoker {<br />Imp imp = new Cimp1();<br /><br />public void invoke() {<br />imp.operation();<br />}<br />}<br /><br />//Composite<br /><br />interface Component {<br />void operation();<br /><br />void add(Component component);<br /><br />void remove(Component component);<br />}<br /><br />class Leaf implements Component {<br />public void operation() {<br />System.out.println("an operation");<br />}<br /><br />public void add(Component component) {<br />throw new UnsupportedOperationException();<br />}<br /><br />public void remove(Component component) {<br />throw new UnsupportedOperationException();<br />}<br />}<br /><br />class Composite implements Component {<br />List components = new ArrayList();<br /><br />public void operation() {<br />Component component = null;<br /><br />Iterator it = components.iterator();<br />while (it.hasNext()) {<br />//不知道此component对象是leafq是compositeQ?br />//如果是leaf则直接实现操作,如果是composite则l递归调用<br />component = (Component) it.next();<br />component.operation();<br />}<br />}<br /><br />public void add(Component component) {<br />components.add(component);<br />}<br /><br />public void remove(Component component) {<br />components.remove(component);<br />}<br />}<br /><br />//Decorator<br />//对一个类的功能进行扩展时Q我可以使用l承Q但是不够灵z,所以选用?br />//另外的一UŞ?引用与扉K可活得对对象的一定的使用能力Q而用引用将更灵z?br />//我们要保证是对原功能的追加而不是修改,否则只能重写ҎQ或使用新的Ҏ<br />//注意concrete的可以直接new出来Q?br />//而decorator的则需要用一个另外的decorator对象才能生成对象<br />//使用对象装Q和公用接口<br />//Decorator链上可以有多个元?br /><br />interface Componenta {<br />void operation();<br />}<br /><br />class ConcreteComponent implements Componenta {<br />public void operation() {<br />System.out.println("do something");<br />}<br />}<br /><br />class Decorator implements Componenta {<br />private Componenta component;<br /><br />public Decorator(Componenta component) {<br />this.component = component;<br />}<br /><br />public void operation() {<br />//do something before<br /><br />component.operation();<br /><br />//do something after<br />}<br />}<br /><br />//Facade<br />//非常实用的一U设计模式,我可以ؓ外部提供感兴的接口<br /><br />class Obj1 {<br />public void ope1() {}<br />public void ope2() {}<br />}<br /><br />class Obj2 {<br />public void ope1() {}<br />public void ope2() {}<br />}<br /><br />class Facade {<br />//我得C一个简z清晰的接口<br />public void fdMethod() {<br />Obj1 obj1 = new Obj1();<br />Obj2 obj2 = new Obj2();<br /><br />obj1.ope1();<br />obj2.ope2();<br /> }<br />}<br /><br />//Flyweight<br />//I?br />//**********行ؓ型模?************<br /><br />//Chain of Responsibility<br />//与Decorator的实现Ş式相cMQ?br />//Decorator是在原来的方法之上进行添加功能,?br />//Chain则是判断信号如果不是当前处理的则转交个下一个节点处?br />//我可以用if分支来实现相同的效果Q但是不够灵z,链上的每个节Ҏ可以替换增加的,相对<br />//比较灉|Q我们可以设计接口实现对节点的增删操作,而实现更方便的效?br />//q个是一个链状的l构Q有没有惌使用环状l构<br /><br />interface Handler {<br />void handRequest(int signal);<br />}<br /><br />class CHandler1 implements Handler {<br />private Handler handler;<br /><br />public CHandler1(Handler handler) {<br />this.handler = handler;<br />}<br /><br />public void handRequest(int signal) {<br />if (signal == 1) {<br />System.out.println("handle signal 1");<br />}<br />else {<br />handler.handRequest(signal);<br />}<br />} <br />}<br /><br />class CHandler2 implements Handler {<br />private Handler handler;<br /><br />public CHandler2(Handler handler) {<br />this.handler = handler;<br />}<br /><br />public void handRequest(int signal) {<br />if (signal == 2) {<br />System.out.println("handle signal 2");<br />}<br />else {<br />handler.handRequest(signal);<br />}<br />} <br />}<br /><br />class CHandler3 implements Handler {<br />public void handRequest(int signal) {<br />if (signal == 3) {<br />System.out.println("handle signal 3");<br />}<br />else {<br />throw new Error("can't handle signal");<br />}<br />} <br />}<br /><br />class ChainClient {<br />public static void main(String[] args) {<br />Handler h3 = new CHandler3();<br />Handler h2 = new CHandler2(h3);<br />Handler h1 = new CHandler1(h2);<br /><br />h1.handRequest(2);<br />}<br />}<br /><br />//Interpreter<br />//感觉跟Composite很类|只不q他分文l结W和非终l符<br /><br />//Template Method<br /><br />abstract class TemplateMethod {<br />abstract void amd1();<br /><br />abstract void amd2();<br /><br />//此方法ؓ一个Template MethodҎ<br />public void tmd() {<br />amd1();<br />amd2();<br />}<br />}<br /><br />//State<br /><br />//标准?br />//状态和操作不应该耦合在一?br />class Contexta {<br />private State st;<br /><br />public Contexta(int nst) {<br />changeStfromNum(nst);<br />}<br /><br />public void changeStfromNum(int nst) {<br />if (nst == 1) {<br />st = new CStatea1();<br />}<br />else if (nst == 2) {<br />st = new CStatea2();<br />}<br /><br />throw new Error("bad state");<br />}<br /><br />void request() {<br />st.handle(this);<br />}<br />}<br /><br />interface State {<br />void handle(Contexta context);<br />}<br /><br />class CStatea1 implements State {<br />public void handle(Contexta context) {<br />System.out.println("state 1");<br />//也许在一个状态的处理q程中要改变状态,例如打开之后立即关闭q种效果<br />//context.changeStfromNum(2);<br />}<br />}<br /><br />class CStatea2 implements State {<br />public void handle(Contexta context) {<br />System.out.println("state 2");<br />}<br />}<br /><br />//工厂?br />//Ҏ状态不通生成不同的state<br /><br />//class StateFactory {<br />//public static State getStateInstance(int num) {<br />//State st = null;<br />//<br />//if (num == 1) {<br />//st = new CStatea1();<br />//}<br />//else if (num == 2) {<br />//st = new CStatea2();<br />//}<br />//<br />//return st;<br />//}<br />//}<br /><br />//Strategy<br />//跟Bridge相类|是一U多态的表示<br /><br />//Visitor<br />//双向引用Q用另外的一个类调用自己的方?讉K自己的数据结?br />interface Visitor {<br />void visitElement(Elementd element);<br />}<br /><br />class CVisitor implements Visitor {<br />public void visitElement(Elementd element) {<br />element.operation();<br />}<br />}<br /><br />interface Elementd {<br />void accept(Visitor visitor);<br /><br />void operation();<br />}<br /><br />class CElementd implements Elementd {<br />public void accept(Visitor visitor) {<br />visitor.visitElement(this);<br />}<br /><br />public void operation() {<br />//实际的操作在q里<br />}<br />}<br /><br />class Clientd {<br />public static void main() {<br />Elementd elm = new CElementd();<br />Visitor vis = new CVisitor();<br /><br />vis.visitElement(elm);<br />}<br />}<br /><br />//Iteraotr<br />//使用q代器对一个类的数据结构进行顺序P?br /><br />interface Structure {<br />interface Iteratora {<br />void first();<br /><br />boolean hasElement();<br /><br />Object next();<br /><br />}<br />}<br /><br />class Structure1 implements Structure {<br />Object[] objs = new Object[100];<br /><br />//使用内部cLZ对Struture1的数据结构有完全的访问权<br />class Iteratora1 implements Iteratora {<br />int index = 0;<br /><br />public void first() {<br />index = 0;<br />}<br /><br />public boolean hasElement() {<br />return index < 100;<br />} <br /><br />public Object next() {<br />Object obj = null;<br /><br />if (hasElement()) {<br />obj = objs[index];<br />index++;<br />}<br /><br />return obj;<br />}<br />}<br />}<br /><br />//Meditor<br /><br />class A1 {<br />public void operation1() {}<br />public void operation2() {}<br />}<br /><br />class A2 {<br />public void operation1() {}<br />public void operation2() {}<br />}<br /><br />class Mediator {<br />A1 a1;<br />A2 a2;<br /><br />public Mediator(A1 a1, A2 a2) {<br />this.a1 = a1;<br />this.a2 = a2;<br /><br />}<br /><br />//如果我想实现q个功能我可能会把他攑֜A1?br />//但是q样耦合大,我不惛_A1中出现A2对象的引用,<br />//所以我使用了Mediator作ؓ中介<br />public void mmed1() {<br />a1.operation1();<br />a2.operation2();<br />}<br /><br />public void mmed2() {<br />a2.operation1();<br />a1.operation2();<br />}<br />}<br /><br />//Command<br />//我认为就是将Ҏ转换成了c?br /><br />class Receiver {<br />public void action1() {}<br /><br />public void action2() {}<br />}<br /><br />interface Command {<br />void Execute();<br />}<br /><br />class CCommand1 implements Command {<br />private Receiver receiver;<br /><br />public CCommand1(Receiver receiver) {<br />this.receiver = receiver;<br />}<br /><br />public void Execute() {<br />receiver.action1();<br />}<br />}<br /><br />class CCommand2 implements Command {<br />private Receiver receiver;<br /><br />public CCommand2(Receiver receiver) {<br />this.receiver = receiver;<br />}<br /><br />public void Execute() {<br />receiver.action2();<br />}<br />}<br /><br />//Observer<br />//在这里看gq个模式没有什么用<br />//但是如果我有一个线E监控SubjectQ如果Subject的状?br />//发生了变化,则更改Observer的状态,q出发一些操作,q样有实际的意义了<br />//Observer与Visitor有相似的地方Q都存在双向引用<br />//Subject可以注册很多Observer<br /><br />interface Subjectb {<br />void attach(Observer observer);<br /><br />void detach(Observer observer);<br /><br />void mynotify();<br /><br />int getState();<br /><br />void setState(int state);<br />}<br /><br />class Subjectb1 implements Subjectb {<br />List observers = new ArrayList();<br />int state;<br /><br />public void attach(Observer observer) {<br />observers.add(observer);<br />}<br /><br />public void detach(Observer observer) {<br />observers.remove(observer);<br />}<br /><br />public void mynotify() {<br />Observer observer = null;<br />Iterator it = observers.iterator();<br /><br />while (it.hasNext()) {<br />observer = (Observer) it.next();<br />observer.Update();<br />}<br />}<br /><br />public int getState() {<br />return state;<br />}<br /><br />public void setState(int state) {<br />this.state = state;<br />}<br />}<br /><br />interface Observer {<br />void Update();<br />}<br /><br />class Observer1 implements Observer {<br />Subjectb subject;<br />int state;<br /><br />public Observer1(Subjectb subject) {<br />this.subject = subject;<br />}<br /><br />public void Update() {<br />this.state = subject.getState();<br />}<br /><br />public void operation() {<br />//一些基于state的操?br />}<br />}<br /><br />//Memento<br />//感觉此模式没有什么大?br /><br />class Memento {<br />int state;<br /><br />public int getState() {<br />return state;<br />}<br /><br />public void setState(int state) {<br />this.state = state;<br />}<br />}<br /><br />class Originator {<br />int state;<br /><br />public void setMemento(Memento memento) {<br />state = memento.getState();<br />}<br /><br />public Memento createMemento() {<br />Memento memento = new Memento();<br />memento.setState(1);<br />return memento;<br />}<br /><br />public int getState() {<br />return state;<br />}<br /><br />public void setState(int state) {<br />this.state = state;<br />}<br />}<br /><br />class careTaker {<br />Memento memento;<br /><br />public void saverMemento(Memento memento) {<br />this.memento = memento;<br />}<br /><br />public Memento retrieveMemento() {<br />return memento;<br />}<br />}<br /><br />//E序最l还是顺序执行的Q是׃通部分的操作拼接h?br />//不同类的代码拼接v来是通过引用实现的,有了引用我就<br />//相当于有了一定访问数据结构和Ҏ的能力,q与写在cd?br />//差不多,例如我想一个类中的一个方法抽d去,因ؓq个Ҏ依赖与此cȝ数据和其他方?br />//直接代码移走是不行的,但如果我们拥有了此类对象的引用,则与写在此类<br />//内部无异Q所以我们拥有了引用可以将此方法移?br />public class tt1 {<br />public static void main(String[] args) {<br />}<br />}<br /><img src ="http://m.tkk7.com/zlsunnan/aggbug/64022.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/zlsunnan/" target="_blank">☆蓝色梦想☆</a> 2006-08-17 00:45 <a href="http://m.tkk7.com/zlsunnan/archive/2006/08/17/64022.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts-Logic 标签?http://m.tkk7.com/zlsunnan/archive/2006/01/11/27648.html☆蓝色梦想☆☆蓝色梦想☆Wed, 11 Jan 2006 15:27:00 GMThttp://m.tkk7.com/zlsunnan/archive/2006/01/11/27648.htmlhttp://m.tkk7.com/zlsunnan/comments/27648.htmlhttp://m.tkk7.com/zlsunnan/archive/2006/01/11/27648.html#Feedback0http://m.tkk7.com/zlsunnan/comments/commentRss/27648.htmlhttp://m.tkk7.com/zlsunnan/services/trackbacks/27648.html此标{ֺ可以分ؓ三种cdQ条件、@环、{?重定向?BR>
一.) 条gcd

  1. logic:empty和logic:notEmpty
    logic:empty标签判断脚本变量是否为nullQ是否是一个空的字W串(长度?)Q是否是一个空的collection或map(调用isEmpty()Ҏ来判?。logic:notEmpty标签cM?BR>
     <logic:empty name="myBean">
       The bean is missing
     </logic:empty>
     <logic:notEmpty name="myBean">
       The bean is not missing
     </logic:notEmpty>
    上段代码表示当一个名为myBean的bean在所有的scope中都不存在时Q输出The bean is missingQ存在的话输出The bean is not missing?BR>此标{有三个属性:name、property和scope?BR>
  2. logic:equal, logic:notEqual, logic:lessThan, logic:greaterThan,logic:lessEqual, and logic:greaterEqual
    q堆logic:*equal*标签从名字上p知道意思,它们使用h有些W拙?BR>有如下属性:name、property、scope、value、cookie、header、parameter?BR>
     <logic:equal name="bean" property="doubleProperty" value="<%= doub1 %>">
        equal
     </logic:equal>
     <logic:greaterEqual name="bean" property="doubleProperty" value="<%= doub1 %>">
        greaterEqual
     </logic:greaterEqual> 

  3. logic:present和logic:notPresent
    查header、request parameter、cookie、JavaBean或JavaBean propertie是否存在且不{于null。另外还可以查当前用Lw䆾Q用属性user和role?BR>其它的属性有Qname、property、scope、cookie、header、parameter?BR>
     <logic:notPresent name="myBean"  property="prop"  scope="page">
     The bean property bean.prop is present
     </logic:notPresent>
    上段代码查在page作用域内名ؓmyBean的bean是否有一个prop属性?BR>
  4. logic:match和logic:notMatch
    比较两字W串是否相等Q可以比较字W串的开始的、结或其中的某个部分?BR>location属性:指定从某个位|开始进行比较?BR>其它的属性有Qname、property、scope、value、cookie、header、parameter?BR>下面的例子是查浏览器cdQ?BR>
     <logic:match header="User-Agent" value="Mozilla">
      Mozilla!
     </logic:match>
     <logic:notMatch header="User-Agent" value="Mozilla">
      Not Mozilla :(
     </logic:notMatch>

    查bean属性是否匹?hello world"字符Ԍ
     <logic:match name="bean" property="stringProperty" value="hello world">
      Hello World!
     </logic:match>
     <logic:notMatch name="bean" property="stringProperty" value="hello world">
      I'm so sad and lonely.
     </logic:notMatch> 

    查名?name"的请求参数是否是"xyz"的子字符Ԍ但是子字W串必须?xyz"的烦引位|?开?也就是说子字W串必须?y"?yz")Q?BR>
     <logic:match parameter="name"  value="xyz"  location="1">
          The parameter name is a sub-string of the string xyz from index 1
     </logic:match>

?) 循环cd

logic:iterate
重复嵌套在此标签体内的指定集合的元素Q集合必Mؓ如下cdQarray 、Collection(包括ArrayList和VectorQ、Enumeration、Iterator、Map(包括HashMap、Hashtable和TreeMap)。例如:
 <logic:iterate id="employee" name="department" property="employees" scope= "request">
?BR> <bean:write name="employee" property="username" />
?BR> <bean:write name="employee" property="name" />
?BR> <bean:write name="employee" property="phone" />
?BR> </logic:iterate> 
上面的代码P代了一个employee的集合,是department属性employees的一个集合,作用域ؓrequest?BR>
Z输出W五个到W十个employeeQ需要用length和offset属性:
 <logic:iterate id="employee" name="department" property="employees" scope= "request" length="10" offset="5">
?BR> <bean:write name="employee" property="username" />
?BR> <bean:write name="employee" property="name" />
?BR> <bean:write name="employee" property="phone" />
?BR> </logic:iterate>

 你可以定义一个变量保存当前的索引|      
 <ol>
 <logic:iterate id="element" name="bean" property="stringArray" indexId="index">
 <li>
 <em>
 <bean:write name="element"/>
 </em>&nbsp;
 [<bean:write name="index"/>]</li>
 </logic:iterate>
 </ol> 

?) 转发/重定向类?/FONT>

logic:forward和logic:redirect
logic:forward标签和jsp:forward标签和相|但它可以使用global forward中的一个ActionForwardQ?/FONT> 
 <logic:forward name="login" />
----------------------------------------------------------------------------------------------------------------------------------
 与上面相关的global forward中的代码Q?BR> <global-forwards>
 <forward name="login" path="/loginForm.jsp"/>
 </global-forwards>

logic:redirect标签和上面的标签cMQ但它默认调用的Ҏ是response.sendRedirect()Q取代了上面的requestDispatcher.forward()。最大的不同是它支持所有html:link标签的属性,所以你能够?/FONT>定request参数Q?/FONT>
 <logic:redirect name="login" paramId="employeeId" paramName="employee" property="id" />



]]>
查客L的Cookie讄http://m.tkk7.com/zlsunnan/archive/2005/12/06/22672.html☆蓝色梦想☆☆蓝色梦想☆Tue, 06 Dec 2005 02:15:00 GMThttp://m.tkk7.com/zlsunnan/archive/2005/12/06/22672.htmlhttp://m.tkk7.com/zlsunnan/comments/22672.htmlhttp://m.tkk7.com/zlsunnan/archive/2005/12/06/22672.html#Feedback0http://m.tkk7.com/zlsunnan/comments/commentRss/22672.htmlhttp://m.tkk7.com/zlsunnan/services/trackbacks/22672.html<%@page contentType="text/html; charset=GBK"%><%
//判断客户端是否打开Cook
  if (request.getParameter("flag") == null)
  {
    // the first request
    Cookie cookie = new Cookie("cookieSetting","on");
    response.addCookie(cookie);
    String nextUrl = request.getRequestURI() +"?flag=1";
    // force the browser to refresh
    out.println(nextUrl);
    //out.println("<META HTTP-EQUIV=Refresh CONTENT = 0; URL = " + nextUrl +" > ");
  }
  else
  {
    // the second request
    Cookie[] cookies = request.getCookies();
    boolean cookieFound = false;
    if (cookies != null) {
      int length = cookies.length;
      for (int i = 0; i < length; i++) {
        Cookie cookie = cookies[i];
        if
            (cookie.getName().equals("cookieSetting") &&
             cookie.getValue().equals("on")) {
          cookieFound = true;
          break;
        }
      }
    }
    if (cookieFound) {
      out.println("Cookie is on.");
    }
    else {
      out.println("Cookie is off.");
    }
  }
%>



]]>
限制对Web资源的访?http://m.tkk7.com/zlsunnan/archive/2005/12/06/22665.html☆蓝色梦想☆☆蓝色梦想☆Tue, 06 Dec 2005 02:00:00 GMThttp://m.tkk7.com/zlsunnan/archive/2005/12/06/22665.htmlhttp://m.tkk7.com/zlsunnan/comments/22665.htmlhttp://m.tkk7.com/zlsunnan/archive/2005/12/06/22665.html#Feedback0http://m.tkk7.com/zlsunnan/comments/commentRss/22665.htmlhttp://m.tkk7.com/zlsunnan/services/trackbacks/22665.html开发h员遇到的一个老问题是Q如何资源不完全暴露在大庭q众下,而只让那些适当的h和程序有完全的权限来讉K他们需要的资源Q至有三个好方法可以解册个问题?/P>

作ؓ一个Java Web开发h员,你可能已l对Web应用E序的目录结构很熟悉了(?A href="javascript:openWindowRes('Java/2002_09/xml2html.asp?xmlfile=RestrictAccessWebR/Figure1.xml&xslfile=../../include/xsl/Figure.xsl');">?Q。在WEB-INF/classes目录下放|了servletc,在WEB-INF/lib下是Java档案文gQ如HTML和图片文件的静态资源直接放在应用程序目录下Q或者在应用E序目录下的M子目录中Q。例如,所有图片文仉攑֜囄目录中(?A href="javascript:openWindowRes('Java/2002_09/xml2html.asp?xmlfile=RestrictAccessWebR/Figure1.xml&xslfile=../../include/xsl/Figure.xsl');">?Q。JSP面也放在应用程序目录中?/P>


				?.
?. 一?Servlet/JSP
应用E序的目录结?/A>
q运的是Q放在WEB-INF目录下的资源是安全的。用户不可以单地在浏览器的Location或Address中输入一个URL来调用它?/P>

q就是ؓ什么许多程序员都把他们的资源文Ӟ如果它们是和应用E序攑֜一L话)攑֜WEB-INF目录中的原因。WEB-INF之外的Q何资源都可以通过输入URL来查看。HTML文g和JSP文g一般都会被调用Q所以它们通常存储在WEB-INF之外?/P>

然而,你可能想限制对WEB-INF目录之外的文件的讉K。你可以用三U方法:通过q用referer HTTP request headerQ是“referer”,不是“referrer”)Q通过查用Lsession对象中的一个属性;或者通过那些资源放在WEB-INF中,q在适当的时候参照它们。下面是q用q三U方法的指南?/P>

q用Referer HTTP Request Header
Referer HTTP request header指定了一个URI (Uniform Resource Identifier)Q该URI包含链接到被h资源的页面的地址。例如,下面是对一个叫做myPage1.jsp的JSP面的请求,该页面来自一个叫做Login.jsp的文Ӟ
http://domainName/appName/Login.jsp

如果直接在Web览器的Address或Location中输入URL来调用myPage1.jspQ就不会有一个referer header?/FONT>

下面的例子运用了一个叫做DisplayRequestHeaders.jsp的JSP面Q?
<%@ page import="java.util.Enumeration" %>
<%
  Enumeration headers = request.getHeaderNames();
  while (headers.hasMoreElements()) {
    String header = (String) 
headers.nextElement();
    out.println(header + ":" + 
request.getHeader(header) + "<br>");
  }
%>

如果你直接将URL输入到浏览器的Address或Location来调用这个页面,l果如下Q?
accept:*/*
accept-language:en-us
accept-encoding:gzip, deflate
user-agent:Mozilla/4.0 (compatible; MSIE 6.0; 
Windows NT 5.0; .NET CLR 1.0.3705)
host:localhost:8080?connection:Keep-Alive
cookie:JSESSIONID=65D28447DFE4F58D1D806EAA933E9DD7

然而,如果通过点击另一个页面(如Login.jspQ中的一个链接来hDisplayRequestHeaders.jspQ你可以看到如下的结果:
accept:image/gif, image/x-xbitmap, image/jpeg, 
image/pjpeg, application/vnd.ms-excel, 
application/msword, application/vnd.ms-powerpoint, 
*/*
referer:http://localhost:8080/myJSPApp/Login.jsp
accept-language:en-us accept-encoding:gzip, deflate user-agent:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.0.3705) host:localhost:8080 connection:Keep-Alive cookie:JSESSIONID=65D28447DFE4F58D1D806EAA933E9DD7

注意两者的主要区别是在W二个结果中出现了referer header。因此,如果你的应用E序规定Q当你直接将URL输入到浏览器的Location或Address中来调用一个资源时Q你不能看到q个资源Q在q个例子中,是myPage1.jspQ,那么你可以把q个代码d到myPage1.jsp的顶部:
if (request.getHeader("referer")==null)
    response.sendRedirect(somewhereElse);
 
其中somewhereElse是你惌用户q入的页面的URL?/P>

或者,如果你想信资源来自一个特定的URLQ可以在前面的代码后面添加下面的代码Q?
if (request.getHeader("referer")==null)
    response.sendRedirect(somewhereElse);
  if (request.getHeader("referer")!=aURL)
    response.sendRedirect(somewhereElse);

然而,你需要注意,q用referer header只适合于简单的控制管理。因为它依赖于来自用Lrequest headersQ所以它q不?00%的安全。了解socket programming的聪明的用户常常可以信有一个包含期望值的referer header?/P>

查一个Session对象的属?/FONT>
另一U限制对一个特定页面的讉K的方法就是通过查用Lsession对象中出现的一个特定的属性。例如,如果你想让ABC.jsp面只能被登录后的用L刎ͼ你可以在用户成功d后,在用户session对象中设|一个叫做loggedIn的属性。然后在ABC.jsp面的顶部,你可以查看loggedIn属性是否出现在用户的session对象中:
<%
  if (session.getAttribute("loggedIn")==null) {
%>
    <jsp:forward page="Login.jsp"/>
<%
  }
  else {
%> 
display the page content here.

q种Ҏ的缺Ҏ你在每一都需要额外的代码Q而且q有另外的维护工作。更重要的是Q受限制的页面需要参预session理Q而这正是你在一些应用程序中可能想避免的事情?/P>

在WEB-INF目录下存储资?/FONT>
在你不想让用戯用你的JSP面ӞW三U方法——将资源攑֜WEB-INF下——会很有用。实现Model 2l构的应用程序和Struts应用E序q用JSP面作ؓModel-View-Controller中的View。这些JSP面q不打算让用户从览器直接调用。作为替代,它们从控制器servlet内部来调用。对q些应用E序来说Q将JSP面攑֜WEB-INF目录外——就像许多程序员所做的那样——需要你d额外的代码来限制对这些资源的直接讉K?/P>

另一斚wQ把它们攑֜WEB-INF中可以保证它们只能从那个应用E序的一个servlet来访问。但如果你决定把JSP面存在WEB-INF中,你就需要知道如何参照这些页面。幸q的是,qƈ不难。做法如下?/P>

通过q用一个RequestDispatcher对象Q一个servlet可以包含QincludeQ或转送(forwardQ一个JSP面。下面的例子forwardqinclude一个叫做Included.jsp的JSP面Q?
  RequestDispatcher rd = 
    request.getRequestDispatcher("/WEB-
    INF/Included.jsp");
  rd.forward(request, response);

但有时侯Q你需要显C的是HTML文gQ而不是JSP面。在一些Web容器QcontainersQ中Q前面代码中的request dispatchersq不能用于静态的资源Q如果静态资源不在WEB-INF下,它可以用Q。对q些资源来说Q你可以q用javax.servlet.ServletContext接口的getResourceAsStreamҎ。该Ҏ的定义如下:
public java.io.InputStream 
getResourceAsStream(java.lang.String path)

要运用这个方法,你需要把一个\径传送到你想包含的静态资源。该Ҏq回一个InputStream。然后,你可以用InputStream的readҎ来得到静态资源的内容?/P>

例如Q下面的q个JSP面包含一个叫做getResourceContent的函敎ͼ你可以用它以字符串Ş式返回一个静态资源的内容Q?
<%@ page import="java.io.InputStream"%>
<%!
  public String getResourceContent(InputStream in) {
    if (in==null)
      return null;

    StringBuffer sb = new StringBuffer(2048);
    try {
      int i = in.read();
      while (i != -1) {
        sb.append((char)i);
        i = in.read();
      }
      in.close();
    }
    catch (Exception e) {
    }
    return sb.toString();
  }
%>

<html>
<head>
<title>
</title>
</head>
<body>
<br>
<%
  String path = "/WEB-INF/header.html";
  InputStream in = 
application.getResourceAsStream(path);
  out.println(getResourceContent(in));
%>
</body>
</html>
 

注意Q在JSP面中,应用E序暗示的对象代表ServletContext对象?/P>

该JSP面昄了如何包含位于WEB-INF目录中的header.html文g的内宏V如果你把header.html文g攑֜q儿Q它׃能直接从览器调用?/P>

通过q用一些缓冲策略,你可以优化JSP面中的getResourceContentҎ。在q里Q我只是解释了得到放在WEB-INF目录下的一个静态资源的内容的方法?/P>

你可以从一个servlet内部Q也可以从一个JSP面q用getResourceContentҎ。从一个JSP面Q你可以q用指示WincludeQ如下面的代码所C:
<%@ include file="/WEB-INF/header.html" %>

现在你应该了解了Q你有三U不同的Ҏ来保护你的资源,以及如何实现q些Ҏ?/P>


]]>
客户端重定向http://m.tkk7.com/zlsunnan/archive/2005/12/06/22658.html☆蓝色梦想☆☆蓝色梦想☆Tue, 06 Dec 2005 01:41:00 GMThttp://m.tkk7.com/zlsunnan/archive/2005/12/06/22658.htmlhttp://m.tkk7.com/zlsunnan/comments/22658.htmlhttp://m.tkk7.com/zlsunnan/archive/2005/12/06/22658.html#Feedback0http://m.tkk7.com/zlsunnan/comments/commentRss/22658.htmlhttp://m.tkk7.com/zlsunnan/services/trackbacks/22658.html
· 当你惛_gq重定向Ӟ你必运用客L重定向。服务器端重定向是立卛_现的Q因此,举例来说Q你׃能用服务器端重定向技术来创徏一个闪屏(splash screenQ?/TD>
· 如果你没有运用诸如servlets或JSP的服务器端处理技术,那么你只能用客户端重定向来引g的网站访问者?/TD>

关于客户端重定向Q你可以用Refresh metatag或JavaScript。下面我分别讲述q两U方法?/P>

q用Refresh Metatag
Metatags比JavaScriptҎ。在一个页面已l显CZ一D|间后Q你可以用它们来把用户从q个面引导开Q?
<META HTTP-EQUIV="Refresh" 
CONTENT="t;URL=differentURL"> 

t是在重定向前Q浏览器等待的U数?/P>

例如Q下面的脚本在页面显CZ三秒后,浏览器重定向到http://www.brainysoftware.com?
<HTML>
<HEAD>
<TITLE>Client side redirection using the 
meta tag </TITLE>
<META HTTP-EQUIV="Refresh" 
CONTENT="3;URL=http://www.brainysoftware.com"> 
</HEAD>
<BODY>
You will be redirected in 3 seconds. For now, 
relax and enjoy.
</BODY>
</HTML>

当t=0Ӟ不会出现延迟?/P>

该技术可以用于Netscape Navigator 3及更高版本,Internet Explorer 4及更高版本?BR>

q用JavaScript
在运用metatagӞ你的局限性很大,因ؓ一些老的览器读不懂它。如果你担心q个问题Q那么你可以用JavaScript。然而,如果用户览器不支持JavaScriptQ你q是会有问题?/P>

要用JavaScriptq行客户端重定向Q运用定位对象(location objectQ:
<SCRIPT LANGUAGE="JavaScript">
location=differentURL
</SCRIPT>

differentURL是浏览器被重新定向到的新的URL。下面的例子昄如何q用定位对象来重定向Q?
<HTML>
<HEAD>
<TITLE>Client-side redirection using 
JavaScript</TITLE>
<SCRIPT LANGUAGE="JavaScript">
location='http://www.brainysoftware.com';
</SCRIPT>
</HEAD>
<BODY>
You will be redirected to another page. For now, 
enjoy and relax.
</BODY>
</HTML>

同运用metatags一P你可以用JavaScript来gq重定向。运用setTimeoutҎ来实现这一点:
setTimeout("location='differentURL'", t);

t是用戯重定向到differentURL前的毫秒数?/P>

下面的代码在5U后用户重定向到www.brainysoftware.comQ?
<HTML>
<HEAD>
<TITLE>Client-side redirection using 
JavaScript</TITLE>
<SCRIPT LANGUAGE="JavaScript">
  setTimeout("location=
  'http://www.brainysoftware.com'", 5000);
</SCRIPT>
</HEAD>
<BODY>
Hello, you will be redirected in 5 seconds. Start 
counting now...
</BODY>
</HTML>

该技术可以用于Netscape Navigator 2及更高版本,Internet Explorer 3及更高版本?BR>

预见不成功的重定?/FONT>
每种技术都有缺炏Vmetatags不能用于老的览器,如果览器不支持JavaScriptQ那么JavaScript׃能用?/P>

所以在重定向用hQ你常常要预料到p|的情c当自动的重定向p|Ӟ用户必须点击一个链接,使他或她可以q入期望的地址。所以需要常发送这个链接,如下例所C:
<HTML>
<HEAD>
<TITLE>When redirection fails . . .
</TITLE>
<SCRIPT LANGUAGE="JavaScript">
  setTimeout("location=
  'http://www.brainysoftware.com'", 5000);
</SCRIPT>
</HEAD>
<BODY>
Click <A HREF="RedirectionURL">here</A> if you do 
not get redirected in 5 seconds.
</BODY>
</HTML>



]]>
服务器端重定?/title><link>http://m.tkk7.com/zlsunnan/archive/2005/12/06/22657.html</link><dc:creator>☆蓝色梦想☆</dc:creator><author>☆蓝色梦想☆</author><pubDate>Tue, 06 Dec 2005 01:39:00 GMT</pubDate><guid>http://m.tkk7.com/zlsunnan/archive/2005/12/06/22657.html</guid><wfw:comment>http://m.tkk7.com/zlsunnan/comments/22657.html</wfw:comment><comments>http://m.tkk7.com/zlsunnan/archive/2005/12/06/22657.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/zlsunnan/comments/commentRss/22657.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/zlsunnan/services/trackbacks/22657.html</trackback:ping><description><![CDATA[<P xmlns:fo="http://www.w3.org/1999/XSL/Format"><BR>     重定向(redirectionQ是Web~程中的一个重要的技术。运用重定向Q你可以把控件发送到另一个servlet/JSP面Q或Web览器(用户Q重定向C个新的URL。然而,用户重定向到同一个页面也是很常见的。例如,如果要查看浏览器的cookie support是否Ȁz,你可以把一个cookie发送到览器,然后浏览器重定向到同一个页面?/P> <P xmlns:fo="http://www.w3.org/1999/XSL/Format">重定向可以在服务器端q行Q也可以在客LQ浏览器Q进行。因为在servlet/JSP面上有服务器端的代码,所以可以在服务器端q行重定向。客L的重定向可以通过发送JavaScript代码或者传送到览器的HTML面的元数据来完成。现在,让我们来看看两个服务器端重定向的技巧?/P> <P xmlns:fo="http://www.w3.org/1999/XSL/Format">在servlet/JSP~程中,服务器端重定向可以通过下面两个Ҏ来实玎ͼq用javax.servlet.RequestDispatcher接口的forwardҎQ或者运用javax.servlet.http.HttpServletResponse接口的sendRedirectҎ?/P> <P xmlns:fo="http://www.w3.org/1999/XSL/Format"><B><FONT color=#333399>q用RequestDispatcher接口的ForwardҎ</FONT></B><BR>要运用RequestDispatcher接口的forwardҎQ首先要得到一个RequestDispatcher对象。servlet技术提供了三种方式来得到它Q? <TABLE cellSpacing=5> <TBODY> <TR> <TD> <TD>1. 通过q用javax.servlet.ServletContext接口的getRequestDispatcherҎQ将一个包含\径的String传递给其它资源。该路径是相对于ServletContext的根路径的?/TD></TR></TBODY></TABLE> <TABLE cellSpacing=5> <TBODY> <TR> <TD> <TD>2. 通过q用javax.servlet.ServletRequest接口的getRequestDispatcherҎQ将一个包含\径的String传递到其它资源。该路径是相对于当前的HTTPh的?/TD></TR></TBODY></TABLE> <TABLE cellSpacing=5> <TBODY> <TR> <TD> <TD>3. 通过q用javax.servlet.ServletContext接口的getNamedDispatcherҎQ传递一个包含其它资源名字的String?/TD></TR></TBODY></TABLE></P> <P xmlns:fo="http://www.w3.org/1999/XSL/Format">在得到RequestDispatcher对象后,q用forwardҎ很Ҏ了。forwardҎ的定义如下: <TABLE bgColor=#ffffaa> <TBODY> <TR> <TD><FONT color=#0000cc><PRE>public void forward(javax.servlet.ServletRequest request, javax.servlet.ServletResponse response) throws javax.servlet.ServletException, java.io.IOException</PRE></FONT></TD></TR></TBODY></TABLE></P> <P xmlns:fo="http://www.w3.org/1999/XSL/Format">但要注意Q你只有在客L没有输出时才可以调用forwardҎ。如果当前页面的~冲区(bufferQ不是空的,那么你在调用forwardҎ前必d清空~冲区。否则,会抛Z个IllegalStateException。forwardҎ也可以用来将h发送到一个静态的面?BR>        </P> <P xmlns:fo="http://www.w3.org/1999/XSL/Format">servlet/JSP的初学者在试得到一个RequestDispatcher对象Ӟ常感到困惑,q是因ؓServletContext接口的getRequestDispatcherҎ和ServletRequest接口的getRequestDispatcherҎ有很大的不同。接着阅读本文你就可以得到一些技巧来避免这两者؜淆在一起了?/P> <P xmlns:fo="http://www.w3.org/1999/XSL/Format">在运用RequestDispatcher对象的forwardҎ来将一个控件从一个叫做ABCServlet的servlet传递到另一个叫做XYZServlet的servletӞ最单的Ҏ是把ABCServlet和XYZServlet的类文g攑֜同一个目录中。通过q种ҎQ你可以从URL http://domain/VirtualDir/servlet/ABCServlet来调用ABCServletQ从URL http://domain/VirtualDir/servlet/XYZServlet来调用XYZServlet了。然后运用forwardҎ很单了。你可以从ServletRequest接口q用getRequestDispatcher ,传递第二个servlet的名字。在ABCServlet中,你可以写下面的代码: <TABLE bgColor=#ffffaa> <TBODY> <TR> <TD><FONT color=#0000cc><PRE> RequestDispatcher rd = request.getRequestDispatcher("SecondServlet"); rd.forward(request, response); </PRE></FONT></TD></TR></TBODY></TABLE></P> <P xmlns:fo="http://www.w3.org/1999/XSL/Format">你不需要在XYZServlet前放 / W号。这U方法是最单的Q因ZҎ不需要担心两个servlets的\径?</P> <P xmlns:fo="http://www.w3.org/1999/XSL/Format">E复杂的Ҏ是把下面这个String传递到ServletRequest的getRequestDispatcherQ? <TABLE bgColor=#ffffaa> <TBODY> <TR> <TD><FONT color=#0000cc><PRE>"/servlet/XYZServlet"</PRE></FONT></TD></TR></TBODY></TABLE></P> <P xmlns:fo="http://www.w3.org/1999/XSL/Format">如果你必调用一个从ServletContext的getRequestDispatcher得到的RequestDispatcher对象的forwardҎQ你需要将?VirtualDir/servlet/XYZServlet”作\径参数来传递,如下Q? <TABLE bgColor=#ffffaa> <TBODY> <TR> <TD><FONT color=#0000cc><PRE> RequestDispatcher rd = getServletContext().getRequestDispatcher( "/servlet/XYZServlet"); rd.forward(request, response); </PRE></FONT></TD></TR></TBODY></TABLE></P> <P xmlns:fo="http://www.w3.org/1999/XSL/Format">要运用getNamedDispatcherҎQ你的代码就会变成: <TABLE bgColor=#ffffaa> <TBODY> <TR> <TD><FONT color=#0000cc><PRE> RequestDispatcher rd = getServletContext().getNamedDispatcher( "XYZServlet"); rd.forward(request, response);</PRE></FONT></TD></TR></TBODY></TABLE></P> <P xmlns:fo="http://www.w3.org/1999/XSL/Format">在运用getNamedDispatcherҎӞ你必d部v描述W中注册W二个servlet。下面是个例子: <TABLE bgColor=#ffffaa> <TBODY> <TR> <TD><FONT color=#0000cc><PRE> <web-app> <servlet> <servlet-name>ABCServlet</servlet-name> <servlet-class>ABCServlet</servlet-class> </servlet> <servlet> <servlet-name>XYZServlet</servlet-name> <servlet-class>XYZServlet</servlet-class> </servlet> </web-app> </PRE></FONT></TD></TR></TBODY></TABLE></P> <P xmlns:fo="http://www.w3.org/1999/XSL/Format">如果你改变了所含的servletQ你需要重新启动Web container以改变生效。这是因为所包含的servlet从来都不是直接调用的。一旦加载了所包含的servletQ它的时间戳Qtime stampQ就不会改变了?/P> <P xmlns:fo="http://www.w3.org/1999/XSL/Format">如果你从一个JSP面发送控Ӟ你也可以?lt;jsp:forward>执行元素Q它会终止当前JSP面的执行,q将控g传递到另一个资源。它的语法如下: <TABLE bgColor=#ffffaa> <TBODY> <TR> <TD><FONT color=#0000cc><PRE><jsp:forward page="relativeURL"/></PRE></FONT></TD></TR></TBODY></TABLE></P> <P xmlns:fo="http://www.w3.org/1999/XSL/Format">例如Q在JSP面被解析后Q?lt;jsp:forward page=”OtherPage.jsp?>在结果servlet中就转换成了下面的代码: <TABLE bgColor=#ffffaa> <TBODY> <TR> <TD><FONT color=#0000cc><PRE>pageContext.forward("OtherPage.jsp");</PRE></FONT></TD></TR></TBODY></TABLE></P> <P xmlns:fo="http://www.w3.org/1999/XSL/Format"><BR xmlns:fo="http://www.w3.org/1999/XSL/Format"></P> <P xmlns:fo="http://www.w3.org/1999/XSL/Format"><B><FONT color=#333399>q用HttpServletResponse接口的sendRedirectҎ</FONT></B><BR>sendRedirectҎ比forwardҎ要容易。其定义如下Q? <TABLE bgColor=#ffffaa> <TBODY> <TR> <TD><FONT color=#0000cc><PRE>public void sendRedirect(java.lang.String location) throws java.iio.IOException </PRE></FONT></TD></TR></TBODY></TABLE></P> <P xmlns:fo="http://www.w3.org/1999/XSL/Format">该方法把一个命令发送到览器,让浏览器对在location中指定的URL提出h。该Ҏ可以接受l对的或相对的URLs。如果传递到该方法的参数是一个相对的URLQ那么Web container在将它发送到客户端前会把它{换成一个绝对的URL。如果地址是相对的Q没有一个?’,那么Web containerp为它是相对于当前的请求URI的?/P> <P xmlns:fo="http://www.w3.org/1999/XSL/Format">例如Q你可以用下面的代码用户重定向到www.brainysoftware.com: <TABLE bgColor=#ffffaa> <TBODY> <TR> <TD><FONT color=#0000cc><PRE>response.sendRedirect(http://www.brainysoftware.com); </PRE></FONT></TD></TR></TBODY></TABLE></P> <P xmlns:fo="http://www.w3.org/1999/XSL/Format"><STRONG><FONT face=Arial color=#000000 size=5><U>你应该运用哪U技巧?<BR>Z~写最有效的代码,你应该了解这两种重定向技巧的不同。forwardҎ是在Web container内部工作的。sendRedirectҎ需要到客户端的一个往q。所以forwardҎ比sendRedirect要快。但是,q用forwardҎ有局限性,你只能重定向到同一个Web应用E序中的一个资源。而sendRedirectҎ可以让你重定向到MURL。结论:如果可以解决你的问题Q那么就用forwardҎ。只有当你不能用forwardҎ时才q用sendRedirectҎ?/U></FONT></STRONG></P><img src ="http://m.tkk7.com/zlsunnan/aggbug/22657.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/zlsunnan/" target="_blank">☆蓝色梦想☆</a> 2005-12-06 09:39 <a href="http://m.tkk7.com/zlsunnan/archive/2005/12/06/22657.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts 例子http://m.tkk7.com/zlsunnan/archive/2005/12/06/22654.html☆蓝色梦想☆☆蓝色梦想☆Tue, 06 Dec 2005 01:21:00 GMThttp://m.tkk7.com/zlsunnan/archive/2005/12/06/22654.htmlhttp://m.tkk7.com/zlsunnan/comments/22654.htmlhttp://m.tkk7.com/zlsunnan/archive/2005/12/06/22654.html#Feedback0http://m.tkk7.com/zlsunnan/comments/commentRss/22654.htmlhttp://m.tkk7.com/zlsunnan/services/trackbacks/22654.html 
  • 查看:[设计图] 下蝲: struts-blank.war
  • 查看:[设计图] 下蝲:struts-example.war
  • 查看:[设计图] 下蝲:struts-exercise-taglib.war
  • 查看:[设计图] 下蝲:struts-validator.war
  • 查看:[设计图] 下蝲:struts-upload.war
  • 查看:[设计图] 下蝲:struts-cookbook.war
  • 查看:[设计图] 下蝲:simple-module-switching.war
  • 本地下蝲 
  •  



    ]]>
    վ֩ģ壺 ѿһaƬþ| 24Сʱձwwwѵ| av߹ۿҰ| ͼƬС˵| ľþþƷ| Ƶ| av˾Ʒ߲| ҹƷ| Ů18ëƬaëƬƵ| è˳վ߹ۿ| ޾Ʒþþwww| ѾþþƷѾѾ| С˵ͼƬ| ĻƵ߹ۿ| Ļ| С߿Ƭ˳Ӿ| Ůbbbbbbbbb| ĻѸ| Ļպ| þþWWW˳ɾƷ| ޾ƷƷ벻99| ˬִ̼߳Ƶ | ޹˾þ| һӰ߿Ƭ| Ʒרһ| ɫþþ99Ʒ91| þù׾Ʒһ | av뾫ƷװƬ| ձַȫ߹ۿ| Ƶ| Ʒۺϳ| ֱѹۿ| ߾Ʒ޵һ| þ99޸ۿҳ | þþþþùaѹۿɫƬ | ޹˽ӰԺ| ëƬ߿Ѱ| ƷŮƵۿ| ۺϾþó69| vƬƵ߹ۿƵ| ھƷ߹ۿ|