ï»??xml version="1.0" encoding="utf-8" standalone="yes"?>伊人影院在线视频,精品福利av导航,国产69精品久久久久孕妇http://www.aygfsteel.com/qileilove/category/53091.html不想做屌丝的码农åQŒä¸æ˜¯å¥½™å¹ç›®¾lç†åQå±Œä¸ç”Ÿæ¶¯ä»Žæ­¤å¼€å§‹ï¼zh-cnThu, 13 Mar 2014 12:28:48 GMTThu, 13 Mar 2014 12:28:48 GMT60一个用于网站自动化‹¹‹è¯•的生态系¾lŸå®žçŽ?/title><link>http://www.aygfsteel.com/qileilove/archive/2014/03/13/410968.html</link><dc:creator>™åºå…¶è‡ªç„¶EVO</dc:creator><author>™åºå…¶è‡ªç„¶EVO</author><pubDate>Thu, 13 Mar 2014 03:34:00 GMT</pubDate><guid>http://www.aygfsteel.com/qileilove/archive/2014/03/13/410968.html</guid><wfw:comment>http://www.aygfsteel.com/qileilove/comments/410968.html</wfw:comment><comments>http://www.aygfsteel.com/qileilove/archive/2014/03/13/410968.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/qileilove/comments/commentRss/410968.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/qileilove/services/trackbacks/410968.html</trackback:ping><description><![CDATA[<div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 11.818181991577148px; background-color: #ffffff;">  ˜q™æ˜¯æˆ‘在从事¾|‘ç«™<a target="_self" style="word-break: break-all; color: #202859; line-height: normal !important;"><u style="word-break: break-all;"><strong style="word-break: break-all;">自动化测è¯?/strong></u></a>çš?a target="_self" style="word-break: break-all; color: #202859; line-height: normal !important;"><u style="word-break: break-all;"><strong style="word-break: break-all;">工作</strong></u></a>当中构徏出的一ä¸?#8220;生态系¾l?#8221;ã€?#8220;生态系¾l?#8221;˜q™ä¸ªæ¦‚念是我从公司的前辈íw«ä¸Šå­¦åˆ°çš„ï¼Œä»–ä¸€ç›´ä»¥æ¥éƒ½è®¤äØ“(f¨´)自动化测试äh员不应仅仅局限于¾~–写‹¹‹è¯•代码åQŒè¿˜åº”该让整个自动化‹¹‹è¯•的过½E‹ï¼ˆ‹¹‹è¯•代码的持¾l­é›†æˆã€åˆ†å‘、执行等åQ‰éƒ½è‡ªåŠ¨åŒ–ï¼Œå½¢æˆä¸€ä¸?#8220;¾pȝ»Ÿ”åQŒè¿™ä¸ªç³»¾lŸçš„自动化程度越高,自动化测试äh员就­‘ŠçœåŠ›ã€?/div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 11.818181991577148px; background-color: #ffffff;">  <strong style="word-break: break-all; line-height: normal !important;">一、概å¿?/strong></div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 11.818181991577148px; background-color: #ffffff;">  ˜q™é‡Œæˆ‘画了一张示意图åQ?/div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 11.818181991577148px; background-color: #ffffff;"><a target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/03/14982672_201403101350321E3JG.jpg" border="0" style="word-break: break-all; list-style: none outside none; margin: 0px; padding: 0px; border: none; max-width: 500px;" alt="" /></a></div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 11.818181991577148px; background-color: #ffffff;">ã€€ã€€ä¹‹æ‰€ä»¥ç§°ä¹‹äØ“(f¨´)“生态系¾l?#8221;åQŒæ˜¯å› äØ“(f¨´)建成之后需要的äºÞZØ“(f¨´)òq²æ¶‰å¾ˆå°‘åQŒå…¶ä½™çš„æ—‰™—´éƒ½æ˜¯¾pȝ»Ÿå†…部循环˜qä½œã€‚ä½œä¸ø™‡ªåŠ¨åŒ–‹¹‹è¯•人员的你只需要提交代码,之后便可以在AutomationDashboard上看到运行的¾l“果了,其余的事情都ç”Þq³»¾lŸå†…部消化。当ç„Óž¼Œ¾l“果的分析还是需要äh来完成,机器˜q˜æ²¡æœ‰èªæ˜Žåˆ°å¯ä»¥ç‰|´»åˆ†æžå‡ºå„¿Uå„æ ¯‚®©case fail掉的原因ã€?/div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 11.818181991577148px; background-color: #ffffff;">  我们可以把整个系¾lŸçœ‹ä½œä¸€ä¸ªé»‘盒子åQŒé‚£ä¹ˆä¸Šé¢çš„囑֏¯ä»¥å˜æˆï¼š(x¨¬)</div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 11.818181991577148px; background-color: #ffffff;"><a target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/03/14982672_201403101350322xbVu.jpg" border="0" style="word-break: break-all; list-style: none outside none; margin: 0px; padding: 0px; border: none; max-width: 500px;" alt="" /></a></div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 11.818181991577148px; background-color: #ffffff;">  实际上这里画的äh不仅限于自动化测试äh员,也可以是åQ?/div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 11.818181991577148px; background-color: #ffffff;">  åQ?åQ‰äñ”品的½Ž¡ç†è€…,比如产品¾lç†éœ€è¦ä»Žè‡ªåŠ¨åŒ–å›žå½’æµ‹è¯•çŸ¥é“è¿™‹Æ¡release有无推迟风险åQ?/div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 11.818181991577148px; background-color: #ffffff;">  åQ?åQ‰å›¢é˜Ÿçš„½Ž¡ç†è€…,比如开发经理、QA¾lç†éœ€è¦ä»Žè‡ªåŠ¨åŒ–çš„daily/weekly regression知道最˜q‘的代码质量如何åQ?/div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 11.818181991577148px; background-color: #ffffff;">  åQ?åQ‰å¼€å‘äh员,他们也许ä¼?x¨¬)想通过quick regressionåQˆæäº¤çš„产品代码被部¾|²åˆ°‹¹‹è¯•环境之后˜qè¡Œçš„æµ‹è¯•)知道自己刚提交的代码有没有破坏系¾lŸçš„基本功能åQ?/div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 11.818181991577148px; background-color: #ffffff;">  åQ?åQ‰å…¶ä»–帮忙做自动化测试的开发äh员、刚刚开å§?a target="_self" style="word-break: break-all; color: #202859; line-height: normal !important;"><u style="word-break: break-all;"><strong style="word-break: break-all;">学习(f¨¤n)</strong></u></a>¾~–写自动化测试代码的手动‹¹‹è¯•人员åQŒä»–们不必关心生态系¾lŸçš„内部实现ã€?/div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; color: #333333; font-family: Arial, Helvetica, sans-serif; font-size: 11.818181991577148px; background-color: #ffffff;"><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;"> <strong style="word-break: break-all;"> 二、实çŽ?/strong></div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">  说完概念åQŒæŽ¥ä¸‹æ¥è¯¥è¯´è¯´å…·ä½“实çŽîCº†ã€‚我˜q™é‡Œè®²çš„æ˜¯æˆ‘è®¤äØ“(f¨´)最适合我所‹¹‹è¯•çš„äñ”品的实现åQŒå·¥å…·ä¸æ­¢ä¸€¿Uï¼Œæ–¹å¼ä¸æ­¢ä¸€¿Uã€‚Jenkins可以用TeamCity或其它CI替换åQŒgit也可以是svn或tfsåQŒAutomationDahsboard可以ç”?NET、SpringMVC、ROR½{‰ç­‰å®žçްåQŒè¿è¡Œæµ‹è¯•çš„slave可以是Windows/Linux/MacåQˆåœŸè±ªï¼åQ‰ï¼Œæ€ÖM¹‹é€‰æ‹©ä¸€¿Uæœ€é€‚合你所‹¹‹è¯•çš„äñ”品的实现。还有一点就是自动化‹¹‹è¯•代码是用关键字驱动思想实现的,˜q™æ˜¯å¦å¤–一个话题了åQŒæœ‰æ—‰™—´å¦å¤–写篇文ã€?/div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">  <strong style="word-break: break-all;">好,˜q›å…¥æ­£é¢˜ã€‚依‹Æ¡è¯´è¯´ç³»¾lŸçš„æ¯ä¸ªé‡è¦¾l„成部分吧:(x¨¬)</strong></div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">  1、SCMåQˆSource Code ManagementåQ‰ã€‚我选的是gitåQŒå¯ä»¥æ˜¯git服务器(公司自己搭徏了一个git <a target="_self" style="word-break: break-all; color: #202859;"><u style="word-break: break-all;"><strong style="word-break: break-all;">server</strong></u></a>åQ‰ï¼Œä¹Ÿå¯ä»¥æ˜¯ä¸€ä¸ªbare repoåQˆhttp://www.saintsjd.com/2011/01/what-is-a-bare-git-repository/åQ?ã€?/div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">  2、CIåQˆcontinuous integrationåQ‰ã€‚我选的是部¾|²æ–¹ä¾Ñ€æ’件丰富的Jenkinsã€?/div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">  <strong style="word-break: break-all;">它的职责是:(x¨¬)</strong></div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">  åQ?åQ‰ä»Žgit上取å‡ÞZ»£ç ï¼ŒbuildåQ?NET对应msbuildåQŒå¦‚果是ruby则不用build了,直接部çÖv卛_¯åQ‰ï¼›</div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">  åQ?åQ‰æŠŠbuild好的*.dll部çÖvåQˆè¿™é‡Œå³æ˜¯æ‹·è´ï¼‰åˆ°æ‰€æœ‰çš„slave上;</div><div style="word-break: break-all; line-height: normal !important; margin: 10px 0px;">  åQ?åQ‰å¯åŠ¨æˆ–åœæ­¢æ‰€æœ‰slave上的AutomationServiceåQˆåŽé¢è¿˜ä¼?x¨¬)讲到AutomationServiceåQ‰ï¼Œä»Žè€ŒæŽ§åˆ¶æµ‹è¯•的执行ã€?span style="font-size: 11.818181991577148px; line-height: 21.60000228881836px;">我在Jenkins的这些个job配置èµäh¥˜q˜æ˜¯æ¯”较¾Jççš„,要细讲又可以另外写一½‹‡æ–‡äº†ã€‚这里就特别提到两个很实用的插äšg吧:(x¨¬)</span></div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; font-size: 11.818181991577148px;">  åQ?åQ‰Parameterized Trigger PluginåQˆhttps://wiki.jenkins-ci.org/display/JENKINS/Parameterized+Trigger+PluginåQ‰ï¼š(x¨¬)可以在一个build step中触发其它projectçš„buildã€?/div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; font-size: 11.818181991577148px;"><a target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/03/14982672_201403101350323MpQL.jpg" border="0" style="word-break: break-all; list-style: none outside none; margin: 0px; padding: 0px; border: none; max-width: 500px;" alt="" /></a></div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; font-size: 11.818181991577148px;">  它最有用的就是这ä¸?#8220;Block until the triggered projects finish their builds”选项åQŒå‹¾ä¸Šçš„话Jenkinsž®Þpƒ½åœ¨æ‰€æœ‰triggerçš„project完成build之后åQˆè€Œéžä»…ä»…trigger其它projectçš„buildåQŒä¸½{‰å®ƒä»¬å®Œæˆå°±¾l§ç®‹ä¸‹ä¸€ä¸ªbuild stepåQ‰å†¾l§ç®‹ä¸‹ä¸€ä¸ªbuild stepåQŒåšåˆ°çœŸæ­£çš„依次执行每个build stepã€?/div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; font-size: 11.818181991577148px;"><a target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/03/14982672_201403101350324cdMj.jpg" border="0" style="word-break: break-all; list-style: none outside none; margin: 0px; padding: 0px; border: none; max-width: 500px;" alt="" /></a></div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; font-size: 11.818181991577148px;">  åQ?åQ‰NodeLabel Parameter PluginåQˆhttps://wiki.jenkins-ci.org/display/JENKINS/NodeLabel+Parameter+PluginåQ‰ï¼š(x¨¬)在所æœ?#8220;Possible nodes”标有指定标签åQ?#8220;Label”åQ‰çš„Jenkins节点åQˆå°±æ˜¯Jenkins master或Jenkins slaveåQ‰ä¸Šè§¦å‘指定projectåQˆè¢«è§¦å‘çš„project是参数化的)ã€?/div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; font-size: 11.818181991577148px;">  比如我有一个projectå?#8220;StartClassicROLATServiceOnAllNodes”åQŒå®ƒæœ‰ä¸€ä¸ªbuild step是这栯‚®¾å®šçš„åQ?/div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; font-size: 11.818181991577148px;"><a target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/03/14982672_201403101350325p0dk.jpg" border="0" style="word-break: break-all; list-style: none outside none; margin: 0px; padding: 0px; border: none; max-width: 500px;" alt="" /></a></div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; font-size: 11.818181991577148px;">  再来看看“StartClassicROLATServiceOnASingleNode”˜q™ä¸ªproject的设定:(x¨¬)</div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; font-size: 11.818181991577148px;"><a target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/03/14982672_2014031013503261mEf.jpg" border="0" style="word-break: break-all; list-style: none outside none; margin: 0px; padding: 0px; border: none; max-width: 500px;" alt="" /></a></div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; font-size: 11.818181991577148px;">  ˜q™ä¸ªproject有一个Node¾cÕdž‹çš„参敎ͼŒå‚æ•°å?#8220;NodeX”与之前Label Factory中的“NodeX”对应åQ?#8220;Possible nodes”选的æ˜?#8220;ALL”åQŒé‚£ä¹ˆåˆ—出的所有nodeåQˆmasterã€?0.107.122.152ã€?0.107.122.153ã€?0.107.122.154åQ‰éƒ½åœ¨åˆ¤æ–­èŒƒå›´ä¹‹å†…(判断其是否有“Node”标签åQŒæœ‰åˆ™æ‰§è¡ŒprojectåQ‰ã€?/div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; font-size: 11.818181991577148px;">  另外åQŒåˆ—出的所有node我都为其加了一ä¸?#8220;Node”标签ã€?/div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; font-size: 11.818181991577148px;"><a target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/03/14982672_201403101350327qC46.jpg" border="0" style="word-break: break-all; list-style: none outside none; margin: 0px; padding: 0px; border: none; max-width: 500px;" alt="" /></a></div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; font-size: 11.818181991577148px;">  ˜q™æ ·åQŒå½“我trigger “StartClassicROLATServiceOnAllNodes”之后åQŒå°±ä¼?x¨¬)在masterã€?0.107.122.152ã€?0.107.122.153ã€?0.107.122.154˜q?个node上同时执è¡?#8220;StartClassicROLATServiceOnASingleNode”ã€?br /><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; font-size: 11.818181991577148px;"><strong style="word-break: break-all; line-height: normal !important;"> 3、AutomationDashboardåQŒè¿™é‡Œå§‘且译ä½?#8220;自动化测试控刉™¢æ?#8221;吧ã€?/strong>实际上它应该和Jenkinsä¸€èµ·åÆˆ¿U°æŽ§åˆ‰™¢æ¿ï¼Œä¸è¿‡å› äØ“(f¨´)Jenkins有API可以调用åQŒæ‰€ä»¥æƒ³åšçš„ç”ÖM¸¤è€…也是可以统一成一个web界面的。这个dashboard完全是用.NET+IIS+SQLServer一点点从数据库设计构徏、数据访问层、业务层、表现层做è“v来的åQŒè¦¾l†è®²……é¢?#8230;…又会(x¨¬)是另外一½‹‡æ–‡äº†ï¼ˆOh man, not again!åQ‰ã€‚反正我觉得åQŒè™½ç„¶æˆ‘是做自动化测试工作的åQŒä½†ä¸åº”该把自己局限于‹¹‹è¯•ã€‚äØ“(f¨´)了更好地˜q›è¡Œè‡ªåŠ¨åŒ–æµ‹è¯•ï¼Œå¼€å‘ç½‘ç«™ã€å®‰è£…é…¾|®è™šæ‹Ÿæœºä»¥åŠ(qi¨¢ng)其它要用到的工具åQŒéƒ½åº”该抽时间去学习(f¨¤n)、掌握ã€?/div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; font-size: 11.818181991577148px;">  好,来说说这个dashboard。这里只讲两个主要组成部分,一个网站(以下½Ž€¿U°dashboardåQ‰ã€ä¸€ä¸ªWindows ServiceåQˆä»¥ä¸‹ç®€¿U°ATServiceåQ‰å’Œä¸€ä¸ªconsole applicationåQˆä»¥ä¸‹ç§°ConsoleRunneråQ‰ï¼š(x¨¬)</div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; font-size: 11.818181991577148px;">  <strong style="word-break: break-all; line-height: normal !important;">åQ?åQ‰dashboardåQŒå®ƒçš„主要功能:(x¨¬)</strong></div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; font-size: 11.818181991577148px;">  a、展½Cºæµ‹è¯•çš„˜qè¡Œçж况åQšæœ‰å¤šå°‘æ­£åœ¨˜qè¡Œ/执行完毕åQŒåˆ†åˆ«åœ¨å“ªå°slave上执行等½{‰ã€?/div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; font-size: 11.818181991577148px;">  b、通过call Jenkinsçš„API来trigger Jenkinsçš„jobåQŒé—´æŽ¥æŽ§åˆ¶æµ‹è¯•的执行ã€?/div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; font-size: 11.818181991577148px;">  c、展½Cºæµ‹è¯•çš„¾l“æžœåQšå‘生错误的是哪个case、出错时间、错误信息、代码回溯(stack traceåQ‰ã€ç”šè‡›_¯ä»¥åŒ…含一张出错时的截图ã€?/div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; font-size: 11.818181991577148px;">  主要界面如下åQ?/div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; font-size: 11.818181991577148px;">  a、SummaryåQŒé¡¾åæ€ä¹‰æ˜¯æ±‡æ€ÖM¿¡æ¯ï¼Œcase有多ž®‘pass多少fail、case按分¾cÀL¯ä¸€¾cÀLœ‰å¤šå°‘½{‰ç­‰ã€‚(其实˜q™é‡Œæˆ‘少做了一张很重要的图åQŒå°±æ˜¯coverage饼状图)</div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; font-size: 11.818181991577148px;"><a target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/03/14982672_20140310135032827KJ.jpg" border="0" style="word-break: break-all; list-style: none outside none; margin: 0px; padding: 0px; border: none; max-width: 500px;" alt="" /></a></div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; font-size: 11.818181991577148px;">  b、QueueåQŒæµ‹è¯•队列,包含当前正在˜qè¡Œçš„、运行完的、等待运行的test fixture或test caseåQˆä¾æ®æµ‹è¯•å·¥å…ïL(f¨¥ng)š„不同åQŒNUnit、JUnit、RSpec½{‰ï¼Œfixture的叫法可能不同,æ€ÖM¹‹ž®±æ˜¯åŒ…含多个test case的集合)。可以启动、停止、终止(¾lˆæ­¢ä¹‹åŽå¯ä»¥æ¸…空åQ‰æµ‹è¯•执行或清空当前队列ã€?/div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; font-size: 11.818181991577148px;"><a target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/03/14982672_201403101350329deYC.jpg" border="0" style="word-break: break-all; list-style: none outside none; margin: 0px; padding: 0px; border: none; max-width: 500px;" alt="" /></a></div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; font-size: 11.818181991577148px;">  c、TestCaseåQŒç”Ÿæ€ç³»¾lŸä¸­çš„æ‰€æœ‰æµ‹è¯•用例会(x¨¬)展示在这里,可以看到它们最后一‹Æ¡æ‰§è¡Œçš„æ—‰™—´å’ŒçŠ¶æ€ï¼ˆpass/failåQ‰ï¼Œç‚¹å‡»æŸæ¡case可以跌™{到该条case的所有test result。可以按状态(pass/fail/otheråQ‰ç­›é€‰ç”¨ä¾‹ï¼Œå¯ä»¥å‹ùN€‰éƒ¨åˆ†ç”¨ä¾‹é‡æ–°æ‰§è¡Œã€æˆ–重新执行所有failçš„caseã€?#8220;Reload Test Cases”主要是考虑åˆ?.dllæ–‡äšg中的test case可能ä¼?x¨¬)在某次部çÖv之后发生变化åQŒéœ€è¦é‡æ–°åŠ è½½ã€‚ä¸˜q‡åŽæ¥æˆ‘修改了Jenkins里的job在每‹Æ¡éƒ¨¾|²ä¹‹åŽéƒ½è‡ªåŠ¨é‡æ–°åŠ è²åQŒæ‰€ä»¥è¿™ä¸ªæŒ‰é’®å…¶å®žæ²¡ä»€ä¹ˆç”¨äº†ã€?/div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; font-size: 11.818181991577148px;"><a target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/03/14982672_201403101350321010y4.jpg" border="0" style="word-break: break-all; list-style: none outside none; margin: 0px; padding: 0px; border: none; max-width: 500px;" alt="" /></a></div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; font-size: 11.818181991577148px;">  d、TestSuiteåQŒåŒ…含多个fixture的集合是一个suite。勾选多个suite点击“Run Suite”卛_¯æŠŠè¿™äº›suite中包含的fixtureæ·ÕdŠ åˆ°Queueã€?/div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; font-size: 11.818181991577148px;"><a target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/03/14982672_20140310135032111vpi.jpg" border="0" style="word-break: break-all; list-style: none outside none; margin: 0px; padding: 0px; border: none; max-width: 500px;" alt="" /></a></div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; font-size: 11.818181991577148px;">  ˜q™é‡Œçš„suite是对NUnit中的Category的一个补充,点击“New Suite”你可以ä“Q意选择fixture来组成自己想要的suiteåQ?/div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; font-size: 11.818181991577148px;"><a target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/03/14982672_2014031013503212Z8mE.jpg" border="0" style="word-break: break-all; list-style: none outside none; margin: 0px; padding: 0px; border: none; max-width: 500px;" alt="" /></a></div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; font-size: 11.818181991577148px;">  e、TestResultåQŒå±•½Cºæ‰€æœ‰test case的运行结果,可以按test case id˜q›è¡Œ½{›é€‰ï¼Œç‚¹å‡»TC#˜q™ä¸€åˆ—çš„idž®±åªæ˜„¡¤º˜q™æ¡case的结果ã€?/div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; font-size: 11.818181991577148px;"><a target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/03/14982672_20140310135032132kv4.jpg" border="0" style="word-break: break-all; list-style: none outside none; margin: 0px; padding: 0px; border: none; max-width: 500px;" alt="" /></a></div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; font-size: 11.818181991577148px;">  点右边的蓝色“i”图标可以跛_ˆ°˜q™æ¡¾l“果的详¾l†é¡µé¢ï¼Œæˆªå›¾åŠŸèƒ½æš‚æœªå¯ç”¨åQŒæ ¹æ®RunnerMessageå’ŒRunnerStackTrace可以知道报错的代码位¾|®ï¼Œ˜q›è€Œå°è¯•重现问题ã€?/div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; font-size: 11.818181991577148px;"><a target="_blank" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;"><img src="http://www.51testing.com/attachments/2014/03/14982672_2014031013503214aCLS.jpg" border="0" style="word-break: break-all; list-style: none outside none; margin: 0px; padding: 0px; border: none; max-width: 500px;" alt="" /><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; color: #333333; font-size: 11.818181991577148px;"> åQ?åQ‰ATService。这个Windows ServiceåQˆslave都是WindowsåQŒç¨åŽä¼š(x¨¬)è®ÔŒ¼‰è¢«å®‰è£…到了每个slave上,用以向dashboard询问“现在有没有分配给我的test fixture/caseåQ?#8221;åQŒå¦‚果有且当前slave½Iºé—²çš„话ž®±æŠ“˜q‡æ¥˜qè¡ŒåQŒè¿è¡Œå®Œæ¯•汇报结果ã€?/div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; color: #333333; font-size: 11.818181991577148px;">  ˜q˜è®°å¾—QueueåQˆé˜Ÿåˆ—)吧?无论你在TestCase˜q˜æ˜¯TestSuite™åµé¢æŒ‘选了test case/suite惌™¦˜qè¡ŒåQŒéƒ½åªæ˜¯æŠŠå®ƒä»¬æ·»åŠ åˆ°é˜Ÿåˆ—å½“ä¸­åQˆå‡†¼‹®åœ°è¯´å°±æ˜¯å¾€Queue˜q™å¼ æ•°æ®åº“表中INSERT记录åQ‰ï¼Œè€Œä¸ä¼?x¨¬)给它们分配slave。只有当Jenkins启动了slave上的ATService之后åQŒATService才会(x¨¬)去Queue表中自己抓取åQˆå°±æ˜¯æ‰“上标记说˜q™æ¡fixture/case已经有主了,其它slavež®×ƒ¸ä¼?x¨¬)再åŽÀLŠ“åQ‰è¿˜æ²¡æœ‰˜qè¡Œ˜q‡ä¸”没有分配有slaveçš„test fixture/caseã€?/div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; color: #333333; font-size: 11.818181991577148px;">  åQ?åQ‰ConsoleRunneråQŒæœ€å¼€å§‹çš„那个图中没有ç”Õd‡ºæ¥ã€‚这个console½E‹åºä¸»è¦ä¾›Jenkins调用。Jenkins不是可以让job定时˜qè¡Œä¹ˆï¼Ÿæ­£å¥½åQŒå®šæ—¶è°ƒç”¨è¿™ä¸ªconsole applicationåQŒä¼ å‡ ä¸ªå‚æ•°åQŒå°±å¯ä»¥åœ¨æŒ‡å®šæ—¶é—´å¾€Queue里填充f(xi¨¦)ixture/caseåQŒç„¶åŽå†å¯åЍATService开始执行测试。这样就能实现quick/daily/weekly/full regression的无人值守˜qè¡Œäº†ã€?/div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; color: #333333; font-size: 11.818181991577148px;"> <strong style="word-break: break-all; line-height: normal !important;"> 4、Slave</strong></div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; color: #333333; font-size: 11.818181991577148px;">  我选择在Windows上运行测试:(x¨¬)</div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; color: #333333; font-size: 11.818181991577148px;">  åQ?åQ‰å…¬å¸IT一般只提供Windows操作¾pȝ»Ÿçš„虚拟机</div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; color: #333333; font-size: 11.818181991577148px;">  åQ?åQ‰äñ”品在Windows上的用户占绝大多敎ͼˆå…¶å®ž˜q™ä¸ªæœ‰ç‚¹åºŸè¯åQŒæ¡Œé¢æ“ä½œç³»¾lŸWindows依然是世界王者。诚ç„Óž¼Œæˆ‘自å·×ƒ¸šä½™æ—¶ç”¨Linux做开发,Mac在国内外也是相当‹¹è¡Œçš„,但GoogleAnalytics昄¡¤ºçš„统计结果就是大部分讉K—®éƒ½æ¥è‡ªWindows。什么,你说iOS/AndroidåQŸé¢……¿UÕdŠ¨ç«¯çŽ°åœ¨ä»ç„¶æ˜¯äº§å“çš„çŸ­æ?#8230;…åQ?/div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; color: #333333; font-size: 11.818181991577148px;">  如果选择Linux的话要注意下selenium webdriverçš„native event讑֮šåQˆhttp://code.google.com/p/selenium/wiki/AdvancedUserInteractions#Native_events_versus_synthetic_eventsåQ‰ã€?/div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; color: #333333; font-size: 11.818181991577148px;">  关于‹¹è§ˆå™¨ï¼ŒFirefox、Chrome、IE皆可åQŒwebdriver的浏览器兼容性已¾lå¾ˆä¸é”™äº†ã€‚浏览器兼容性是个有点头疼的问题åQŒæƒ³æ”¯æŒå¾ˆå¤š‹¹è§ˆå™¨çš„话有时会(x¨¬)增加很多开发、测试成本,我一般在Firefox上跑ž®Þpƒö够了。什么?数字åQŸé©¬æ¡Óž¼Ÿä¼é¹…åQŸæ?zh¨¨n)¨æƒ›_¤šäº†ï¼Œselenium官方不支持ã€?/div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; color: #333333; font-size: 11.818181991577148px;">  你能扑ֈ°å¤šå°‘台slave来执行测试?多多益善哦!找不到那么多实体机就自己配虚拟机吧,分布式运行可以给你的自动化测试生态系¾lŸè£…上火½Ž­ï¼åœ¨æ›´çŸ­çš„æ—‰™—´å†…运行完更多‹¹‹è¯•åQŒä»Žè€Œæ›´å¿«åœ°ä»Žæµ‹è¯•中获得反馈åQ?/div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; color: #333333; font-size: 11.818181991577148px;">  嗯,差不多就˜q™ä¹ˆå¤šäº†ã€‚还有很多细节就留在之后的文中再说了。自我感觉这个生态系¾lŸè¿˜æ˜¯æœ‰å¾ˆå¤šå¯ä»¥å®Œå–„、增加的功能åQŒè€Œä¸”˜q™ä¸ªå®žçŽ°æ–¹å¼ã€è¿ä½œæœºåˆ¶å¯èƒ½ä¹Ÿòq‰™žé€‚用于你所‹¹‹è¯•çš„äñ”品,不过现在对于我测的äñ”品来说是够用的了ã€?/div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; color: #333333; font-size: 11.818181991577148px;">  不管怎样实现åQŒæˆ‘惌™¡¨è¾„¡š„核心观点是:(x¨¬)</div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; color: #333333; font-size: 11.818181991577148px;">  做自动化‹¹‹è¯•不要局限于自动化测试代码的¾~–写åQŒæˆ‘们要自动化的不仅仅是manual test caseåQŒè¿˜åº”包括整个automation testçš„processåQæµ‹è¯•代码持¾l­é›†æˆã€éƒ¨¾|ÔŒ¼ˆåˆ†å‘åQ‰ã€æ‰§è¡Œã€ç»“果展½Cºï¼Œè‡ªåŠ¨åŒ–çš„çŽ¯èŠ‚­‘Šå¤šã€è¶Šå½Õdº•åQŒäØ“(f¨´)你节¾U¦çš„æ—‰™—´ž®Þp¶Šå¤šï¼Œä½ å¯ä»¥ç”¨˜q™äº›èŠ‚çº¦çš„æ—¶é—´åšæ›´æœ‰æ„ä¹‰çš„äº‹æƒ…ã€‚äh¾cÕd‘明计½Ž—机åQŒç”¨ä»£ç ¾~–写½E‹åºåQŒå…¶å®žå°±æ˜¯ä¸€¿Uè‡ªåŠ¨åŒ–çš„è¿‡½E‹ã€‚以前要靠手工劳动完成的现在都交¾l™ç”µ(sh¨´)脑做äº?#8212;—服务器不正是勤勤æÏx³åœ°é‡å¤æ‰§è¡Œç€æˆ‘们写好的程序么åQŸæž„廸™‡ªåŠ¨åŒ–‹¹‹è¯•生态系¾lŸæ˜¯åŒæ ·çš„é“ç†ï¼Œå› äØ“(f¨´)机器能比人更可靠地完成重复劳动ã€?/div><div style="word-break: break-all; line-height: 21.60000228881836px; margin: 10px 0px; color: #333333; font-size: 11.818181991577148px;">  如果你还在手动拷è´?.dllåQŒè¿˜éœ€è¦æ‰“å¼€NUnit手动执行‹¹‹è¯•åQŒè¿˜åœ?台机器上˜qè¡Œ‹¹‹è¯•åQŒé‚£ä¹ˆï¼ŒçŽ°åœ¨ž®±æ˜¯è¯¥æé«˜ç”Ÿäº§åŠ›çš„æ—¶å€™äº†åQ?/div></a></div></div></div><img src ="http://www.aygfsteel.com/qileilove/aggbug/410968.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/qileilove/" target="_blank">™åºå…¶è‡ªç„¶EVO</a> 2014-03-13 11:34 <a href="http://www.aygfsteel.com/qileilove/archive/2014/03/13/410968.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>操作¾pȝ»Ÿä¸­å†…存管理的™åµé¢¾|®æ¢½Ž—法http://www.aygfsteel.com/qileilove/archive/2013/11/01/405876.html™åºå…¶è‡ªç„¶EVO™åºå…¶è‡ªç„¶EVOFri, 01 Nov 2013 02:37:00 GMThttp://www.aygfsteel.com/qileilove/archive/2013/11/01/405876.htmlhttp://www.aygfsteel.com/qileilove/comments/405876.htmlhttp://www.aygfsteel.com/qileilove/archive/2013/11/01/405876.html#Feedback0http://www.aygfsteel.com/qileilove/comments/commentRss/405876.htmlhttp://www.aygfsteel.com/qileilove/services/trackbacks/405876.html  考虑下述™åµé¢èµ°å‘åQ?/strong>
  1åQ?åQ?åQ?åQ?åQ?åQ?åQ?åQ?åQ?åQ?åQ?åQ?åQ?åQ?åQ?åQ?åQ?åQ?åQ?
  当内存块数量分别ä¸?æ—Óž¼Œè¯•é—®FIFO、LRU、OPT˜q™ä¸‰¿Uç½®æ¢ç®—法的¾~ºé¡µ‹Æ¡æ•°å„是多少?
  ½{”:(x¨¬)¾~ºé¡µå®šä¹‰ä¸ºæ‰€æœ‰å†…存块最初都是空的,所以第一‹Æ¡ç”¨åˆ°çš„™åµé¢éƒ½äñ”生一‹Æ¡ç¼º™åüc(di¨£n)€?/div>
  当内存块数量ä¸?æ—Óž¼š(x¨¬)
  发生¾~ºé¡µä¸­æ–­çš„æ¬¡æ•îCØ“(f¨´)16ã€?/div>
  在FIFO½Ž—法中,先进入内存的™åµé¢è¢«å…ˆæ¢å‡ºã€‚当™å?要调入时åQŒå†…å­˜çš„çŠ¶æ€äØ“(f¨´)4ã€?ã€?åQŒè€ƒæŸ¥™å?之前调入的页面,分别ä¸?ã€?ã€?ã€?åQŒå¯è§?为最先进入内存的åQŒæœ¬‹Æ¡åº”换出åQŒç„¶åŽæŠŠ™å?调入内存ã€?/div>
  发生¾~ºé¡µä¸­æ–­çš„æ¬¡æ•îCØ“(f¨´)15ã€?/div>
  在LRU½Ž—法中,最˜q‘最ž®‘ä‹É用的™åµé¢è¢«å…ˆæ¢å‡ºã€‚当™å?要调入时åQŒå†…å­˜çš„çŠ¶æ€äØ“(f¨´)5ã€?ã€?åQŒè€ƒæŸ¥™å?之前调入的页面,分别ä¸?ã€?ã€?åQŒå¯è§?为最˜q‘一ŒD‰|—¶é—´å†…使用最ž®‘çš„åQŒæœ¬‹Æ¡åº”换出åQŒç„¶åŽæŠŠ™å?调入内存ã€?/div>
  发生¾~ºé¡µä¸­æ–­çš„æ¬¡æ•îCØ“(f¨´)11ã€?/div>
  在OPT½Ž—法中,在最˜qœçš„ž®†æ¥æ‰è¢«è®‰K—®çš„页面被先换出。当™å?要调入时åQŒå†…å­˜çš„çŠ¶æ€äØ“(f¨´)1ã€?ã€?åQŒè€ƒæŸ¥™å?后面要调入的™åµé¢åQŒåˆ†åˆ«äØ“(f¨´)2ã€?ã€?ã€?#8230;åQŒå¯è§?为最˜q‘一ŒD‰|—¶é—´å†…使用最ž®‘çš„åQŒæœ¬‹Æ¡åº”换出åQŒç„¶åŽæŠŠ™å?调入内存ã€?/div>
  OPT½Ž—æ³•å› äØ“(f¨´)要知道后面请求的™å‰|¡†åQŒå› æ­¤æˆ‘觉得˜q™ä¸ª½Ž—法有个ž®å°çš„bug,如果在某个请求中åQŒè‹¥åœ¨è¯¥è¯äh±‚的页框之后的™å‰|¡†åºåˆ—中至ž®‘存在一个和当前内存块中不匹配的™å‰|¡†åQŒåˆ™æŒ‰ç…§å†…存块的™åºåºåQˆä»Žä¸Šå¾€ä¸‹ï¼‰æ›¿æ¢æ²¡æœ‰å‡ºçŽ°çš„é¡µæ¡†ã€‚æ¯”å¦‚ä¸Šé¢é‚£ä¸ªOPTä¾‹å­ã€‚å¯¹äºŽæœ€åŽä¸€ä¸ªé¡µæ¡†è¯·æ±‚ï¼Œå› äØ“(f¨´)6未命中,ä¸?之后没有è¯äh±‚的序列,因此应该替换3åQŒæ‰€ä»¥æ›¿æ¢åŽçš„åºåˆ—äØ“(f¨´)6 åQ?2 åQ?   当然åQŒè¿™åªæ˜¯é’ˆå¯¹åšé¢˜è€Œè¨€ã€?/div>

]]>™å¹ç›®å®žæˆ˜½W”记之六åQšå›¢é˜Ÿå¾è®„¡š„三种境界http://www.aygfsteel.com/qileilove/archive/2013/06/04/400153.html™åºå…¶è‡ªç„¶EVO™åºå…¶è‡ªç„¶EVOTue, 04 Jun 2013 02:32:00 GMThttp://www.aygfsteel.com/qileilove/archive/2013/06/04/400153.htmlhttp://www.aygfsteel.com/qileilove/comments/400153.htmlhttp://www.aygfsteel.com/qileilove/archive/2013/06/04/400153.html#Feedback0http://www.aygfsteel.com/qileilove/comments/commentRss/400153.htmlhttp://www.aygfsteel.com/qileilove/services/trackbacks/400153.html ¾lè¿‡è‡ªå·±æ€È»“和项目经理们探讨åQŒè®¤ä¸ºé¡¹ç›®æˆ–éƒ¨é—¨å›¢é˜Ÿå»ø™®¾å¯åˆ†ä¸ÞZ¸‰ä¸ªç­‰¾U§ï¼š(x¨¬)

  一、乌合之众,强权政治åQˆæ–°æ‰‹ï¼‰

  很多新手都会(x¨¬)¾låކ˜q™æ ·çš„过½E‹ï¼Œæ–°ç»„建的团队冲突不断åQŒå¤§å®¶å¯¹å½“各¿Uåˆ¶åº¦æŽªæ–½ï¼ŒæŠ¥ä»¥åæ„Ÿã€‚䨓(f¨´)保证执行力和™å¹ç›®æˆåŠŸåQŒé¡¹ç›®ç»ç†ä¼š(x¨¬)选择强权压制åQŒå°¤å…¶æ˜¯æŠ€æœ¯æ¯”较好的项目经理。大æŠëŠš„逻辑æ˜?#8220;我是老大òq¶ä¸”我资深,要听我的”。最¾lˆçš„¾l“果是大家对™å¹ç›®ç›®æ ‡å·²ç»å®Œå…¨ä¸æ„Ÿå…´è¶£åQŒä¸€äº›å†²½Hå‡¾U§åˆ°ä¸ªäh情感冲突åQŒé¡¹ç›®ç»ç†å·¦å³çªå‡»ï¼Œä¸Šè¹¿ä¸‹èŸ©åQŒç”šæ˜¯è¾›è‹¦ï¼Œå¿™ç¢ŒåQŒç¡®å¾—不到大家的认可ã€?/p>

  此时的项目经理至ž®‘需要做åˆîC¸¤ç‚¹ï¼Œæ‰æœ‰å¯èƒ½˜q›å…¥ä¸‹ä¸ªé˜¶æ®µåQŒç”¨æ°å…‹éŸ¦å°”奇的两句话概况:(x¨¬)

  1ã€?#8220;åœ¨ä½ æˆäØ“(f¨´)领导以前åQŒæˆåŠŸåªåŒè‡ªå·Þqš„æˆé•¿æœ‰å…³ã€‚当你成为领å¯ég»¥åŽï¼ŒæˆåŠŸéƒ½åŒåˆ«äh的成长有兟ë€?#8221;

  2ã€?#8220;世界上的每一个äh都想得到发言权和ž®Šä¸¥åQŒè€Œä¸”也应当得åˆ?#8221;

  所è°?#8220;发言æ?#8221;åQŒæ˜¯æŒ‡äh们希望有æœÞZ¼š(x¨¬)说出他们的思想åQŒæ‹¥æœ‰è‡ªå·Þqš„观点、看法、获得被們֐¬çš„æ„Ÿå—,无论他们的国¾cã€æ€§åˆ«ã€å¹´é¾„或者文化背景如何ã€?/p>

  所è°?#8220;ž®Šä¸¥”åQŒæ˜¯æŒ‡äh们本能地和自发地希望ç”׃ºŽè‡ªå·±çš?a href="" target="_self" style="word-break: break-all; color: #202859; text-decoration: none; line-height: normal !important;">工作、努力和个性而得到尊重ã€?/p>

  ˜q™ä¸ªé˜¶æ®µä¹‹æ‰€ä»¥å‘½åäØ“(f¨´)乌合之众åQŒæ˜¯å› äØ“(f¨´)大家对团队根本没有归属感åQŒç”šè‡›_ŽŒå¼ƒå›¢é˜Ÿï¼ŒæœŸæœ›å›¢é˜Ÿå¾—åˆ°è§£æ•£åQŒæˆ–者团队目标达成时åQŒåƈ没有取得成就的感觉,而是有终于熬˜q‡æ¥çš„æ„Ÿè§¦ã€?/p>

  二、尊重,民主½C¾ä¼š(x¨¬) åQˆè€æ‰‹åQ?/strong>

  在经历过挫折或是老前辈们的谆谆教导后åQŒæ–°æ‰‹å¾€å¾€éƒ½èƒ½˜q›å…¥˜q™ä¸ªé˜¶æ®µã€‚当然有些厉害的人有时也ä¼?x¨¬)自å·ÞpŸ©åˆ°è¿™ä¸ªé˜¶ŒDüc(di¨£n)€‚但是这个阶ŒDµé‡Œçš„ähåQŒä¹Ÿæœ‰é«˜ä¸‹ä¹‹åˆ†ã€‚在˜q™ä¸ªé˜¶æ®µçš„ähåQŒå¾€å¾€å¯ä»¥å¸¦å›¢é˜Ÿæ—¶åQŒå¾€å¾€å¯ä»¥åšåˆ°åQ?/p>

  1、尊重,­a€è·¯å¼€æ˜?/p>

  不把人当做机器。制定计划,措施æ—Óž¼Œéƒ½å¯ä»¥å¾æ±‚的大家意见åQŒå½“然计划定下来后,执行时是不能含糊的ã€?/p>

  2、善用äh才,培养人才

  团队里有人才æ—Óž¼Œä¼?x¨¬)ä‹É用授权等方式调用˜q™äº›äººçš„¿U¯æžæ€§ï¼Œè€Œä¸æ˜¯å¹¼½Ešçš„æ‰“压åQŒåƈ且在团队里没有äh才时åQŒèƒ½å¤Ÿç§¯æžé€‰æ‹”备选äh员,òq¶ç»™äºˆé”»ç‚¼æœºä¼?/p>

  3、分享荣�/p>

  ˜q™ä¸ªé˜¶æ®µçš„项目经理,在交‹¹ä¸­åQŒä¼š(x¨¬)摈弃æŽ?#8220;æˆ‘æ€Žä¹ˆæ øP¼Œæ€Žä¹ˆæ ?#8221;åQŒå¤šä½¿ç”¨“我们åQŒæˆ‘们团队怎么æ ?#8221;åQŒå°¤å…¶æ˜¯åœ¨é¢å¯¹è¡¨æ‰¬å’Œè£èª‰æ—¶ã€‚在™å¹ç›®¾l„内也想方设法树(w¨¨i)ç«‹æ¦œæ øP¼Œòq¶ä¸”非常愿意˜q™äº›äºø™¢«è‡ªå·±çš„上¾U§æ‰€èŽïL(f¨¥ng)Ÿ¥åQŒæ„¿æ„äØ“(f¨´)˜q™äº›äºø™°‹ä¸ªå¥½å‰ç¨‹ã€?/p>

  4、坦�/p>

  坦诚是相处的长远之计åQŒè€Œå¿½æ‚(zh¨¨n) ï¼Œç”Õd¤§é¥ÆD¿™äº›æ‰‹ŒDµåªèƒ½çŸ­æœŸæ•ˆåº”,òq¶åœ¨é•¿æœŸä¸Šè®©è‡ªå·±çš„äh格受损。关于这炚w¡¹ç›®ç»ç†å¤§å¤šåšå¾—程度不一åQŒæœ‰æ—¶è¯´å‡ÞZ¸€äº›ä¸å¼€å¿ƒçš„事,是需要勇气的åQŒä¾‹å¦‚在¾l©æ•ˆæ²Ÿé€šæ—¶ã€‚但是这个阶ŒD늚„™å¹ç›®¾lç†éƒ½äº†è§£å®ƒé‡è¦æ€§ã€?/p>

  5、团队信息透明

  只有信息­‘›_¤Ÿé€æ˜ŽåQŒå¤§å®¶æ‰èƒ½å¤Ÿä¸ºé¡¹ç›®å‡ºè°‹åˆ’½{–,才能有坦诚沟通的基础åQŒå¤§å®¶æ‰èƒ½å¯¹™å¹ç›®å½’属ã€?#8220;垄断信息åQŒä»¥æ˜„¡¤ºè‡ªå·±é¢†å¯¼çš„地ä½?#8221;是愚蠢的人才ä¼?x¨¬)干的事æ?/p>

  ˜q™ä¸ªé˜¶æ®µä¹‹æ‰€ä»¥å‘½åäØ“(f¨´)民主½C¾ä¼š(x¨¬)åQŒè¿™ä¸ªé˜¶ŒD늚„价倯D§‚是:(x¨¬)民主计划åQŒä¸¥æ ¼æ‰§è¡Œï¼Œæœ‰ä»˜å‡ºæœ‰å›žæŠ¥åQŒé›†ä½“荣誉。第一个阶ŒDµåˆ°½W¬äºŒä¸ªé˜¶ŒDµå¯èƒ½éœ€è¦æ—¶é—´çš„¿U¯ç¯åQŒè€Œç¬¬äºŒä¸ªé˜¶æ®µåˆ°ç¬¬ä¸‰ä¸ªé˜¶æ®µåQŒæœ‰æ—¶å´å¯æœ›è€Œä¸å¯è¾¾ã€?/p>

  三、激情,燃烧军团 åQˆé«˜æ‰‹ï¼‰

  ‹È€æƒ…团队的充分必要前提是,团队负责人是非常有激情的。这点很关键åQŒä¸€ä¸ªæ‰“工者心态,没有把工作当成自å·×ƒº‹ä¸šç»è¥çš„人是不会(x¨¬)带出有长久激情的团队。检视的原理åQ?#8220;看一下大家是不是ä¸ÞZº†åŒä¸€ä¸ªæ¢¦æƒŒ™€Œèµ°åˆîC¸€èµïL(f¨¥ng)š„”

  要达成团队激情,臛_°‘具备以下几点åQ?/p>

  1、老板风格åQŒè€æ¿è¦æœ‰åˆ†äín成功的决心,例如åQšè‚¡¼œ¨ï¼ŒæœŸæƒ‹È€åŠ?/p>

  2、企业文化,企业要有文化宣扬集体奋斗的精¼œžï¼Œä¼ä¸šçš„ä‹É命ä­h(hu¨¢n)倯D§‚能够深入人心åQŒå¾—到强烈响应,此时企业的创新精¼œžï¼Œž®†æ˜¯ä»Žå†…而外的,从下而上的,大家集体思考,集体˜q›æ­¥åQŒé›†ä½“创新ã€?/p>

  3、有‹È€æƒ…的中层åQŒå…¬åæ€¸­å±‚是企业的中‹¹ç ¥æŸ±ï¼Œå¦‚果每个中层是有‹È€æƒ…çš„åQŒæ‰©æ•£å¼€æ¥çš„影响力是很大的,反之åQŒåˆ™‹È€æƒ…容易变成口受÷€?/p>

  ˜q™é‡Œå…¸åž‹çš„æ¡ˆä¾‹æ˜¯sony的没落,从井深大的激情军团的消失åQŒäº•深大倡导”工作保证本èínž®±æ˜¯ä¸€¿Uå¼ºæœ‰åŠ›çš„æ¿€åŠ?#8220;åQŒæŠŠ˜q™ç§ç†å¿µèƒ½å¤Ÿæ·±æ¤å…¬å¸æ˜¯å¤šä¹ˆå¯æ€•,‹È€æƒ…可以创造出很多奇迹ã€?/p>

  ¾U¦ç¿°·¿U‘特说过“如果你想建造一艘船åQŒé¦–先要做的不是去采集木材、加工木板和分派工作åQŒè€Œåº”该去唤è“väºÞZ»¬å¯¹å¹¿é˜”无垠大‹¹ïL(f¨¥ng)š„向往ã€?#8220; ½Ž¡ç†è€…的本质是获得追随的人,一个企业,一个团队如果能够拥有一æ‰ÒŽ(gu¨©)„¿æ„è¿½éšå…¬å¸æˆé•¿çš„人,所产生的正向能量是无比巨大的ã€?/p>

  ˜q™ç§å¢ƒç•Œçš„达到需要多方因素的促合åQŒé¢‡ä¼égºŽæ­¦ä¾ é‡Œçš„天äh合一åQŒæ¿€æƒ…团队的½Ž¡ç†ž®†ååˆ†ç®€å•,保护˜q™ç§‹È€æƒ…,员工ä¼?x¨¬)很自主的进行自我管理ã€?/p>

  当然实际工作中,以上每个阶段不孤立存在,可能ä¼?x¨¬)存在一些阶ŒD늚„中间体ã€?/p>

相关链接åQ?/p>

™å¹ç›®å®žæˆ˜½W”记之一åQšé«˜æ•ˆä¼š(x¨¬)议的¾l„织æ–ÒŽ(gu¨©)³•

™å¹ç›®å®žæˆ˜½W”记之二åQšé£Žé™©ç®¡ç?/a>

™å¹ç›®å®žæˆ˜½W”记之三åQšæ—¶é—´ä¼°½Ž—的三步æ›?/a>

™å¹ç›®å®žæˆ˜½W”记之四åQšå›¢é˜Ÿå¾è®¾ï¼ˆž®Šé‡åQ?/a>

™å¹ç›®å®žæˆ˜½W”记之五åQšé‡Œ½E‹ç¢‘½Ž¡ç†



]]>
跟屌丝大哥学ä¹?f¨¤n)设计模式-抽象工厂模å¼?/title><link>http://www.aygfsteel.com/qileilove/archive/2012/12/21/393318.html</link><dc:creator>™åºå…¶è‡ªç„¶EVO</dc:creator><author>™åºå…¶è‡ªç„¶EVO</author><pubDate>Fri, 21 Dec 2012 08:26:00 GMT</pubDate><guid>http://www.aygfsteel.com/qileilove/archive/2012/12/21/393318.html</guid><wfw:comment>http://www.aygfsteel.com/qileilove/comments/393318.html</wfw:comment><comments>http://www.aygfsteel.com/qileilove/archive/2012/12/21/393318.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/qileilove/comments/commentRss/393318.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/qileilove/services/trackbacks/393318.html</trackback:ping><description><![CDATA[<div><strong>1.3 æŠ½è±¡å·¥åŽ‚åQˆAbstract FactoryåQ‰æ¨¡å¼?br /></strong>    抽象工厂模式可以向客æˆïL(f¨¥ng)«¯æä¾›ä¸€ä¸ªæŽ¥å£ï¼Œä½¿å¾—客户端在不必指定产品具体¾cÕdž‹çš„æƒ…况下åQŒåˆ›å»ºå¤šä¸ªäñ”品族中的产品对象。这ž®±æ˜¯æŠ½è±¡å·¥åŽ‚æ¨¡å¼çš„ç”¨æ„ã€?br />    每个模式都是针对一定问题的解决æ–ÒŽ(gu¨©)¡ˆã€‚抽象工厂模式面对的问题是多产品½{‰çñ”¾l“构的系¾lŸè®¾è®¡ã€?br />    在学ä¹?f¨¤n)抽象工厂具体实例之前,应该明白两个重要的概念ï¼?x¨¬)产品族和产品½{‰çñ”ã€?br />    产品族:(x¨¬)是指位于不同产品½{‰çñ”¾l“构中,功能相关联的产品¾l„成的家族。比如AMDçš„CPUå’ŒADM芯片的主板,¾l„成一个家族。Intelçš„CPUå’?Intel芯片的主板,又组成一个家族。而这两个家族都来自于两个产品½{‰çñ”åQšCPUåQŒä¸»æÑ€‚一个等¾U§ç»“构是ç”Þq›¸åŒçš„¾l“构的äñ”品组成,½Cºæ„å›‘Ö¦‚下:(x¨¬)</div><img alt="" src="http://www.aygfsteel.com/images/blogjava_net/qileilove/aaa1165334942718.png" height="332" width="508" /><br /><br /><br /><div><br />    理解˜q™ä¸ªäº§å“¾l“构是理解抽象工厂模式的关键所在,所以我不惜èŠÞp´¹æ—‰™—´æ¥ç”»æ­¤å›¾ã€‚如果领æ‚(zh¨¨n)Ÿä¸åˆ°æ­¤å›„¡š„含义åQŒå°±æ— æ³•区分工厂æ–ÒŽ(gu¨©)³•模式和抽象工厂模式的区别ã€?br />    从上囑֏¯ä»¥çœ‹å‡ºï¼ŒæŠ½è±¡å·¥åŽ‚æ¨¡å¼çš„æ¯ä¸ªå·¥åŽ‚åˆ›é€ å‡ºæ¥çš„éƒ½æ˜¯ä¸€æ—äñ”品,而不是一个或者一¾l„。组是可以随意组合的åQå…¶å®žä¸¤ä¸ªå°±˜q™ç‚¹ç‚¹å·®åˆ«ï¼Œå‘µå‘µåQŒä¼°è®¡çŽ°åœ¨ä½ å·²ç»å·®ä¸å¤šæ˜Žç™½äº†æŠ½è±¡å·¥åŽ‚æ¨¡å¼çš„å«ä¹‰ã€‚ä¸åºŸè¯äº†ï¼Œçœ‹ä¸ªä¾‹å­åQŒçœŸç›¸å°†å¤§ç™½äºŽå¤©ä¸‹ï¼<br /> <div><strong>1.3.1 æŠ½è±¡å·¥åŽ‚æ¨¡å¼åœ¨å†œåœÞZ¸­çš„实çŽ?/strong></div> <div><br /><strong>1.3.1.1 èƒŒæ™¯</strong></div> <div><br />    聪明的农åœÞZ¸»æ€ÀL˜¯è®©è‡ªå·Þqš„庄园­‘Šæ¥­‘Šæœ‰ä»·å€û|¼Œ“农场”在经历了½Ž€å•工厂模式和工厂模式后,不断的扩大生产。如今,再次面äÍ(f¨´)新的大发展,一™åšw‡è¦çš„工作ž®±æ˜¯ 引进塑料大棚技术,在大‹‚šé‡Œ¿Uæ¤çƒ­å¸¦åQˆTropicalåQ‰å’Œäºšçƒ­å¸¦ï¼ˆNorthernåQ‰çš„æ°´æžœå’Œè”¬èœï¼Œç”¨ä»¥æ»¡èƒö市场需求,获取更大的利益ã€?/div> <div><br /><strong>1.3.1.2 äº§å“è§’色å›?/strong></div> <div><br />    ¾lè¿‡åˆ†æžåQŒå¯¹äº§å“è§’色˜q›è¡Œåˆ†æžå¾—出下图</div></div><img alt="" src="http://www.aygfsteel.com/images/blogjava_net/qileilove/abb1165335033921.png" height="231" width="428" /><br /><br /><div>    ¾lè¿‡åˆ†æžåQŒæ‰€è°“的各个园丁其实ž®±æ˜¯å·¥åŽ‚è§’è‰²åQŒè€Œè”¬èœå’Œæ°´æžœåˆ™æ˜¯äº§å“è§’色。将抽象工厂模式用于农场中,¾pȝ»Ÿè®¾è®¡å›‘Ö¦‚下:(x¨¬)<br /><br /><img alt="" src="http://www.aygfsteel.com/images/blogjava_net/qileilove/caa1165384624477.png" height="421" width="632" /><br /><br /><div>1.3.1.4.1 æŠ½è±¡å·¥åŽ‚åQšGardener.java <div>package com.lavasoft.patterns.abstractfactory.ybms;</div> <div>/**<br /> * Created by IntelliJ IDEA.<br /> * FileName:Gardener.java<br /> * User:    LavaSoft<br /> * Date:    2006-12-5<br /> * Time:    22:55:23<br /> * 《Java与模式》(--阎宏博士著)è¯ÖM¹¦½W”è®°<br /> * 工厂模式--抽象工厂模式--一般性模式(农场应用åQ?br /> * ReadMe:  抽象工厂角色åQšå·¥åŽ‚æŽ¥å?br /> */<br />public interface Gardener {</div> <div>    public Fruit createFruit(String name);</div> <div>1.3.1.4.2 æŠ½è±¡æ°´æžœäº§å“åQšFruit.java</div> <div>package com.lavasoft.patterns.abstractfactory.ybms;</div> <div>/**<br /> * Created by IntelliJ IDEA.<br /> * FileName:Fruit.java<br /> * User:    LavaSoft<br /> * Date:    2006-12-5<br /> * Time:    22:54:15<br /> * 《Java与模式》(--阎宏博士著)è¯ÖM¹¦½W”è®°<br /> * 工厂模式--抽象工厂模式--一般性模式(农场应用åQ?br /> * ReadMe:  抽象产品角色åQšæ°´æžœæŽ¥å?br /> */<br />public interface Fruit {<br />}</div> <div>1.3.1.4.3 æŠ½è±¡è”¬èœäº§å“åQšVeggie.java<br />package com.lavasoft.patterns.abstractfactory.ybms;</div> <div>/**<br /> * Created by IntelliJ IDEA.<br /> * FileName:Veggie.java<br /> * User:    LavaSoft<br /> * Date:    2006-12-5<br /> * Time:    22:56:22<br /> * 《Java与模式》(--阎宏博士著)è¯ÖM¹¦½W”è®°<br /> * 工厂模式--抽象工厂模式--一般性模式(农场应用åQ?br /> * ReadMe:  抽象产品角色åQšè”¬èœæŽ¥å?br /> */<br />public interface Veggie {<br />}</div> <div>1.3.1.4.4 çƒ­å¸¦æ°´æžœåQšTropicalFruit.java<br />package com.lavasoft.patterns.abstractfactory.ybms;</div> <div>/**<br /> * Created by IntelliJ IDEA.<br /> * FileName:TropicalFruit.java<br /> * User:    LavaSoft<br /> * Date:    2006-12-5<br /> * Time:    22:57:08<br /> * 《Java与模式》(--阎宏博士著)è¯ÖM¹¦½W”è®°<br /> * 工厂模式--抽象工厂模式--一般性模式(农场应用åQ?br /> * ReadMe:  具体产品角色åQšçƒ­å¸¦æ°´æž?br /> */<br />public class TropicalFruit implements Fruit {<br />    private String name;</div> <div>}</div> <div>1.3.1.4.5 çƒ­å¸¦è”¬èœåQšTropicalVeggie.java<br />package com.lavasoft.patterns.abstractfactory.ybms;</div> <div>/**<br /> * Created by IntelliJ IDEA.<br /> * FileName:TropicalVeggie.java<br /> * User:    LavaSoft<br /> * Date:    2006-12-5<br /> * Time:    22:58:03<br /> * 《Java与模式》(--阎宏博士著)è¯ÖM¹¦½W”è®°<br /> * 工厂模式--抽象工厂模式--一般性模式(农场应用åQ?br /> * ReadMe:  具体产品角色åQšçƒ­å¸¦è”¬è?br /> */<br />public class TropicalVeggie implements Veggie {<br />    private String name;</div> <div>    public TropicalVeggie(String name) {<br />        System.out.println("热带工厂为æ?zh¨¨n)¨åˆ›å¾äº†ï¼?x¨¬)热带水果åQ?+name);<br />    }</div> <div>}</div> <div>1.3.1.4.6 äºšçƒ­å¸¦æ°´æžœï¼š(x¨¬)NorthernFruit.java<br />package com.lavasoft.patterns.abstractfactory.ybms;</div> <div>/**<br /> * Created by IntelliJ IDEA.<br /> * FileName:NorthernFruit.java<br /> * User:    LavaSoft<br /> * Date:    2006-12-5<br /> * Time:    22:58:55<br /> * 《Java与模式》(--阎宏博士著)è¯ÖM¹¦½W”è®°<br /> * 工厂模式--抽象工厂模式--一般性模式(农场应用åQ?br /> * ReadMe:  具体产品角色åQšäºšçƒ­å¸¦æ°´æžœ<br /> */<br />public class NorthernFruit implements Fruit {<br />    private String name;</div> <div>    public NorthernFruit(String name) {<br />        System.out.println("äºšçƒ­å¸¦å·¥åŽ‚äØ“(f¨´)æ‚(zh¨¨n)¨åˆ›å»ÞZº†åQšäºšçƒ­å¸¦æ°´æžœåQ?+name);<br />    }</div> <div>}</div> <div><br />1.3.1.4.7 äºšçƒ­å¸¦è”¬èœï¼š(x¨¬)NorthernVeggie.java<br />package com.lavasoft.patterns.abstractfactory.ybms;</div> <div>/**<br /> * Created by IntelliJ IDEA.<br /> * FileName:NorthernVeggie.java<br /> * User:    LavaSoft<br /> * Date:    2006-12-5<br /> * Time:    22:59:36<br /> * 《Java与模式》(--阎宏博士著)è¯ÖM¹¦½W”è®°<br /> * 工厂模式--抽象工厂模式--一般性模式(农场应用åQ?br /> * ReadMe:  具体产品角色åQšäºšçƒ­å¸¦è”¬èœ<br /> */<br />public class NorthernVeggie implements Veggie {<br />    private String name;</div> <div>    public NorthernVeggie(String name) {<br />        System.out.println("äºšçƒ­å¸¦å·¥åŽ‚äØ“(f¨´)æ‚(zh¨¨n)¨åˆ›å»ÞZº†åQšäºšçƒ­å¸¦è”¬èœåQ?+name);<br />    }</div> <div>}</div> <div>1.3.1.4.8 çƒ­å¸¦å·¥åŽ‚åQšTropicalGardener.java<br />/**<br /> * Created by IntelliJ IDEA.<br /> * FileName:TropicalGardener.java<br /> * User:    LavaSoft<br /> * Date:    2006-12-5<br /> * Time:    23:01:49<br /> * 《Java与模式》(--阎宏博士著)è¯ÖM¹¦½W”è®°<br /> * 工厂模式--抽象工厂模式--一般性模式(农场应用åQ?br /> * ReadMe:  具体工厂角色åQšçƒ­å¸¦å·¥åŽ?br /> */<br />public class TropicalGardener implements Gardener {<br />    public Fruit createFruit(String name) {<br />        return new TropicalFruit(name);<br />    }</div> <div>    public Veggie createVeggie(String name) {<br />        return new TropicalVeggie(name);<br />    }<br />}</div> <div>1.3.1.4.9 äºšçƒ­å¸¦å·¥åŽ‚ï¼š(x¨¬)NorthernGardener.java<br />package com.lavasoft.patterns.abstractfactory.ybms;</div> <div>/**<br /> * Created by IntelliJ IDEA.<br /> * FileName:NorthernGardener.java<br /> * User:    LavaSoft<br /> * Date:    2006-12-5<br /> * Time:    23:00:31<br /> * 《Java与模式》(--阎宏博士著)è¯ÖM¹¦½W”è®°<br /> * 工厂模式--抽象工厂模式--一般性模式(农场应用åQ?br /> * ReadMe:  具体工厂角色åQšäºšçƒ­å¸¦å·¥åŽ‚<br /> */<br />public class NorthernGardener implements Gardener {<br />    public Fruit createFruit(String name) {<br />        return new NorthernFruit(name);<br />    }</div> <div>    public Veggie createVeggie(String name) {<br />        return new NorthernVeggie(name);<br />    }<br />}</div> <div></div> <div>1.3.1.4.10 ‹¹‹è¯•¾c»ï¼ˆå®¢æˆ·ç«¯ï¼‰åQšTestApp.java<br />package com.lavasoft.patterns.abstractfactory.ybms;</div> <div>/**<br /> * Created by IntelliJ IDEA.<br /> * FileName:TestApp.java<br /> * User:    LavaSoft<br /> * Date:    2006-12-5<br /> * Time:    23:03:22<br /> * 《Java与模式》(--阎宏博士著)è¯ÖM¹¦½W”è®°<br /> * 工厂模式--抽象工厂模式--一般性模式(农场应用åQ?br /> * ReadMe:  ‹¹‹è¯•¾c»ï¼ˆå®¢æˆ·ç«¯ï¼‰<br /> */<br />public class TestApp {<br />    private void test(){<br />        Veggie tv,nv;<br />        Fruit tf,nf;<br />        TropicalGardener tg=new TropicalGardener();<br />        NorthernGardener ng=new NorthernGardener();</div> <div>        tv=tg.createVeggie("热带菜叶");<br />        nv=ng.createVeggie("东北甜菜");<br />        tf=tg.createFruit("‹¹·å—椰子");<br />        nf=ng.createFruit("雪梨");<br />    }<br />    public static void main(String args[]){<br />        TestApp test=new TestApp();<br />        test.test();<br />    }<br />}</div> <div>1.3.1.4.11 ‹¹‹è¯•˜qè¡Œ¾l“æžœ<br />    热带工厂为æ?zh¨¨n)¨åˆ›å¾äº†ï¼?x¨¬)热带水果åQçƒ­å¸¦èœå?br />    äºšçƒ­å¸¦å·¥åŽ‚äØ“(f¨´)æ‚(zh¨¨n)¨åˆ›å»ÞZº†åQšäºšçƒ­å¸¦è”¬èœåQä¸œåŒ—甜è?br />    热带工厂为æ?zh¨¨n)¨åˆ›å¾äº†ï¼?x¨¬)热带水果åQæ“v南椰å­?br />    äºšçƒ­å¸¦å·¥åŽ‚äØ“(f¨´)æ‚(zh¨¨n)¨åˆ›å»ÞZº†åQšäºšçƒ­å¸¦æ°´æžœåQé›ªæ¢?/div> <div>    Process finished with exit code 0<br />    看完设计囑֒Œæºç åQŒåŽŸç†å·²¾lå¾ˆæ¸…楚了,˜q™ä¸ªæ¨¡å¼åº”用很灵‹z»ï¼ŒçŒ´äº¤¾l™ä½ äº†ï¼Œçœ‹ä½ æ€Žä¹ˆçŽ©å®ƒåQå“ˆå“ˆå“ˆå“ˆã€‚。。ã€?/div> <div><strong>1.3.1.5 å¥›_¨²ä¸„¡‘Ñ造万ç‰?br /></strong>    奛_¨²ä¸„¡‘Ñ造物的故事很适合在这里ä‹D例子åQŒå¥³å¨²çš„¾l›_­æŒ‰ç…§é˜´é˜³åˆ’分åQŒäñ”品则按äh、兽划分。将抽象工厂模式用于奛_¨²é€ ä¸‡ç‰©çš„æ¨¡æ‹Ÿ¾pȝ»Ÿè®¾è®¡ä¸­ã€‚ç³»¾lŸè®¾è®¡å›¾å¦‚下åQ?/div> </div></div><img alt="" src="http://www.aygfsteel.com/images/blogjava_net/qileilove/d1165335259515.png" height="531" width="685" /><img src ="http://www.aygfsteel.com/qileilove/aggbug/393318.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/qileilove/" target="_blank">™åºå…¶è‡ªç„¶EVO</a> 2012-12-21 16:26 <a href="http://www.aygfsteel.com/qileilove/archive/2012/12/21/393318.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>跟屌丝大哥学ä¹?f¨¤n)设计模å?-工厂æ–ÒŽ(gu¨©)³•模式http://www.aygfsteel.com/qileilove/archive/2012/12/19/393215.html™åºå…¶è‡ªç„¶EVO™åºå…¶è‡ªç„¶EVOWed, 19 Dec 2012 08:25:00 GMThttp://www.aygfsteel.com/qileilove/archive/2012/12/19/393215.htmlhttp://www.aygfsteel.com/qileilove/comments/393215.htmlhttp://www.aygfsteel.com/qileilove/archive/2012/12/19/393215.html#Feedback0http://www.aygfsteel.com/qileilove/comments/commentRss/393215.htmlhttp://www.aygfsteel.com/qileilove/services/trackbacks/393215.html阅读全文

]]>
跟屌丝大哥学ä¹?f¨¤n)设计模å?--生成器模å¼?Builder)解析例子 http://www.aygfsteel.com/qileilove/archive/2012/12/18/393166.html™åºå…¶è‡ªç„¶EVO™åºå…¶è‡ªç„¶EVOTue, 18 Dec 2012 09:16:00 GMThttp://www.aygfsteel.com/qileilove/archive/2012/12/18/393166.htmlhttp://www.aygfsteel.com/qileilove/comments/393166.htmlhttp://www.aygfsteel.com/qileilove/archive/2012/12/18/393166.html#Feedback0http://www.aygfsteel.com/qileilove/comments/commentRss/393166.htmlhttp://www.aygfsteel.com/qileilove/services/trackbacks/393166.html
生成器模式属于对象结构型模式åQŒå…¶æ„å›¾æ˜¯å°†ä¸€ä¸ªå¤æ‚对象的构徏与他的表½Cºåˆ†¼›»ï¼Œä½¿å¾—åŒæ ·çš„æž„å»ºåˆ›å»ø™¿‡½E‹å¯ä»¥åˆ›å»ÞZ¸åŒçš„表示ã€?/span>
适用性:(x¨¬)
1.         当创建复杂对象的½Ž—法应该独立于该对象的组成部分以å?qi¨¢ng)他们的装配方式æ?/span>
2.         当构造过½E‹å¿…™åÕd…è®¸è¢«æž„造的对象有不同的表示时ã€?/span>
 
参与�/span>:
       生成å™?/span>Builder:为创å»ÞZ¸€ä¸?/span>Product对象的各个部件指定抽象接å?/span>(AnimalBuilder)ã€?/span>
       具体生成å™?/span>ConcreteBuilder:实现Builder接口一构造和装配该äñ”品的各个部äšgã€?/span>
                     定义òq¶æ˜Ž¼‹®ä»–所创徏的表½Cºï¼Œ
                     提供一个检索äñ”品的接口(getAnimal)ã€?/span>
导向器:(x¨¬)构徏一个适用Builder对象的接口ã€?/span>
ProductåQ?/span>Checken,pigåQ?/span>:表示被构造的复杂对象ã€?/span>ConcreteBuilder创徏该äñ”品的内部表示òq¶å®šä¹‰å®ƒçš„装配过½E‹ï¼ŒåŒ…含定义¾l„成部äšg的类åQŒåŒ…括将˜q™äº›éƒ¨äšg装配成最¾lˆçš„产品ã€?img alt="" src="http://img1.51cto.com/attachment/200707/200707141184406082109.gif" border="0" />
å›?
当客户需要一个äñ”品时åQŒæŠŠéœ€è¦çš„参数传递个导向器,导向器根据传递的参数调用具体的生成器åQŒå…·ä½“的生成器通过一¾pÕdˆ—的操ä½?/span>(getAnimal()通过调用其它的接口方法实çŽ?/span>)最ä¼?x¨¬)返回一个äñ”品ã€?/span>
Bridge模式的优点:(x¨¬)
1.         它ä‹É你可以改变一个äñ”品的内部表示åQ?/span>Builder对象提供¾l™å¯¼å‘器一个构造äñ”品的抽象接口åQŒè¯¥æŽ¥å£ä½¿å¾—生成器可以隐藏这个äñ”品的表示和内部结构,他同时也隐藏了该产品是如何装配的åQŒå› ä¸ÞZñ”品时通过抽象接口构造的(注:(x¨¬)本例子把接口的实现放在具体类中了)åQŒä½ åœ¨æ”¹å˜è¯¥äº§å“çš„内部表½Cºæ—¶æ‰€è¦åšçš„只是定义一个新的生成器ã€?/span>
2.         他将构造代码和表示代码分开åQŒè¿™æœ‰ç‚¹¾cÖM¼¼äºŽæ¨¡æ¿æ¨¡å¼ã€‚所不同的是模版模式最¾lˆæ˜¯å®Œæˆå¤æ‚的工作,而生成器的目的是要生成一个复杂的对象ã€?/span>
3.         ä»–ä‹Éå¾—ä½ å¯ÒŽ(gu¨©)ž„造过½E‹è¿›è¡Œæ›´åŠ ç²¾¾l†çš„æŽ§åˆ¶ã€?/span>Builder模式是在导向者的控制下一步一步构造äñ”品的åQŒä»…当该产品完成æ—Óž¼Œå¯¼å‘者才从生成器中取回äñ”品。因æ­?/span>Builder模式能更好的反映产品的构造过½E‹ï¼Œä½¿ä½ å¯ä»¥æ›´ç²¾¾l†çš„æŽ§åˆ¶æž„徏˜q‡ç¨‹åQŒä»Žè€Œèƒ½æ›´ç²¾¾l†çš„æŽ§åˆ¶æ‰€çš„äñ”品的内部¾l“æž„ã€?/span>
代码½CÞZ¾‹:
AnimalBuilderåQšä»£ç ?/span>
package builder;
public interface AnimalBuilder{
    public void buildName();
    public void buildLegs();
    public void buildMeat();
    public Animal getAnimal();
}
ChickenBuilderçš?/span>代码åQ?/span>
package builder;
public class ChickenBuilder implements AnimalBuilder{
    private Animal chicken = null;
    public ChickenBuilder(){
       chicken = new Animal();
    }
    public void buildName(){
       chicken.setName("chicken");
    }
    public void buildLegs(){
       chicken.setLegs(2);
    }
    public void buildMeat(){
       chicken.setMeat("chicken");
    }
    public Animal getAnimal(){
       buildName();
       buildLegs();
       buildMeat();
       return chicken;
    }
}
Animal代码åQ?/span>
package builder;
public class Animal{
    private String name;
    private String meat;
    private int legs;
    public String getName(){
       return name;
    }
    public String getMeat(){
       return meat;
    }
    public int getLegs(){
       return legs;
    }
    public void setName(String aName){
       name = aName;
    }
    public void setMeat(String aMeat){
       meat = aMeat;
    }
    public void setLegs(int alegs){
       legs = alegs;
    }
}
Director代码åQ?/span>
package builder;
public class Director{
    public Animal getAnimal(String aName){
       if(aName.equals("chicken")){
           return new ChickenBuilder().getAnimal();
       }
       else if(aName.equals("pig")){
           return new PigBuilder().getAnimal();
       }
       else return null;
    }
}
 
客户端代码:(x¨¬)
package builder;
public class Client{
    public static void description(Animal animal){
       String desc = "This animal is called "+animal.getName();
       desc +="\n Its meat is "+animal.getMeat();
       desc +="\n And it has "+animal.getLegs()+" legs.";
       System.out.println(desc);
    }
    public static void main(String[] args){
       String aName = "chicken";
       Director d = new Director();
       Animal animal =d.getAnimal(aName);
       description(animal);
       aName = "pig";
       animal = d.getAnimal(aName);
       description(animal);
    }
}
¾l“论åQšç”Ÿæˆå™¨æ¨¡å¼ä½¿å¾—客户可以更加¾_„¡»†çš„æŽ§åˆ¶ä¸€ä¸ªå¯¹è±¡çš„æž„徏åQŒæ¯ä¸ªå…·ä½“的创徏者包含了创徏和装配一个特定äñ”品的所有代码,˜q™äº›ä»£ç åªç”¨å†™ä¸€‹Æ¡ï¼Œä¾¿å¯ä»¥è¢«ä¸åŒçš?/span>Director使用åQŒä»Žè€Œå¯ä»¥è£…配出不同的对象ã€?/span>
 


]]>跟屌丝大哥学ä¹?f¨¤n)设计模å?--代理模式之动态代ç?/title><link>http://www.aygfsteel.com/qileilove/archive/2012/12/13/392932.html</link><dc:creator>™åºå…¶è‡ªç„¶EVO</dc:creator><author>™åºå…¶è‡ªç„¶EVO</author><pubDate>Thu, 13 Dec 2012 03:53:00 GMT</pubDate><guid>http://www.aygfsteel.com/qileilove/archive/2012/12/13/392932.html</guid><wfw:comment>http://www.aygfsteel.com/qileilove/comments/392932.html</wfw:comment><comments>http://www.aygfsteel.com/qileilove/archive/2012/12/13/392932.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/qileilove/comments/commentRss/392932.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/qileilove/services/trackbacks/392932.html</trackback:ping><description><![CDATA[<div><p>动态代ç?/p> <p>java中动态代理机制的引入使得代理模式的思想更加完善与进步,它允许动态的创徏代理òq¶æ”¯æŒå¯¹åŠ¨æ€çš„å¯ÒŽ(gu¨©)‰€ä»£ç†çš„æ–¹æ³•进行调用。Java动态代理类位于Java.lang.reflect包下åQŒä¸€èˆ¬ä¸»è¦æ¶‰å?qi¨¢ng)到以下两个¾c»ï¼š(x¨¬) </p> <p><span>(1). Interface InvocationHandler</span>åQšè¯¥æŽ¥å£ä¸­ä»…定义了一个方法ObjectåQ?span>invoke(Object obj,Method method, Object[] args)</span>。在实际使用æ—Óž¼Œ½W¬ä¸€ä¸ªå‚æ•°obj一般是指代理类åQŒmethod是被代理的方法,如上例中的request()åQŒargs䏸™¯¥æ–ÒŽ(gu¨©)³•的参数数¾l„。这个抽象方法在代理¾cÖM¸­åŠ¨æ€å®žçŽ°ã€?nbsp;</p> <p>(2).ProxyåQšè¯¥¾cÕd³ä¸ºåŠ¨æ€ä»£ç†ç±»åQŒä½œç”¨ç±»ä¼égºŽä¸Šä¾‹ä¸­çš„ProxySubjectåQŒå…¶ä¸­ä¸»è¦åŒ…含以下内容:(x¨¬) </p> <p><span>Protected Proxy(InvocationHandler h)</span>åQšæž„é€ å‡½æ•ŽÍ¼Œä¼°è®¡ç”¨äºŽ¾l™å†…部的h赋倹{€?nbsp;</p> <p><span>Static Class getProxyClass (ClassLoader loader, Class[] interfaces)</span>åQšèŽ·å¾—ä¸€ä¸ªä»£ç†ç±»åQŒå…¶ä¸­loader是类装蝲器,interfaces是真实类所拥有的全部接口的数组ã€?nbsp;</p> <p><span>Static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)</span>åQšè¿”回代理类的一个实例,˜q”回后的代理¾cÕd¯ä»¥å½“作被代理¾cÖM‹Éç”?可ä‹É用被代理¾cȝš„在Subject接口中声明过的方æ³?ã€?nbsp;</p> <p> </p> <p>所谓Dynamic Proxy是这样一¿UclassåQšå®ƒæ˜¯åœ¨˜qè¡Œæ—¶ç”Ÿæˆçš„classåQŒåœ¨ç”Ÿæˆå®ƒæ—¶ä½ å¿…™åÀLä¾›ä¸€¾l„interface¾l™å®ƒåQŒç„¶åŽè¯¥classž®±å®£¿U°å®ƒå®žçŽ°äº†è¿™äº›interface。你当然可以把该class的实例当作这些interface中的ä»ÖM½•一个来用。当然啦åQŒè¿™ä¸ªDynamic Proxy其实ž®±æ˜¯ä¸€ä¸ªProxyåQŒå®ƒä¸ä¼š(x¨¬)替你作实质性的工作åQŒåœ¨ç”Ÿæˆå®ƒçš„实例时你必须提供一个handleråQŒç”±å®ƒæŽ¥½Ž¡å®žé™…的工作ã€?下面我们通过动态代理来重新实现上面发送信息的例子åQ?/p> <p><br /></p> <p> <img src="http://hi.csdn.net/attachment/201006/15/0_1276561533dOxg.gif" alt="" /></p> <p>在上面的例子基础上,我们先添加一个通过短信来发送消息的处理¾c»ï¼š(x¨¬)</p></div><div>public class SmsMessage implements MessageHandler {<br />@Override<br />public void sendMessage(String msg) {<br />// TODO Auto-generated method stub<br />System.out.println("SMS Message :" + msg+" sent !");<br />}<br />}<br />//动态代理类<br />import java.lang.reflect.InvocationHandler;<br />import java.lang.reflect.Method;<br />public class DynamicMessageProxy implements InvocationHandler {<br />private static int count;<br />private MessageHandler msgHandler;<br />public DynamicMessageProxy(MessageHandler handler) {<br />msgHandler = handler;<br />}<br />@Override<br />public Object invoke(Object proxy, Method method, Object[] args)<br />throws Throwable {<br />// TODO Auto-generated method stub<br />System.out.println("++++++++=============+++++++++");<br />System.out.println("proxy:" + proxy.getClass());<br />System.out.println("method:" + method);<br />System.out.println("++++++++=============+++++++++");<br />if (args != null && args.length == 1 && checkMessage((String) args[0])) {<br />count++;<br />System.out.println("Message sent:" + count);<br />return method.invoke(msgHandler, args);<br />}<br />return null;<br />}<br />private boolean checkMessage(String msg) {<br />return msg != null && msg.length() > 10;<br />}<br />}<br />//下面是调ç”?br />import java.lang.reflect.Proxy;<br />public class MainClass {<br />private static void runProxy(MessageHandler handler) {<br />handler.sendMessage("message for test");<br />}<br />/**<br /> * @param args<br /> */<br />public static void main(String[] args) {<br />// TODO Auto-generated method stub<br />// runProxy(new EmailMessage());<br />// System.out.println("++++++++++++++++Proxy++++++++++++++++++");<br />// runProxy(new MessageProxy());<br />MessageHandler handler = new EmailMessage();<br />runProxy(handler);<br />MessageHandler proxy = (MessageHandler) Proxy.newProxyInstance(<br />MessageHandler.class.getClassLoader(),<br />new Class[] { MessageHandler.class }, new DynamicMessageProxy(<br />handler));<br />runProxy(proxy);<br />System.out.println("++++++++++++++++++++++++++++++++++");<br />// 短信方式<br />handler = new SmsMessage();<br />runProxy(handler);<br />proxy = (MessageHandler) Proxy.newProxyInstance(MessageHandler.class<br />.getClassLoader(), new Class[] { MessageHandler.class },<br />new DynamicMessageProxy(handler));<br />runProxy(proxy);<br />}<br />}<br />下面ä¸ÞZ»¥ä¸Šæ–¹æ³•的输出åQ?br />message for test send!!<br />++++++++=============+++++++++<br />proxy:class $Proxy0<br />method:public abstract void MessageHandler.sendMessage(java.lang.String)<br />++++++++=============+++++++++<br />Message sent:1<br />message for test send!!<br />++++++++++++++++++++++++++++++++++<br />SMS Message :message for test sent !<br />++++++++=============+++++++++<br />proxy:class $Proxy0<br />method:public abstract void MessageHandler.sendMessage(java.lang.String)<br />++++++++=============+++++++++<br />Message sent:2<br />SMS Message :message for test sent !</div><div><p>以上例子中,通过调用Proxy.newProxyInstanceæ–ÒŽ(gu¨©)³•创徏动态代理对象,该方法需要传入一ä¸?<span>¾cÕdŠ è½½å™¨ã€ä¸€¾l„希望代理实现的接口列表、InvocationHandler 接口的一个具体实现。动态代理可以将所有调用重定向到调用处理器åQŒé€šå¸¸æˆ‘们ä¼?x¨¬)向该处理器传递一个时间对象的引用ã€?/span>invoke()æ–ÒŽ(gu¨©)³•中传递进来了代理对象åQŒå½“你需要区分请求来源时˜q™æ˜¯éžå¸¸æœ‰ç”¨çš„,例如你可以通过判断传入的方法名屏蔽掉某些方法的执行åQåŠ¨æ€ä»£ç†æœºåˆ¶åÆˆä¸æ˜¯ä¼?x¨¬)å¾ˆé¢‘ç¹ä½¿ç”¨çš„æ–¹æ³•ï¼Œå®ƒé€šå¸¸ç”¨æ¥è§£å†³ä¸€äº›ç‰¹å®šæƒ…å†µä¸‹çš„é—®é¢˜ï¼Œå› æ­¤ä¸è¦ç›²ç›®çš„äØ“(f¨´)了ä‹É用而ä‹É用,要根据自å·Þqš„实际需求来军_®šåQ?/p></div><div>动态代理的应用十分òq¿æ³›åQŒåœ¨struts2的拦截器中就用到了动态代理机制。还是以买èžR¼œ¨äØ“(f¨´)例子åQŒçŽ°åœ¨ç”¨åŠ¨æ€ä»£ç†æ¥å®žçŽ°åQŒå…¶ä¸­ä¸æ‡‚的接口æ–ÒŽ(gu¨©)³•查查Java apiž®×ƒ¼š(x¨¬)明白了,在此不多做解释,代码如下(注意PassengerProxy¾c?åQ? <p style="text-indent: 2em;">imp<wbr>ort java.lang.reflect.*;</p> <p style="text-indent: 2em;">public interface Passenger {<br />public void buyTicket();<br />}</p> <p style="text-indent: 2em;">public class RealPassenger implements Passenger {</p> <p style="text-indent: 2em;">@Override<br />public void buyTicket() {<br />   // TODO Auto-generated method stub<br />   System.out.println("购买了èžR¼œ?);<br />}<br />}</p> <p style="text-indent: 2em;">// 用动态代理实çŽ?/p><p style="text-indent: 2em;">/<code>/InvocationHandler</code> 是代理实例的<em>调用处理½E‹åº</em> 实现的接口ã€? 每个代理实例都具有一个关联的调用处理½E‹åºã€‚对代理实例调用æ–ÒŽ(gu¨©)³•æ—Óž¼Œž®†å¯¹æ–ÒŽ(gu¨©)³•调用˜q›è¡Œ¾~–码òq¶å°†å…¶æŒ‡‹z‘Öˆ°//它的调用处理½E‹åºçš?<code>invoke</code> æ–ÒŽ(gu¨©)³•ã€?br />public class PassengerProxy implements InvocationHandler {<br />public Object obj;</p> <p style="text-indent: 2em;">// 把obj交给代理¾c?br />public Object obj(Object obj) {<br />   this.obj = obj;<br />   return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj<br />     .getClass().getInterfaces(), this);<br />}</p> <p style="text-indent: 2em;">@Override<br />public Object invoke(Object proxy, Method method, Object[] args)<br />    throws Throwable {<br />   // TODO Auto-generated method stub<br />   System.out.println("通过代理");<br />   method.invoke(obj, args);<br />   return null;<br />}<br />}</p> <p style="text-indent: 2em;">public class Client {<br />public static void main(String[] args) {<br />   PassengerProxy proxy = new PassengerProxy();<br />   Passenger passenger = (Passenger) proxy.obj(new RealPassenger());<br />   passenger.buyTicket();<br />}<br />}</p><p style="text-indent: 2em;">再来一个更牛的例子</p><p style="text-indent: 2em;"></p><div><ol start="1"><li><span>/** </span></li><li><span> * ç›æ€º²æŽ¥å£ </span></li><li><span> *  </span></li><li><span> * @author zhengt </span></li><li><span> * @time Jun 3, 2095 3:13:03 PM </span></li><li><span> */  </span></li><li><span>public interface XiangQinInterface {  </span></li><li>    <span>/** </span></li><li><span>     * ç›æ€º²æ–ÒŽ(gu¨©)³• </span></li><li><span>     */  </span></li><li>    <span>public void xiangQin();  </span></li><li>}  </li><li><span>/** </span></li><li><span> * å¼ ä¸‰ç›æ€º²å®žçް¾c?nbsp;</span></li><li><span> *  </span></li><li><span> * @author zhengt </span></li><li><span> * @time Jun 3, 2095 3:14:48 PM </span></li><li><span> */  </span></li><li><span>public class ZhangSanXiangQinInterfaceImpl implements XiangQinInterface {  </span></li><li>    <span>public void xiangQin() {  </span></li><li>        System.out.println(<span>"张三åŽÈ›¸äºÔŒ¼Œå¨¶ä¸ªæ¼‚亮老婆ã€?);  </span></li><li>    }  </li><li>}  </li><li><span>import java.lang.reflect.InvocationHandler;  </span></li><li><span>import java.lang.reflect.Method;  </span></li><li>  </li><li><span>/** </span></li><li><span> * ç›æ€º²å¯æ˜¯ä¸€è¾ˆå­çš„å¤§äº‹ï¼Œç›æ€º²å‰è¦å‡†å¤‡ä¸€ä¸‹ï¼Œæ‰“扮得帅气些ã€?nbsp;</span></li><li><span> *  </span></li><li><span> * @author zhengt </span></li><li><span> * @time Jun 3, 2095 3:15:48 PM </span></li><li><span> */  </span></li><li><span>public class ReadyInvocationHandler implements InvocationHandler {  </span></li><li>    <span>//ç›æ€º²æŽ¥å£çš„实现类åQŒä¹Ÿž®±æ˜¯å¼ ä¸‰ç›æ€º²¾c?nbsp; </span></li><li>    <span>private Object zhangSan = null;  </span></li><li>  </li><li>    <span>public ReadyInvocationHandler(Object realSubject) {  </span></li><li>        <span>this.zhangSan = realSubject;  </span></li><li>    }  </li><li>  </li><li>    <span>public Object invoke(Object proxy, Method m, Object[] args) {  </span></li><li>        Object result = <span>null;  </span></li><li>        <span>try {  </span></li><li>            <span>/** </span></li><li><span>             * åŠ¨æ€ä»£ç†ç±»$Proxy0调用xiangQinæ–ÒŽ(gu¨©)³•时会(x¨¬)调用它自å·Þqš„xiangQinæ–ÒŽ(gu¨©)³•åQ?nbsp;</span></li><li><span>             * è€Œå®ƒè‡ªå·±çš„xiangQinæ–ÒŽ(gu¨©)³•里面调用的是super.h.invoke(this, , )åQŒä¹Ÿž®±æ˜¯çˆ¶ç±»Proxyçš„hçš„invokeæ–ÒŽ(gu¨©)³•åQ?nbsp;</span></li><li><span>             * ä¹Ÿå°±æ˜¯ReadyInvocationHandler¾cȝš„invokeæ–ÒŽ(gu¨©)³•ã€?nbsp;</span></li><li><span>             * æ‰€ä»¥ï¼Œinvoke(Object proxy, Method m, Object[] args)¿Uçš„proxy实际上就是动态代理类$Proxy0åQ?nbsp;</span></li><li><span>             * å¦‚果你将其强转成XiangQinInterface然后调用它的xiangQinæ–ÒŽ(gu¨©)³•åQŒç„¶åŽå®ƒ?y¨­u)®×ƒ¼?x¨¬)调用super.h.invoke(this, , )åQŒè¿™æ ·å°±ä¼?x¨¬)死循环ã€?nbsp;</span></li><li><span>             */  </span></li><li>            <span>/** </span></li><li><span>             * ¾|‘上关于˜q™é‡Œæœ€å¤šé—®é¢˜å°±æ˜¯Object proxy攑֜¨˜q™é‡Œç”¨æ¥åšä»€ä¹ˆå‘¢åQŸè¿™ä¸ªæˆ‘也不知道åQ?nbsp;</span></li><li><span>             * ä¸è¿‡è‡›_°‘我们知道它到底是个什么东西,具体做什么用嘛就不得而知äº?nbsp;</span></li><li><span>             */  </span></li><li>            System.out.println(proxy.getClass().getSimpleName());  </li><li>            System.out.println(<span>"å¼ ä¸‰ç›æ€º²å‰ï¼Œä»£ç†äººç»™ä»–打扮了打扮ã€?);  </span></li><li>            result = m.invoke(zhangSan, args);  </li><li>        } <span>catch (Exception ex) {  </span></li><li>            System.exit(<span>1);  </span></li><li>        }  </li><li>        <span>return result;  </span></li><li>    }  </li><li>}  </li><li><span>import java.lang.reflect.InvocationHandler;  </span></li><li><span>import java.lang.reflect.Method;  </span></li><li><span>import java.lang.reflect.Proxy;  </span></li><li>  </li><li><span>/** </span></li><li><span> * å¼ ä¸‰æ¥åˆ°äº†å©šä»‹æ‰€(ç›æ€º²çŽ°åœº)åQŒå¼€å§‹ç›¸äºŒÓ€?nbsp;</span></li><li><span> *  </span></li><li><span> * @author zhengt </span></li><li><span> * @time Jun 3, 2095 3:17:16 PM </span></li><li><span> */  </span></li><li><span>public class HunJieSuo {  </span></li><li>    <span>public static void main(String args[]) {  </span></li><li>        <span>//å…ˆå°†å¼ ä¸‰ç›æ€º²˜q™ä¸ªç›æ€º²çš„实现类实例化,也就是得到XiangQinInterface接口的一个实例对è±?nbsp; </span></li><li>        XiangQinInterface zhangSan = <span>new ZhangSanXiangQinInterfaceImpl();  </span></li><li>        <span>/** </span></li><li><span>         * å¾—到ZhangSanXiangQinInterfaceImpl˜q™ä¸ª¾cȝš„一个代理类åQŒåŒæ—¶äØ“(f¨´)代理¾cȝ»‘定了一个处理类ReadyInvocationHandlerã€?nbsp;</span></li><li><span>         * å¬ç€å¾ˆç»•口,其实ž®±æ˜¯æ¯æ¬¡è°ƒç”¨ZhangSanXiangQinInterfaceImpl˜q™ä¸ªå­ç±»çš„xiangQinæ–ÒŽ(gu¨©)³•æ—Óž¼Œ </span></li><li><span>         * ä¸æ˜¯zhangSan˜q™ä¸ªZhangSanXiangQinInterfaceImpl¾cȝš„实例去调用, </span></li><li><span>         * è€Œæ˜¯˜q™ä¸ªZhangSanXiangQinInterfaceImpl的代理类ReadyInvocationHandler去调用它自己的invokeæ–ÒŽ(gu¨©)³•, </span></li><li><span>         * ˜q™ä¸ªinvokeæ–ÒŽ(gu¨©)³•里呢可以调用zhangSan˜q™ä¸ªå®žä¾‹çš„xiangQinæ–ÒŽ(gu¨©)³• </span></li><li><span>         */  </span></li><li>        <span>/** </span></li><li><span>         * åœ¨java¿Uæ€Žæ ·å®žçŽ°åŠ¨æ€ä»£ç†å‘¢ </span></li><li><span>         * ½W¬ä¸€æ­¥ï¼Œæˆ‘们要有一个接口,˜q˜è¦æœ‰ä¸€ä¸ªæŽ¥å£çš„实现¾c»ï¼Œè€Œè¿™ä¸ªå®žçŽ°ç±»å‘¢å°±æ˜¯æˆ‘ä»¬è¦ä»£ç†çš„å¯¹è±¡ï¼Œ </span></li><li><span>         * æ‰€è°“代理呢也就是在调用实现¾cÈš„æ–ÒŽ(gu¨©)³•æ—Óž¼Œå¯ä»¥åœ¨æ–¹æ³•执行前后做额外的工作,˜q™ä¸ªž®±æ˜¯ä»£ç†ã€?nbsp;</span></li><li><span>         * ½W¬äºŒæ­¥ï¼Œæˆ‘们要自己写一个在要代理类的方法执行时åQŒèƒ½å¤Ÿåšé¢å¤–工作的类åQŒè€Œè¿™ä¸ªç±»å¿…é¡»¾l§æ‰¿InvocationHandler接口åQ?nbsp;</span></li><li><span>         * ä¸ÞZ»€ä¹ˆè¦¾l§æ‰¿å®ƒå‘¢åQŸå› ä¸ÞZ»£ç†ç±»çš„实例在调用实现¾cÈš„æ–ÒŽ(gu¨©)³•的时候,不会(x¨¬)调真正的实现¾cȝš„˜q™ä¸ªæ–ÒŽ(gu¨©)³•åQ?nbsp;</span></li><li><span>         * è€Œæ˜¯è½¬è€Œè°ƒç”¨è¿™ä¸ªç±»çš„invokeæ–ÒŽ(gu¨©)³•åQˆç‘ô承时必须实现的方法)åQŒåœ¨˜q™ä¸ªæ–ÒŽ(gu¨©)³•中你可以调用真正的实现类的这个方法ã€?nbsp;</span></li><li><span>         * ½W¬ä¸‰æ­¥ï¼Œåœ¨è¦ç”¨ä»£ç†ç±»çš„实例去调用实现¾cÈš„æ–ÒŽ(gu¨©)³•的时候,写出下面两段代码ã€?nbsp;</span></li><li><span>         */  </span></li><li>        XiangQinInterface proxy = (XiangQinInterface) Proxy.newProxyInstance(  </li><li>                zhangSan.getClass().getClassLoader(),  </li><li>                zhangSan.getClass().getInterfaces(),  </li><li>                <span>new ReadyInvocationHandler(zhangSan));  </span></li><li>        proxy.xiangQin();  </li><li>        <span>/** </span></li><li><span>         * ˜q™é‡Œè¦è§£é‡Šä¸‹ä¸­éƒ¨é‚£æ®µé•‰K•¿çš„代码的意思,以及(qi¨¢ng)具体做了哪些工作åQ?nbsp;</span></li><li><span>         * ½W¬ä¸€åQŒæ ¹æ®zhangSan.getClass().getClassLoader()˜q™ä¸ªè¦ä»£ç†ç±»çš„类加蝲器和 </span></li><li><span>         * zhangSan.getClass().getInterfaces()要代理类所实现的所有的接口 </span></li><li><span>         * ä½œäØ“(f¨´)参数调用Proxy.getProxyClass(ClassLoader loader, Class<?>... interfaces) </span></li><li><span>         * çš„æ–¹æ³•返回代理类的java.lang.Class对象åQŒä¹Ÿž®±æ˜¯å¾—到了java动态生成的代理¾c?Proxy0çš„Class对象ã€?nbsp;</span></li><li><span>         * åŒæ—¶åQŒjava˜q˜è®©˜q™ä¸ªåŠ¨æ€ç”Ÿæˆçš„$Proxy0¾cÕd®žçŽîCº†è¦ä»£ç†ç±»çš„实现的所有接口,òq¶ç‘ô承了Proxy接口ã€?nbsp;</span></li><li><span>         * ½W¬äºŒåQŒå®žä¾‹åŒ–˜q™ä¸ªåŠ¨æ€ç”Ÿæˆçš„$Proxy0¾cȝš„一个实例,实例化代理类的构造函æ•îCØ“(f¨´)Proxy(InvocationHandler h)åQ?nbsp;</span></li><li><span>         * ä¹Ÿå°±æ˜¯è¯´è¦å®žä¾‹åŒ–˜q™ä¸ªåŠ¨æ€ç”Ÿæˆçš„$Proxy0¾c»ï¼Œå¿…é¡»¾l™å®ƒä¸€ä¸ªInvocationHandler参数åQŒä¹Ÿž®±æ˜¯æˆ‘们自己实现的用来在代理¾c?nbsp;</span></li><li><span>         * æ–ÒŽ(gu¨©)³•执行前后做额外工作的¾c»ReadyInvocationHandlerã€?nbsp;</span></li><li><span><span>         * ˜q?ŒDµä»£ç ?Proxy.newProxyInstance(zhangSan.getClass().getClassLoader(),zhangSan.getClass().getInterfaces(),new ReadyInvocationHandler(zhangSan))</span> </span></li><li><span>         * å¾—到的其实是一个类名叫$Proxy0 extends Proxy implements XiangQinInterface的类ã€?nbsp;</span></li><li><span>         * ½W¬ä¸‰åQŒå°†˜q™ä¸ª$Proxy0¾cÕd¼ºåˆ¶è{型成XiangQinInterface¾cÕdž‹åQŒè°ƒç”¨xiangQinæ–ÒŽ(gu¨©)³•ã€?nbsp;</span></li><li><span>         */  </span></li><li>    }  </li><li>}  <br /></li></ol></div><div>¾|‘ä¸Šçœ‹åˆ°ä¸€ä¸ªç‰›äºø™¯»˜q‡è¿™ä¸ªåŠ¨æ€ä»£ç†çš„æºä»£ç ï¼ŒçŽ°æŠŠ¾|‘址留在˜q™é‡ŒåQŒå¸Œæœ›å¯¹¾|‘友们有帮助ã€?<br /><a target="_blank" >http://hi.baidu.com/malecu/blog/item/45d4952b31bc0e27d52af17a.html</a> </div><div><div><div>在目前的Java开发包中包含了对动态代理的支持åQŒä½†æ˜¯å…¶å®žçŽ°åªæ”¯æŒå¯¹æŽ¥å£çš„çš„å®žçŽ°ã€?<br /> <br />  其实çŽîC¸»è¦é€šè¿‡æ˜¯java.lang.reflect.Proxy¾cÕd’Œjava.lang.reflect.InvocationHandler接口ã€?<br /> <br />  Proxy¾cÖM¸»è¦ç”¨æ¥èŽ·å–åŠ¨æ€ä»£ç†å¯¹è±¡ï¼ŒInvocationHandler接口用来¾U¦æŸè°ƒç”¨è€…实玎ͼŒå¦‚下åQŒDiaoSi接口定义çš?业务æ–ÒŽ(gu¨©)³•åQŒDiaoSiNanImpl是DiaoSi接口的实玎ͼŒ<div>DiaoSiNanHandleræ˜? InvocationHandler接口实现。代码如下:(x¨¬)<br /><div>业务接口: </div></div></div><div>package proxy;<br /><br />public interface DiaoSi {<br />void luGuan();<br />}<br /></div><div><div> 业务接口实现åQ?</div></div><div>public class DiaoSiNan implements DiaoSi {<br /><br />    @Override<br />    public void luGuan() {<br />        // TODO Auto-generated method stub<br />        System.out.println("我是撸管çŽ?);<br />    }<br /><br />}</div><div> InvocationHandler实现åQŒéœ€è¦åœ¨æŽ¥å£æ–ÒŽ(gu¨©)³•调用前后加入一部䆾处理工作åQŒè¿™é‡Œä»…仅在æ–ÒŽ(gu¨©)³•调用前后向后台输å‡ÞZ¸¤å¥å­—½W¦ä¸²åQŒå…¶ä»£ç å¦‚下åQ?</div><div>package proxy;<br /><br />import java.lang.reflect.InvocationHandler;<br />import java.lang.reflect.Method;<br /><br />public class DiaoSiNanHander implements InvocationHandler{<br />    //要代理的原始对象 <br />    <br />private Object diaosinan; <br />/**<br /><br />* 构造函数ã€?br /><br />* @param obj 要代理的原始对象ã€?br /><br />*/ <br />public DiaoSiNanHander(Object diaosinan) {<br /><br />    this.diaosinan = diaosinan;<br />}<br />    @Override<br />    <br />    public Object invoke(Object proxy, Method method, Object[] args)<br />            throws Throwable {<br />        // TODO Auto-generated method stub<br />        Object result ;<br />        doBefore(); <br />        //调用原始对象的方æ³?<br />        result = method.invoke(this.diaosinan ,args); <br />        //æ–ÒŽ(gu¨©)³•调用之后 <br />        doafter();<br />        return result;<br /><br />        <br />    }<br />    private void doafter() {<br />        // TODO Auto-generated method stub<br />System.out.println("after method invoke!"); <br />    }<br />    private void doBefore() {<br />        // TODO Auto-generated method stub<br />        System.out.println("before method invoke!"); <br />    }<br /><br /><br />}<br /></div><div>‹¹‹è¯•代码åQ?</div><div>package proxy;<br /><br />import java.lang.reflect.InvocationHandler;<br />import java.lang.reflect.Proxy;<br /><br />public class Test {<br />public static void main(String[] args) {<br />DiaoSi ds = new DiaoSiNan();<br /><br />DiaoSiNanHander handler = new DiaoSiNanHander(ds);<br /><br />DiaoSi proxy = (DiaoSi) Proxy.newProxyInstance(<br /><br />ds.getClass().getClassLoader(),<br /><br />ds.getClass().getInterfaces(),<br /><br />handler);<br />/*public static Object newProxyInstance(ClassLoader loader,<br />        Class<?>[] interfaces,<br />        InvocationHandler h)<br />throws IllegalArgumentException<br />{<br />if (h == null) {<br />throw new NullPointerException();<br />}*/<br />proxy.luGuan();<br /><br />        <br /><br />}<br />}<br /><div>Ø é¦–å…ˆèŽ·å–ä¸€ä¸ªä¸šåŠ¡æŽ¥å£çš„å®žçŽ°å¯¹è±¡; <br /> <br />ã€€ã€€Ø èŽ·å–ä¸€ä¸ªInvocationHandler实现åQŒæ­¤å¤„是<div>DiaoSiNanHanderHandler对象;</div> <br />ã€€ã€€Ø åˆ›å¾åŠ¨æ€ä»£ç†å¯¹è±? <br /> <br />ã€€ã€€Ø é€šè¿‡åŠ¨æ€ä»£ç†å¯¹è±¡è°ƒç”¨luGuan()æ–ÒŽ(gu¨©)³•åQŒæ­¤æ—¶ä¼š(x¨¬)在原始对象DiaoSiNan.luGuan()æ–ÒŽ(gu¨©)³•前后输出两句字符丌Ӏ?<br /> <br />  ˜qè¡Œ‹¹‹è¯•¾c»è¾“出如ä¸? <br /> <br />  <div>before method invoke!<br />我试撸管çŽ?br />after method invoke!<br /></div><br /> <br />  此处Test¾cÖM¸­çš„æ–¹æ³•调用代码比较多åQŒåœ¨æˆ‘们的实际应用中可以通过配置文äšg来来½Ž€åŒ–客æˆïL(f¨¥ng)«¯çš„调用实现。另外也可以通过动态代理来实现½Ž€å•çš„AOPã€?</div></div><br /><p><br /></p></div><br /></div><br /><p> </p></div><img src ="http://www.aygfsteel.com/qileilove/aggbug/392932.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/qileilove/" target="_blank">™åºå…¶è‡ªç„¶EVO</a> 2012-12-13 11:53 <a href="http://www.aygfsteel.com/qileilove/archive/2012/12/13/392932.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>跟屌丝大哥学ä¹?f¨¤n)设计模å?--代理模式http://www.aygfsteel.com/qileilove/archive/2012/12/13/392930.html™åºå…¶è‡ªç„¶EVO™åºå…¶è‡ªç„¶EVOThu, 13 Dec 2012 03:20:00 GMThttp://www.aygfsteel.com/qileilove/archive/2012/12/13/392930.htmlhttp://www.aygfsteel.com/qileilove/comments/392930.htmlhttp://www.aygfsteel.com/qileilove/archive/2012/12/13/392930.html#Feedback0http://www.aygfsteel.com/qileilove/comments/commentRss/392930.htmlhttp://www.aygfsteel.com/qileilove/services/trackbacks/392930.htmlJava 代理模式详解

ä»£ç†æ¨¡å¼æ˜¯æˆ‘ä»¬æ¯”è¾ƒå¸¸ç”¨çš„è®¾è®¡æ¨¡å¼ä¹‹ä¸€ã€‚å…¶ä¸­æ–°æ€æƒ³æ˜¯äØ“(f¨´)了提供额外的处理或者不同的操作而在实际对象与调用者之间插入一个代理对象。这些额外的操作通常需要与实际对象˜q›è¡Œé€šä¿¡åQŒä»£ç†æ¨¡å¼ä¸€èˆ¬æ¶‰å?qi¨¢ng)到的角色有åQ?nbsp;

抽象角色åQšå£°æ˜ŽçœŸå®žå¯¹è±¡å’Œä»£ç†å¯¹è±¡çš„共同接口; 

代理角色åQšä»£ç†å¯¹è±¡è§’色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在ä“Q何时刻都能代替真实对象。同æ—Óž¼Œä»£ç†å¯¹è±¡å¯ä»¥åœ¨æ‰§è¡ŒçœŸå®žå¯¹è±¡æ“ä½œæ—¶åQŒé™„加其他的操作åQŒç›¸å½“于对真实对象进行封装ã€?nbsp;

真实角色åQšä»£ç†è§’色所代表的真实对象,是我们最¾lˆè¦å¼•用的对象ã€?

 

ä»¥ä¸‹ä»¥å‘é€æ¶ˆæ¯äØ“(f¨´)例来说明一个简单的代理模式的基本实玎ͼš(x¨¬)

首先明确目的åQšæœ‰ä¸€æ¡æ¶ˆæ¯ï¼Œéœ€è¦æŠŠ˜q™ä¸ªæ¶ˆæ¯å‘送出去,æ ÒŽ(gu¨©)®˜q™ä¸ªç›®çš„定义对应接口MessageHandler。需要的附加操作åQšå‡è®ùNœ€è¦éªŒè¯æ¶ˆæ¯çš„长度不能­‘…过指定长度òq¶ä¸”不能为空åQŒåƈ且我们需要统计相关信息发送到‹Æ¡æ•°åQŒè¶…˜q‡æŒ‡å®šçš„‹Æ¡æ•°æˆ‘ä»¬éœ€è¦è¾“å‡ø™­¦æŠ¥ã€‚æˆ‘ä»¬é€šè¿‡ä»£ç†æ¨¡å¼æ¥å®žçŽ°è¿™ä¸ªé™„åŠ çš„æ“ä½œã€‚ä¸‹é¢äØ“(f¨´)对应的类关系囑֏Š(qi¨¢ng)½CÞZ¾‹ä»£ç ã€?/p>




//接口定义
public interface MessageHandler {
public void sendMessage(String msg);
}
//通过Email方式发送消息的实现¾c?br />public class EmailMessage implements MessageHandler {
@Override
public void sendMessage(String msg) {
// TODO Auto-generated method stub
System.out.println(msg+" send!!");
}
}
//消息处理的代理类
public class MessageProxy implements MessageHandler {
private static int count;
private MessageHandler emailMsg;
@Override
public void sendMessage(String msg) {
// TODO Auto-generated method stub
if(checkMessage(msg))
{
if(emailMsg==null) emailMsg=new EmailMessage();
count++;
emailMsg.sendMessage(msg);
System.out.println("Message sent:"+count);
}
}
private boolean checkMessage(String msg) {
return msg != null && msg.length() > 10;
}
}
//调用¾c?br />public class MainClass {
private static void runProxy(MessageHandler handler)
{
handler.sendMessage("message for test");
}
/**
 * @param args
 */
public static void main(String[] args) {
// TODO Auto-generated method stub
runProxy(new EmailMessage());
System.out.println("++++++++++++++++Pjroxy++++++++++++++++++");
runProxy(new MessageProxy());
}
}
输出
message for test send!!
++++++++++++++++Pjroxy++++++++++++++++++
message for test send!!
Message sent:1

在例子中我们可以方便的在消息发送过½E‹ä¸­æ·ÕdŠ å„ç§éœ€è¦çš„é™„åŠ å¤„ç†æ–¹å¼åQŒä¹Ÿèƒ½æ–¹ä¾¿çš„æ›¿æ¢æ¶ˆæ¯çš„处理方式,如将通过Emailå‘é€æ¶ˆæ¯æ›¿æ¢äØ“(f¨´)通过短信发送消息,而调用方不会(x¨¬)有丝毫察觉!在ä“Q何你惌™¦ž®†ä¸€äº›é¢å¤–操作分¼›Õdˆ°å…·ä½“对象之外åQŒç‰¹åˆ«æ˜¯å¸Œæœ›èƒ½å¤Ÿå¾ˆå®¹æ˜“做å‡ÞZ¿®æ”¹ï¼Œæˆ–者想在具体对象的æ–ÒŽ(gu¨©)³•执行前插入一些额外操作的时候,代理ž®±æ˜¾å¾—十分有用!

 例如åQšå‡è®¾æœ‰ä¸€¾l„对象都实现同一个接口,实现同样的方法,但这¾l„对象中有一部分对象需要有单独的方法,传统的笨办法是在每一个应用端都加上这个单独的æ–ÒŽ(gu¨©)³•åQŒä½†æ˜¯ä»£ç é‡ç”¨æ€§ä½ŽåQŒè€¦åˆæ€§é«˜ã€?  如果用代理的æ–ÒŽ(gu¨©)³•则很好的解决了这个问é¢?/div>
 假设有一个Italk接口åQŒæœ‰½Iºçš„æ–ÒŽ(gu¨©)³•talkåQˆï¼‰åQˆè¯´è¯ï¼‰åQŒæ‰€æœ‰çš„people对象都实玎ͼˆimplementsåQ‰è¿™ä¸ªæŽ¥å£ï¼Œå®žçްtalkåQˆï¼‰æ–ÒŽ(gu¨©)³•åQ?前端有很多地斚wƒ½ž®†people实例化,执行talkæ–ÒŽ(gu¨©)³•åQŒåŽæ¥å‘现这些前端里有一些除了要说话以外˜q˜è¦å”±æ­ŒåQˆsingåQ‰ï¼Œé‚£ä¹ˆæˆ‘们既不能在ItalkæŽ?口里增加sing()æ–ÒŽ(gu¨©)³•åQŒåˆä¸èƒ½åœ¨æ¯ä¸ªå‰ç«¯éƒ½å¢žåŠ singæ–ÒŽ(gu¨©)³•åQŒæˆ‘们只有增加一个代理类talkProxyåQŒè¿™ä¸ªä»£ç†ç±»é‡Œå®žçްtalkå’Œsingæ–ÒŽ(gu¨©)³•åQ?然后在需要singæ–ÒŽ(gu¨©)³•的客æˆïL(f¨¥ng)«¯è°ƒç”¨ä»£ç†¾cÕd³å¯ï¼Œä»£ç å¦‚下åQ?h3>接口¾c»Italk  public interface Italk {
  public void talk(String msg);
  }

实现¾c»people

  public class People implements Italk
 {   public String username;  
 public String age;  
 public String getName()
{   
return username;
  }   
public void setName(String name) {
  this.username= name;   
}  
 public String getAge() {  
 return age;   }   
public void setAge(String age) {
  this.age = age;   }  
 public People(String name1, String age1) {
  this.username= name1;  
 this.age = age1;  
 }
  public void talk(String msg) {
  System.out.println(msg+"!你好,我是"+username+"åQŒæˆ‘òq´é¾„æ˜?+age);
  }   
}

代理¾c»talkProxy

  public class TalkProxy implements Italk
 {   Italk talker;  
 public TalkProxy (Italk talker)
{
  //super();   
this.talker=talker;  
 }   
public void talk(String msg)
{   
talker.talk(msg);  
 }   
public void talk(String msg,String singname)
 {   
talker.talk(msg);
  sing(singname);
  }   
private void sing(String singname)
{  
 System.out.println("唱歌åQ?+singname);
  }  
 }
  }

应用端myProxyTest

  public class MyProxyTest {  
 /**代理模式   * @param args   */  
 public static void main(String[] args)
 {   
//不需要执行额外方法的  
 Italk people1=new People(" people1.talk("No ProXY Test");  
 System.out.println("-----------------------------");  
 //需要执行额外方法的   
TalkProxy talker=new TalkProxy(people1);   
talker.talk("ProXY Test","七里�);
  }  
 }
所谓代理,是指å…ähœ‰ä¸Žä»£ç†å…ƒåQˆè¢«ä»£ç†çš„对象)å…ähœ‰ç›¸åŒçš„æŽ¥å£çš„¾c»ï¼Œå®¢æˆ·ç«¯å¿…™å»é€šè¿‡ä»£ç†ä¸Žè¢«ä»?理的目标¾cÖMº¤äº’,而代理一般在交互的过½E‹ä¸­åQˆäº¤äº’前后)åQŒè¿›è¡ŒæŸäº›ç‰¹åˆ«çš„处理。Proxy模式是很常见的模式,在我们生‹zÖM¸­å¤„处可见åQŒä¾‹å¦‚我们买火èžR¼œ¨ä¸ 一定非要到火èžR站去乎ͼŒå¯ä»¥åˆîC¸€äº›ç«è½¦ç¥¨çš„代售点åŽÖM¹°ã€‚寄信不一定是自己åŽÕd¯„åQŒå¯ä»¥æŠŠä¿¡å§”托给邮局åQŒç”±é‚®å±€æŠŠä¿¡é€åˆ°ç›®çš„地ã€?

代理¾l“构如下图所½C?/p>

Java 代理/动态代理模�Proxy) - stevinzhu - stevinzhu的博� src=

以通过代售点买火èžR¼œ¨äØ“(f¨´)例,代码实现如下åQ?/p>

//提供买票的公共接�br />interface Passenger {
public void buyTicket();
}

//乘客实体
public class RealPassenger implements Passenger {
@Override
public void buyTicket() {
   // TODO Auto-generated method stub
   System.out.print("购买了火车票");
}
}

//代售�br />public class Proxy implements Passenger {
Passenger passenger;

public Proxy(Passenger p) {
   this.passenger = p;
}

@Override
public void buyTicket() {
   // TODO Auto-generated method stub
   System.out.println("通过代售ç‚?);
   passenger.buyTicket();
}
}

//‹¹‹è¯•¾c?br />public class Client {
public static void main(String[] args) {
   Passenger passenger = new RealPassenger();
   Passenger proxy = new Proxy(passenger);
   proxy.buyTicket();
}
}

输出¾l“æžœåQ?br />通过代售ç‚?br />购买了火车票

ä»?ä¸Šçš„ä¹Ÿå¯å«åšé™æ€ä»£ç†ï¼Œæ˜¯äØ“(f¨´)了区别代理模式在Java中的另一¿Uå®žçŽ?#8212;—动态代理ã€?/p>

接下来会(x¨¬)为大家带来动态代ç?br />



]]>跟屌丝大哥一起学ä¹?f¨¤n)设计模å?--中介者模å¼?/title><link>http://www.aygfsteel.com/qileilove/archive/2012/12/12/392858.html</link><dc:creator>™åºå…¶è‡ªç„¶EVO</dc:creator><author>™åºå…¶è‡ªç„¶EVO</author><pubDate>Wed, 12 Dec 2012 05:23:00 GMT</pubDate><guid>http://www.aygfsteel.com/qileilove/archive/2012/12/12/392858.html</guid><wfw:comment>http://www.aygfsteel.com/qileilove/comments/392858.html</wfw:comment><comments>http://www.aygfsteel.com/qileilove/archive/2012/12/12/392858.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/qileilove/comments/commentRss/392858.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/qileilove/services/trackbacks/392858.html</trackback:ping><description><![CDATA[     摘要: 中介者模式(MediatoråQ‰ï¼š(x¨¬)用一个中介对象来ž®è£…一¾pÕdˆ—的对象交互。中介者ä‹Éå„å¯¹è±¡ä¸éœ€è¦æ˜¾å¼åœ°ç›æ€º’引用åQŒä»Žè€Œä‹É其耦合松散åQŒè€Œä¸”可以独立地改变它们之间的交互。通用¾cÕd›¾åQšä‹D例:(x¨¬)在一个公叔R‡Œé¢ï¼Œæœ‰å¾ˆå¤šéƒ¨é—¨ã€å‘˜å·¥ï¼ˆæˆ‘们¾lŸç§°ä»–们互相为Colleague“同事”åQ‰ï¼Œä¸ÞZº†å®Œæˆä¸€å®šçš„ä»ÕdŠ¡åQ?#8220;同事”之间肯定有许多需要互盔R…åˆã€äº¤‹¹çš„˜q‡ç¨‹ã€‚如果由各个“同事...  <a href='http://www.aygfsteel.com/qileilove/archive/2012/12/12/392858.html'>阅读全文</a><img src ="http://www.aygfsteel.com/qileilove/aggbug/392858.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/qileilove/" target="_blank">™åºå…¶è‡ªç„¶EVO</a> 2012-12-12 13:23 <a href="http://www.aygfsteel.com/qileilove/archive/2012/12/12/392858.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>跟屌丝大哥学ä¹?f¨¤n)设计模å?--观察者模å¼?/title><link>http://www.aygfsteel.com/qileilove/archive/2012/12/11/392774.html</link><dc:creator>™åºå…¶è‡ªç„¶EVO</dc:creator><author>™åºå…¶è‡ªç„¶EVO</author><pubDate>Tue, 11 Dec 2012 03:51:00 GMT</pubDate><guid>http://www.aygfsteel.com/qileilove/archive/2012/12/11/392774.html</guid><wfw:comment>http://www.aygfsteel.com/qileilove/comments/392774.html</wfw:comment><comments>http://www.aygfsteel.com/qileilove/archive/2012/12/11/392774.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/qileilove/comments/commentRss/392774.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/qileilove/services/trackbacks/392774.html</trackback:ping><description><![CDATA[<h2><a id="viewpost1_TitleUrl" href="http://www.aygfsteel.com/supercrsky/articles/202544.html" style="color: #0066aa; text-decoration: initial;">Java 观察者模式的‹¹…析</a></h2><div style="font-size: 13px; line-height: 19px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">½Ž€å•地è¯ß_(d¨¢)¼Œè§‚察者模式定义了一个一对多的依赖关¾p»ï¼Œè®©ä¸€ä¸ªæˆ–多个观察者对象监察一个主题对象。这样一个主题对象在状态上的变化能够通知所有的依赖于此对象的那些观察者对象,使这些观察者对象能够自动更新ã€?br /> <strong>观察者模式的¾l“æž„</strong><br /><br />  观察者(ObserveråQ‰æ¨¡å¼æ˜¯å¯¹è±¡çš„行为型模式åQŒåˆå«åšå‘表-订阅åQˆPublish/SubscribeåQ‰æ¨¡å¼ã€æ¨¡åž?视图åQˆModel/ViewåQ‰æ¨¡å¼ã€æº-收听者(Source/ListeneråQ‰æ¨¡å¼æˆ–从属者(DependentsåQ‰æ¨¡å¼ã€?br /><br /> 本模式的¾cÕd›¾¾l“构如下åQ?br /><br /><table width="100%" style="width: 667px;"><tbody><tr><td style="font-size: 12px;"><img height="371" alt="" src="http://www.yesky.com/20020603/observer.gif" width="557" /><br />å›?、观察者模式的静态结构可从类图中看清楚ã€?/td></tr></tbody></table><p style="margin: 10px 0px;">  在观察者模式里有如下的角色åQ?br /> .<strong> æŠ½è±¡ä¸»é¢˜åQˆSubjectåQ‰è§’è‰?/strong>åQšä¸»é¢˜è§’色把所有的观察者对象的引用保存在一个列表里åQ›æ¯ä¸ªä¸»é¢˜éƒ½å¯ä»¥æœ‰ä“Q何数量的观察者。主题提供一个接口可以加上或撤销观察者对象;主题角色又叫做抽象被观察è€?Observable)角色åQ?nbsp;<br /><table width="100%" style="width: 667px;"><tbody><tr><td style="font-size: 12px;"><img height="154" alt="" src="http://www.yesky.com/20020603/role1.gif" width="154" /><br />å›?、抽象主题角è‰ÔŒ¼Œæœ‰æ—¶åˆå«åšæŠ½è±¡è¢«è§‚察者角è‰ÔŒ¼Œå¯ä»¥ç”¨ä¸€ä¸ªæŠ½è±¡ç±»æˆ–者一个接口实玎ͼ›åœ¨å…·ä½“的情况下也不排除ä‹É用具体类实现ã€?/td></tr></tbody></table></p><p style="margin: 10px 0px;">  .<strong> æŠ½è±¡è§‚察者(ObserveråQ‰è§’è‰?/strong>åQšäØ“(f¨´)所有的具体观察者定义一个接口,在得到通知时更新自己; <br /></p><br /><table width="100%" style="width: 667px;"><tbody><tr><td style="font-size: 12px;"><img height="122" alt="" src="http://www.yesky.com/20020603/role3.gif" width="154" /><br />å›?、抽象观察者角è‰ÔŒ¼Œå¯ä»¥ç”¨ä¸€ä¸ªæŠ½è±¡ç±»æˆ–者一个接口实玎ͼ›åœ¨å…·ä½“的情况下也不排除ä‹É用具体类实现ã€?/td></tr></tbody></table><p style="margin: 10px 0px;">  .<strong> å…·ä½“主题åQˆConcreteSubjectåQ‰è§’è‰?/strong>åQšä¿å­˜å¯¹å…·ä½“观察者对象有用的内部状态;在这¿Uå†…部状态改变时¾l™å…¶è§‚察者发å‡ÞZ¸€ä¸ªé€šçŸ¥åQ›å…·ä½“主题角色又叫作具体被观察者角è‰ÔŒ¼›</p><img height="179" alt="" src="http://www.yesky.com/20020603/role2.gif" width="171" style="font-size: 12px; line-height: normal;" /><br style="font-size: 12px; line-height: normal;" /><span style="font-size: 12px; line-height: normal;">å›?、具体主题角è‰ÔŒ¼Œé€šå¸¸ç”¨ä¸€ä¸ªå…·ä½“子¾cÕd®žçްã€?br /><br /></span><p style="margin: 10px 0px;">åQ?strong>具体观察者(ConcreteObserveråQ‰è§’è‰?/strong>åQšä¿å­˜ä¸€ä¸ªæŒ‡å‘具体主题对象的引用åQ›å’Œä¸€ä¸ªä¸Žä¸»é¢˜çš„状态相½W¦çš„状态。具体观察者角色实现抽象观察者角色所要求的更新自å·Þqš„æŽ¥å£åQŒä»¥ä¾¿ä‹É本èín的状态与主题的状态自恰ã€?nbsp;<br /></p><table width="100%" style="width: 667px;"><tbody><tr><td style="font-size: 12px;"><img height="122" alt="" src="http://www.yesky.com/20020603/role4.gif" width="160" /><br />å›?、具体观察者角è‰ÔŒ¼Œé€šå¸¸ç”¨ä¸€ä¸ªå…·ä½“子¾cÕd®žçްã€?/td></tr></tbody></table><span style="font-size: 12px; line-height: normal;"><br /></span><p style="margin: 10px 0px;">下面¾l™å‡ºä¸€ä¸ªç¤ºæ„æ€§å®žçŽ°çš„Java代码。首先在˜q™ä¸ª½Cºæ„æ€§çš„实现里,用一个Java接口实现抽象主题角色åQŒè¿™ž®±æ˜¯ä¸‹é¢çš„Subject接口åQ?br /></p><table width="100%" bgcolor="#ffffff" style="width: 667px;"><tbody><tr><td style="font-size: 12px;"><br />public interface Subject<br />{<br />public void attach(Observer observer);<br /><br />public void detach(Observer observer);<br /><br />void notifyObservers();<br />}<br /></td></tr></tbody></table>代码清单1、Subject接口的源代码ã€?nbsp;<br /><br />  ˜q™ä¸ªæŠ½è±¡ä¸»é¢˜æŽ¥å£è§„定å‡ÞZ¸‰ä¸ªå­¾cÕd¿…™åÕd®žçŽ°çš„æ“ä½œåQŒå³ attach() 用来增加一个观察者对象;detach() 用来删除一个观察者对象;和notifyObservers() ç”¨æ¥é€šçŸ¥å„ä¸ªè§‚å¯Ÿè€…åˆ·æ–°å®ƒä»¬è‡ªå·±ã€‚æŠ½è±¡ä¸»é¢˜è§’è‰²å®žé™…ä¸Šè¦æ±‚å­ç±»ä¿æŒä¸€ä¸ªä»¥æ‰€æœ‰çš„è§‚å¯Ÿè€…å¯¹è±¡äØ“(f¨´)元素的列表ã€?br /><br />  具体主题则是实现了抽象主题Subject接口的一个具体类åQŒå®ƒ¾l™å‡ºäº†ä»¥ä¸Šçš„三个操作的具体实现。从下面的源代码可以看出åQŒè¿™é‡Œç»™å‡ºçš„Java实现使用了一个Java向量来保存所有的观察者对象,è€?attach() å’?detach() 操作则是å¯ÒŽ(gu¨©)­¤å‘量的元素增减操作ã€?br /><br /><table width="100%" bgcolor="#ffffff" style="width: 667px;"><tbody><tr><td style="font-size: 12px;"><br />import java.util.Vector;<br />import java.util.Enumeration;<br /><br />public class ConcreteSubject implements Subject<br />{<br />public void attach(Observer observer)<br />{<br />observersVector.addElement(observer);<br />}<br /><br />public void detach(Observer observer)<br />{<br />observersVector.removeElement(observer);<br />}<br /><br />public void notifyObservers()<br />{<br />Enumeration enumeration = observers();<br />while (enumeration.hasMoreElements())<br />{<br />((Observer)enumeration.nextElement()).update();<br />}<br />}<br /><br />public Enumeration observers()<br />{<br />return (åQˆVector) observersVector.clone()).elements();<br />}<br />private Vector observersVector = new java.util.Vector();<br />}<br /></td></tr></tbody></table>代码清单2、ConcreteSubject¾cÈš„æºä»£ç ã€?nbsp;<br />  抽象观察者角色的实现实际上是最为简单的一个,它是一个Java接口åQŒåªå£°æ˜Žäº†ä¸€ä¸ªæ–¹æ³•,即update()。这个方法被子类实现后,一被调用便åˆäh–°è‡ªå·±ã€?br /><br /><table width="100%" bgcolor="#ffffff" style="width: 667px;"><tbody><tr><td style="font-size: 12px;">public interface Observer<br />{<br />void update();<br />}</td></tr></tbody></table>代码清单3、Observer接口的源代码ã€?nbsp;<br /><br />  具体观察者角色的实现其实只涉å?qi¨¢ng)update()æ–ÒŽ(gu¨©)³•的实现。这个方法怎么实现与应用密切相养I¼Œå› æ­¤æœ¬ç±»åªç»™å‡ÞZ¸€ä¸ªæ¡†æž¶ã€?br /><table width="100%" bgcolor="#ffffff" style="width: 667px;"><tbody><tr><td style="font-size: 12px;">public class ConcreteObserver implements Observer<br />{<br />public void update()<br />{<br />// Write your code here<br />}<br />}</td></tr></tbody></table>代码清单4、ConcreteObserver¾cÈš„æºä»£ç ã€?nbsp;<br /><br />  虽然观察者模式的实现æ–ÒŽ(gu¨©)³•可以有设计师自己¼‹®å®šåQŒä½†æ˜¯å› ä¸ÞZ»ŽAWT1.1开始视½H—ç³»¾lŸçš„事äšg模型采用观察者模式,因此观察者模式在Java语言里的åœîC½è¾ƒäØ“(f¨´)é‡è¦ã€‚æ­£å› äØ“(f¨´)˜q™ä¸ªåŽŸå› åQŒJava语言¾l™å‡ºäº†å®ƒè‡ªå·±å¯¹è§‚å¯Ÿè€…æ¨¡å¼çš„æ”¯æŒã€‚å› æ­¤ï¼Œæœ¬æ–‡å»ø™®®è¯»è€…在自己的系¾lŸä¸­åº”用观察者模式时åQŒä¸å¦¨åˆ©ç”¨Java语言所提供的支持ã€?br />  <strong>Java语言提供的对观察者模式的支持</strong><br /><br />  在Java语言的java.util库里面,提供了一个Observable¾cÖM»¥å?qi¨¢ng)一个Observer接口åQŒæž„成Java语言对观察者模式的支持ã€?br /><br />  <strong>Observer接口</strong><br /><br />  ˜q™ä¸ªæŽ¥å£åªå®šä¹‰äº†ä¸€ä¸ªæ–¹æ³•,update()。当被观察者对象的状态发生变化时åQŒè¿™ä¸ªæ–¹æ³•å°±ä¼?x¨¬)被调用。这个方法的实现应当调用每一个被观察者对象的notifyObservers()æ–ÒŽ(gu¨©)³•åQŒä»Žè€Œé€šçŸ¥æ‰€æœ‰çš„观察对象ã€?br /><br /><table width="100%" style="width: 667px;"><tbody><tr><td style="font-size: 12px;"><img height="115" alt="" src="http://www.yesky.com/20020603/observerinterface.gif" width="258" /><br />å›?、java.util提供的Observer接口的类图ã€?/td></tr></tbody></table><br /><table width="100%" bgcolor="#ffffff" style="width: 667px;"><tbody><tr><td style="font-size: 12px;"><br />package java.util;<br /><br />public interface Observer<br />{<br />/**<br />* 当被观察的对象发生变化时åQŒè¿™ä¸ªæ–¹æ³•会(x¨¬)被调用ã€?br />*/<br />void update(Observable o, Object arg);<br />}<br /></td></tr></tbody></table>代码清单5、java.util.Observer接口的源代码ã€?nbsp;<br /><br />  <strong>Observable¾c?/strong><br /><br />  被观察者类都是java.util.Observable¾cȝš„子类。java.util.Observable提供公开的方法支持观察者对象,˜q™äº›æ–ÒŽ(gu¨©)³•中有两个对Observable的子¾c»éžå¸”R‡è¦ï¼š(x¨¬)一个是setChanged()åQŒå¦ä¸€ä¸ªæ˜¯notifyObservers()。第一个方法setChanged()被调用之后会(x¨¬)讄¡½®ä¸€ä¸ªå†…部标记变量,代表被观察者对象的状态发生了变化。第二个是notifyObservers()åQŒè¿™ä¸ªæ–¹æ³•被调用æ—Óž¼Œä¼?x¨¬)调用所有登记过的观察者对象的update()æ–ÒŽ(gu¨©)³•åQŒä‹É˜q™äº›è§‚察者对象可以更新自己ã€?br /><br />  java.util.Observable¾c»è¿˜æœ‰å…¶å®ƒçš„一些重要的æ–ÒŽ(gu¨©)³•。比如,观察者对象可以调用java.util.Observable¾cȝš„addObserver()æ–ÒŽ(gu¨©)³•åQŒå°†å¯¹è±¡ä¸€ä¸ªä¸€ä¸ªåŠ å…¥åˆ°ä¸€ä¸ªåˆ—è¡¨ä¸Šã€‚å½“æœ‰å˜åŒ–æ—¶åQŒè¿™ä¸ªåˆ—表可以告诉notifyObservers()æ–ÒŽ(gu¨©)³•那些观察者对象需要通知。由于这个列表是¿Uæœ‰çš„,因此java.util.Observable的子对象òq¶ä¸çŸ¥é“观察者对象一直在观察着它们ã€?br /><br /><table width="100%" style="width: 667px;"><tbody><tr><td style="font-size: 12px;"><img height="281" alt="" src="http://www.yesky.com/20020603/observable.gif" width="223" /><br />å›?、Java语言提供的被观察者的¾cÕd›¾ã€?/td></tr></tbody></table><br />  被观察者类Observable的源代码åQ?br /><br /><span style="line-height: normal; color: #0000ff;">package</span><span style="line-height: normal;"> java.util;<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/None.gif" align="top" alt="" /></span><span style="line-height: normal; color: #0000ff;">public</span> <span style="line-height: normal; color: #0000ff;">class</span><span style="line-height: normal;"> Observable<br /><img id="Codehighlighter1_44_1304_Open_Image" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top" alt="" /></span><span id="Codehighlighter1_44_1304_Open_Text" style="line-height: normal;">{<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">boolean</span> changed = <span style="color: #0000ff;">false</span>;<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><span style="color: #0000ff;">private</span> Vector obs;<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><br /><img id="Codehighlighter1_100_121_Open_Image" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" alt="" /><span id="Codehighlighter1_100_121_Open_Text"><span style="color: #008000;">/**</span><span style="color: #008000;"> ç”?个观察者构造一个被观察者ã€?</span><span style="color: #008000;">*/</span></span><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><span style="color: #0000ff;">public</span> Observable()<br /><img id="Codehighlighter1_144_166_Open_Image" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" alt="" /><span id="Codehighlighter1_144_166_Open_Text">{<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" />obs = <span style="color: #0000ff;">new</span> Vector();<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" alt="" />}</span><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><br /><img id="Codehighlighter1_169_193_Open_Image" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" alt="" /><span id="Codehighlighter1_169_193_Open_Text"><span style="color: #008000;">/**</span><span style="color: #008000;"><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" />* ž®†ä¸€ä¸ªè§‚察者加到观察者列表上面ã€?br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" alt="" /></span><span style="color: #008000;">*/</span></span><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">synchronized</span> <span style="color: #0000ff;">void</span> addObserver(Observer o)<br /><img id="Codehighlighter1_244_291_Open_Image" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" alt="" /><span id="Codehighlighter1_244_291_Open_Text">{<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><span style="color: #0000ff;">if</span> (!obs.contains(o))<br /><img id="Codehighlighter1_268_289_Open_Image" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" alt="" /><span id="Codehighlighter1_268_289_Open_Text">{<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" />obs.addElement(o);<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" alt="" />}</span><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" alt="" />}</span><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><br /><img id="Codehighlighter1_294_320_Open_Image" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" alt="" /><span id="Codehighlighter1_294_320_Open_Text"><span style="color: #008000;">/**</span><span style="color: #008000;"><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" />* ž®†ä¸€ä¸ªè§‚察者对象从观察者列表上删除ã€?br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" alt="" /></span><span style="color: #008000;">*/</span></span><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">synchronized</span> <span style="color: #0000ff;">void</span> deleteObserver(Observer o)<br /><img id="Codehighlighter1_374_398_Open_Image" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" alt="" /><span id="Codehighlighter1_374_398_Open_Text">{<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" />obs.removeElement(o);<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" alt="" />}</span><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><br /><img id="Codehighlighter1_401_434_Open_Image" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" alt="" /><span id="Codehighlighter1_401_434_Open_Text"><span style="color: #008000;">/**</span><span style="color: #008000;"><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" />* ç›¸å½“äº?nbsp;notifyObservers(null)<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" alt="" /></span><span style="color: #008000;">*/</span></span><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> notifyObservers()<br /><img id="Codehighlighter1_466_491_Open_Image" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" alt="" /><span id="Codehighlighter1_466_491_Open_Text">{<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" />notifyObservers(<span style="color: #0000ff;">null</span>);<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" alt="" />}</span><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><br /><img id="Codehighlighter1_494_590_Open_Image" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" alt="" /><span id="Codehighlighter1_494_590_Open_Text"><span style="color: #008000;">/**</span><span style="color: #008000;"><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" />* å¦‚果本对象有变化åQˆé‚£æ—¶hasChanged æ–ÒŽ(gu¨©)³•ä¼?x¨¬)返回trueåQ?br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" />* è°ƒç”¨æœ¬æ–¹æ³•通知所有登记在案的观察者,卌™°ƒç”¨å®ƒä»¬çš„update()æ–ÒŽ(gu¨©)³•åQ?br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" />* ä¼ å…¥thiså’Œargä½œäØ“(f¨´)参量ã€?br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" alt="" /></span><span style="color: #008000;">*/</span></span><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> notifyObservers(Object arg)<br /><img id="Codehighlighter1_632_861_Open_Image" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" alt="" /><span id="Codehighlighter1_632_861_Open_Text">{<br /><img id="Codehighlighter1_634_664_Open_Image" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" alt="" /><span id="Codehighlighter1_634_664_Open_Text"><span style="color: #008000;">/**</span><span style="color: #008000;"><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" />* ä¸´æ—¶å­˜æ”¾å½“前的观察者的状态。参见备忘录模式ã€?br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" alt="" /></span><span style="color: #008000;">*/</span></span><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" />Object[] arrLocal;<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><span style="color: #0000ff;">synchronized</span> (<span style="color: #0000ff;">this</span>)<br /><img id="Codehighlighter1_706_772_Open_Image" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" alt="" /><span id="Codehighlighter1_706_772_Open_Text">{<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><span style="color: #0000ff;">if</span> (!changed) <span style="color: #0000ff;">return</span>;<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" />arrLocal = obs.toArray();<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" />clearChanged();<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" alt="" />}</span><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = arrLocal.length-1; i>=0; i--)<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" />((Observer)arrLocal[i]).update(<span style="color: #0000ff;">this</span>, arg);<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" alt="" />}</span><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><br /><img id="Codehighlighter1_864_880_Open_Image" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" alt="" /><span id="Codehighlighter1_864_880_Open_Text"><span style="color: #008000;">/**</span><span style="color: #008000;"><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" />* ž®†è§‚察者列表清½I?br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" alt="" /></span><span style="color: #008000;">*/</span></span><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">synchronized</span> <span style="color: #0000ff;">void</span> deleteObservers()<br /><img id="Codehighlighter1_925_952_Open_Image" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" alt="" /><span id="Codehighlighter1_925_952_Open_Text">{<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" />obs.removeAllElements();<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" alt="" />}</span><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><br /><img id="Codehighlighter1_955_975_Open_Image" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" alt="" /><span id="Codehighlighter1_955_975_Open_Text"><span style="color: #008000;">/**</span><span style="color: #008000;"><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" />* ž®?#8220;已变åŒ?#8221;è®¾äØ“(f¨´)true<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" alt="" /></span><span style="color: #008000;">*/</span></span><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><span style="color: #0000ff;">protected</span> <span style="color: #0000ff;">synchronized</span> <span style="color: #0000ff;">void</span> setChanged()<br /><img id="Codehighlighter1_1018_1036_Open_Image" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" alt="" /><span id="Codehighlighter1_1018_1036_Open_Text">{<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" />changed = <span style="color: #0000ff;">true</span>;<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" alt="" />}</span><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><br /><img id="Codehighlighter1_1039_1061_Open_Image" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" alt="" /><span id="Codehighlighter1_1039_1061_Open_Text"><span style="color: #008000;">/**</span><span style="color: #008000;"><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" />* ž®?#8220;已变åŒ?#8221;重置为false<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" alt="" /></span><span style="color: #008000;">*/</span></span><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><span style="color: #0000ff;">protected</span> <span style="color: #0000ff;">synchronized</span> <span style="color: #0000ff;">void</span> clearChanged()<br /><img id="Codehighlighter1_1106_1125_Open_Image" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" alt="" /><span id="Codehighlighter1_1106_1125_Open_Text">{<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" />changed = <span style="color: #0000ff;">false</span>;<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" alt="" />}</span><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><br /><img id="Codehighlighter1_1128_1146_Open_Image" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" alt="" /><span id="Codehighlighter1_1128_1146_Open_Text"><span style="color: #008000;">/**</span><span style="color: #008000;"><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" />* æŽ¢æµ‹æœ¬å¯¹è±¡æ˜¯å¦å·²å˜åŒ–<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" alt="" /></span><span style="color: #008000;">*/</span></span><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">synchronized</span> <span style="color: #0000ff;">boolean</span> hasChanged()<br /><img id="Codehighlighter1_1189_1207_Open_Image" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" alt="" /><span id="Codehighlighter1_1189_1207_Open_Text">{<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><span style="color: #0000ff;">return</span> changed;<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" alt="" />}</span><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><br /><img id="Codehighlighter1_1210_1238_Open_Image" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" alt="" /><span id="Codehighlighter1_1210_1238_Open_Text"><span style="color: #008000;">/**</span><span style="color: #008000;"><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" />* ˜q”还被观察对象(åÏx­¤å¯¹è±¡åQ‰çš„观察者æ€ÀL•°ã€?br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" alt="" /></span><span style="color: #008000;">*/</span></span><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">synchronized</span> <span style="color: #0000ff;">int</span> countObservers()<br /><img id="Codehighlighter1_1281_1302_Open_Image" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" alt="" /><span id="Codehighlighter1_1281_1302_Open_Text">{<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><span style="color: #0000ff;">return</span> obs.size();<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" alt="" />}</span><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" alt="" />}</span><span style="line-height: normal;"><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/None.gif" align="top" alt="" /><br /></span>代码清单6、java.util.Observer接口的源代码ã€?nbsp;<br /><br />  ˜q™ä¸ªObservable¾cÖM»£è¡¨ä¸€ä¸ªè¢«è§‚察者对象。一个被观察者对象可以有æ•îC¸ªè§‚察者对象,一个观察者可以是一个实现Observer接口的对象。在被观察者对象发生变化时åQŒå®ƒä¼?x¨¬)调用Observableçš„notifyObserversæ–ÒŽ(gu¨©)³•åQŒæ­¤æ–ÒŽ(gu¨©)³•调用所有的具体观察者的update()æ–ÒŽ(gu¨©)³•åQŒä»Žè€Œä‹É所有的观察者都被通知更新自己。见下面的类图:(x¨¬)<br /><br /><table width="100%" style="width: 667px;"><tbody><tr><td style="font-size: 12px;"><img height="211" alt="" src="http://www.yesky.com/20020603/javautilmethods.gif" width="585" /><br />å›?、ä‹É用Java语言提供的对观察者模式的支持ã€?/td></tr></tbody></table><br />  发通知的次序在˜q™é‡Œæ²¡æœ‰æŒ‡æ˜Žã€‚Observerable¾cÀL‰€æä¾›çš„缺省实çŽîC¼š(x¨¬)按照Observers对象被登记的‹Æ¡åºé€šçŸ¥å®ƒä»¬åQŒä½†æ˜¯Observerable¾cȝš„子类可以æ”ÒŽ(gu¨©)މ˜q™ä¸€‹Æ¡åºã€‚子¾cÕdƈ可以在单独的¾U¿ç¨‹é‡Œé€šçŸ¥è§‚察者对象;或者在一个公用的¾U¿ç¨‹é‡ŒæŒ‰ç…§æ¬¡åºæ‰§è¡Œã€?nbsp;<br /><br />  当一个可观察者对象刚刚创立时åQŒå®ƒçš„观察者集合是½Iºçš„。两个观察者对象在它们的equals()æ–ÒŽ(gu¨©)³•˜q”回trueæ—Óž¼Œè¢«è®¤ä¸ºæ˜¯ä¸¤ä¸ªç›¸ç­‰çš„对象ã€?nbsp;<br />  <strong>怎样使用Java对观察者模式的支持</strong><br /><br />  ä¸ÞZº†è¯´æ˜Žæ€Žæ ·ä½¿ç”¨Java所提供的对观察者模式的支持åQŒæœ¬èŠ‚ç»™å‡ÞZ¸€ä¸ªéžå¸¸ç®€å•的例子。在˜q™ä¸ªä¾‹å­é‡Œï¼Œè¢«è§‚察对象叫做WatchedåQŒä¹Ÿž®±æ˜¯è¢«ç›‘视者;而观察者对象叫做Watcher。Watched对象¾l§æ‰¿è‡ªjava.util.Obsevable¾c»ï¼›è€ŒW(xu¨¦)atcher对象实现了java.util.Observer接口。另外有一个对象TesteråQŒæ‰®æ¼”客æˆïL(f¨¥ng)«¯çš„角艌Ӏ?nbsp;<br /><br />  ˜q™ä¸ª½Ž€å•çš„¾pȝ»Ÿçš„结构如下图所½Cºã€?nbsp;<br /><br /><table width="100%" style="width: 667px;"><tbody><tr><td style="font-size: 12px;"><img height="371" alt="" src="http://www.yesky.com/20020603/watching.gif" width="511" /><br />å›?、一个ä‹É用Observer接口和Observable¾cȝš„例子ã€?/td></tr></tbody></table><br />  在客æˆïL(f¨¥ng)«¯æ”¹å˜Watched对象的内部状态时åQŒW(xu¨¦)atchedž®×ƒ¼š(x¨¬)通知Watcher采取必要的行动ã€?nbsp;<br /><span style="line-height: normal;"><br /></span><table width="100%" bgcolor="#ffffff" style="width: 667px;"><tbody><tr><td style="font-size: 12px;"><br /><div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; font-size: 13px; width: 647.7666625976563px; word-break: break-all; background-color: #eeeeee;"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/None.gif" align="top" alt="" /><span style="color: #0000ff;">package</span> com.javapatterns.observer.watching;<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/None.gif" align="top" alt="" /><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/None.gif" align="top" alt="" /><span style="color: #0000ff;">import</span> java.util.Observer;<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/None.gif" align="top" alt="" /><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/None.gif" align="top" alt="" /><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> Tester<br /><img id="Codehighlighter1_93_466_Open_Image" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top" alt="" /><span id="Codehighlighter1_93_466_Open_Text">{<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><span style="color: #0000ff;">static</span> <span style="color: #0000ff;">private</span> Watched watched;<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><span style="color: #0000ff;">static</span> <span style="color: #0000ff;">private</span> Observer watcher;<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> main(String[] args)<br /><img id="Codehighlighter1_200_464_Open_Image" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" alt="" /><span id="Codehighlighter1_200_464_Open_Text">{<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" />watched = <span style="color: #0000ff;">new</span> Watched();<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" />watcher = <span style="color: #0000ff;">new</span> Watcher(watched);<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" />watched.changeData("In C, we create bugs.");<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" />watched.changeData("In Java, we inherit bugs.");<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" />watched.changeData("In Java, we inherit bugs.");<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" />watched.changeData("In Visual Basic, we visualize bugs."); <br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" alt="" />}</span><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" alt="" />}</span><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/None.gif" align="top" alt="" /></div></td></tr></tbody></table><br />  代码清单7、Tester¾cÈš„æºä»£ç ã€?nbsp;<br /><span style="line-height: normal;"><br /><br /></span> 代码清单7、Tester¾cÈš„æºä»£ç ã€?nbsp;<br /><br /><table width="100%" bgcolor="#ffffff" style="width: 667px;"><tbody><tr><td style="font-size: 12px;"><br /><div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; font-size: 13px; width: 647.7666625976563px; word-break: break-all; background-color: #eeeeee;"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/None.gif" align="top" alt="" /><span style="color: #0000ff;">package</span> com.javapatterns.observer.watching;<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/None.gif" align="top" alt="" /><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/None.gif" align="top" alt="" /><span style="color: #0000ff;">import</span> java.util.Observable;<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/None.gif" align="top" alt="" /><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/None.gif" align="top" alt="" /><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> Watched <span style="color: #0000ff;">extends</span> Observable<br /><img id="Codehighlighter1_115_319_Open_Image" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top" alt="" /><span id="Codehighlighter1_115_319_Open_Text">{<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><span style="color: #0000ff;">private</span> String data = "";<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><span style="color: #0000ff;">public</span> String retrieveData()<br /><img id="Codehighlighter1_173_188_Open_Image" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" alt="" /><span id="Codehighlighter1_173_188_Open_Text">{<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><span style="color: #0000ff;">return</span> data;<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" alt="" />}</span><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> changeData(String data)<br /><img id="Codehighlighter1_227_317_Open_Image" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" alt="" /><span id="Codehighlighter1_227_317_Open_Text">{<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><span style="color: #0000ff;">if</span> ( !<span style="color: #0000ff;">this</span>.data.equals( data) )<br /><img id="Codehighlighter1_261_295_Open_Image" src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" alt="" /><span id="Codehighlighter1_261_295_Open_Text">{<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><span style="color: #0000ff;">this</span>.data = data;<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" />setChanged();<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" alt="" />}</span><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" /><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/InBlock.gif" align="top" alt="" />notifyObservers();<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" alt="" />}</span><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" alt="" />}</span></div></td></tr></tbody></table><br /><br />代码清单9、Watcher¾cÈš„æºä»£ç ã€?nbsp;<br /><br />  可以看出åQŒè™½ç„¶å®¢æˆïL(f¨¥ng)«¯ž®†Watched对象的内部状态赋å€égº†å››æ¬¡åQŒä½†æ˜¯å€¼çš„æ”¹å˜åªæœ‰ä¸‰æ¬¡åQ?br /><br /><table width="100%" bgcolor="#ffffff" style="width: 667px;"><tbody><tr><td style="font-size: 12px;"><div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; font-size: 13px; width: 647.7666625976563px; word-break: break-all; background-color: #eeeeee;"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/None.gif" align="top" alt="" />watched.changeData("In C, we create bugs.");<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/None.gif" align="top" alt="" />watched.changeData("In Java, we inherit bugs.");<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/None.gif" align="top" alt="" />watched.changeData("In Java, we inherit bugs.");<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/None.gif" align="top" alt="" />watched.changeData("In Visual Basic, we visualize bugs."); </div></td></tr></tbody></table><br />  代码清单10、被观察者的内部状态发生了改变ã€?nbsp;<br /><br />  对应圎ͼŒW(xu¨¦)atcher对象汇报了三‹Æ¡æ”¹å˜ï¼Œä¸‹é¢ž®±æ˜¯˜qè¡Œæ—‰™—´½E‹åºæ‰“印出的信息åQ?br /><table width="100%" bgcolor="#ffffff" style="width: 667px;"><tbody><tr><td style="font-size: 12px;"><br /><div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; font-size: 13px; width: 647.7666625976563px; word-break: break-all; background-color: #eeeeee;"><img src="http://www.aygfsteel.com/Images/OutliningIndicators/None.gif" align="top" alt="" />Data has been changed to: 'In C, we create bugs.'<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/None.gif" align="top" alt="" /><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/None.gif" align="top" alt="" />Data has been changed to: 'In Java, we inherit bugs.'<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/None.gif" align="top" alt="" /><br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/None.gif" align="top" alt="" />Data has been changed to: 'In Visual Basic, we visualize bugs.'<br /><img src="http://www.aygfsteel.com/Images/OutliningIndicators/None.gif" align="top" alt="" /></div></td></tr></tbody></table><br />  代码清单11、运行的¾l“æžœã€?nbsp;<br /><br /> <strong>菩萨的守瓉™¾Ÿ</strong><br /><br />  惛_½“òq´é½å¤©å¤§åœ£äØ“(f¨´)解救师傅唐僧åQŒå‰å¾€å—æ“v普陀å±Þp¯·è©è¨é™ä¼å¦–怪红孩儿åQ?#8220;菩萨听说...恨了一壎ͼŒž®†æ‰‹ä¸­å®ç å‡€ç“¶å¾€‹¹·å¿ƒé‡Œæ‰‘的一æŽ?..只见那æ“v当中åQŒç¿»æ³¢èŸ©‹¹ªï¼Œé’Õd‡ºä¸ªç“¶æ¥ï¼ŒåŽŸæ¥æ˜¯ä¸€ä¸ªæ€ªç‰©é©®ç€å‡ºæ¥...要知此怪名和姓åQŒå…´é£Žä½œ‹¹ªæ¶ä¹Œé¾Ÿã€?#8221; <br /><br />  使用面向对象的语­a€æè¿°åQŒä¹Œé¾Ÿä¾¿æ˜¯ä¸€ä¸ªè§‚察者对象,它观察的主题是菩萨。一旦菩萨将净瓶掼到æ“v里,ž®Þp±¡å¾ç€è©è¨ä½œäØ“(f¨´)主题调用了notifyObservers()æ–ÒŽ(gu¨©)³•。在西游è®îC¸­åQŒè§‚察者对象有两个åQŒä¸€ä¸ªæ˜¯ä¹Œé¾ŸåQŒå¦ä¸€ä¸ªæ˜¯æ‚(zh¨¨n)Ÿç©ºã€‚æ?zh¨¨n)Ÿ½Iºçš„反应在这里暂时不考虑åQŒè€Œä¹Œé¾Ÿçš„反应便是ž®†ç“¶å­é©®å›žæ“v岸ã€?nbsp;<br /><br /><table width="100%" style="width: 667px;"><tbody><tr><td style="font-size: 12px;"><img height="184" alt="" src="http://www.yesky.com/20020603/turtle.gif" width="447" /><br />å›?0、菩萨和菩萨的守瓶乌龟ã€?/td></tr></tbody></table><strong>Java中的DEM事äšg机制</strong><br /><br />  <strong>AWT中的DEM机制</strong><br /><br />  责ä“Q链模式一章中曾谈刎ͼŒAWT1.0的事件处理的模型是基于责任链的。这¿Uæ¨¡åž‹ä¸é€‚用于复杂的¾pȝ»ŸåQŒå› æ­¤åœ¨AWT1.1版本å?qi¨¢ng)以后的各个版本中,事äšgå¤„ç†æ¨¡åž‹å‡äØ“(f¨´)åŸÞZºŽè§‚察者模式的委派事äšg模型åQˆDelegation Event Model或DEMåQ‰ã€?nbsp;<br /><br />  在DEM模型里面åQŒä¸»é¢˜ï¼ˆSubjectåQ‰è§’色负责发布(publishåQ‰äº‹ä»Óž¼Œè€Œè§‚察者角色向特定的主题订阅(subscribeåQ‰å®ƒæ‰€æ„Ÿå…´­‘£çš„事äšg。当一个具体主题äñ”生一个事件时åQŒå®ƒ?y¨­u)®×ƒ¼?x¨¬)通知所有感兴趣的订阅者ã€?nbsp;<br /><br />  使用˜q™ç§å‘布-订阅机制的基本设计目标,是提供一¿Uå°†å‘布者与订阅者松散地耦合在一èµïL(f¨¥ng)š„联系形式åQŒä»¥å?qi¨¢ng)一¿Uèƒ½å¤ŸåŠ¨æ€åœ°ç™»è®°ã€å–æ¶ˆå‘ä¸€ä¸ªå‘å¸ƒè€…çš„è®¢é˜…è¯äh±‚的办法。显ç„Óž¼Œå®žçް˜q™ä¸€æž„思的技巧,是设计抽象接口,òq¶æŠŠæŠ½è±¡å±‚和具体层分开。这在观察者模式里可以清楚地看到ã€?nbsp;<br /><br />  使用DEM的用词,发布者叫做事件源åQˆevent sourceåQ‰ï¼Œè€Œè®¢é˜…者叫做事件聆听者(event listeneråQ‰ã€‚在Java里面åQŒäº‹ä»¶ç”±¾cÖM»£è¡¨ï¼Œäº‹äšg的发布是通过同步地调用成员方法做到的ã€?nbsp;<br /><br />  <strong>Servlet技术中的的DEM机制</strong><br /><br />  AWT中所使用的DEM事äšg模型实际上被应用åˆîCº†æ‰€æœ‰çš„Java事äšg机制上。Servlet技术中的事件处理机制同样也是ä‹É用的DEM模型ã€?nbsp;<br /><br />  <strong>SAX2技术中的DEM机制</strong><br /><br />  DEM事äšg模型也被应用åˆîCº†SAX2的事件处理机制上ã€?nbsp;<br /><br />  <strong>观察者模式的效果</strong><br /><br />  观察者模式的效果有以下的<strong>优点</strong>åQ?nbsp;<br /><br />  ½W¬ä¸€ã€è§‚察者模式在被观察者和观察者之间徏立一个抽象的耦合。被观察者角色所知道的只是一个具体观察者列表,每一个具体观察者都½W¦åˆä¸€ä¸ªæŠ½è±¡è§‚å¯Ÿè€…çš„æŽ¥å£ã€‚è¢«è§‚å¯Ÿè€…åÆˆä¸è®¤è¯†ä“Q何一个具体观察者,它只知道它们都有一个共同的接口ã€?nbsp;<br /><br />  ç”׃ºŽè¢«è§‚å¯Ÿè€…å’Œè§‚å¯Ÿè€…æ²¡æœ‰ç´§å¯†åœ°è€¦åˆåœ¨ä¸€èµøP¼Œå› æ­¤å®ƒä»¬å¯ä»¥å±žäºŽä¸åŒçš„æŠ½è±¡åŒ–层次。如果被观察者和观察者都被扔åˆîC¸€èµøP¼Œé‚£ä¹ˆ˜q™ä¸ªå¯¹è±¡å¿…然跨越抽象化和具体化层‹Æ¡ã€?nbsp;<br /><br />  ½W¬äºŒã€è§‚察者模式支持广播通讯。被观察者会(x¨¬)向所有的登记˜q‡çš„观察者发出通知åQ?nbsp;<br /><br />  观察者模式有下面çš?strong>¾~ºç‚¹</strong>åQ?nbsp;<br /><br />  ½W¬ä¸€ã€å¦‚果一个被观察者对象有很多的直接和间接的观察者的话,ž®†æ‰€æœ‰çš„观察者都通知åˆîC¼š(x¨¬)èŠÞp´¹å¾ˆå¤šæ—‰™—´ã€?nbsp;<br /><br />  ½W¬äºŒã€å¦‚果在被观察者之间有循环依赖的话åQŒè¢«è§‚察者会(x¨¬)触发它们之间˜q›è¡Œå¾ªçŽ¯è°ƒç”¨åQŒå¯¼è‡´ç³»¾lŸå´©æºƒã€‚在使用观察者模式是要特别注意这一炏V€?nbsp;<br /><br />  ½W¬ä¸‰ã€å¦‚果对观察者的通知是通过另外的线½E‹è¿›è¡Œå¼‚步投递的话,¾pȝ»Ÿå¿…须保证投递是以自恰的方式˜q›è¡Œçš„ã€?nbsp;<br /><br />  ½W¬å››ã€è™½ç„¶è§‚察者模式可以随时ä‹É观察者知道所观察的对象发生了变化åQŒä½†æ˜¯è§‚察者模式没有相应的机制使观察者知道所观察的对象是怎么发生变化的ã€?nbsp;<br /><br />  <strong>观察者模式与其它模式的关¾p?/strong><br /><br />  观察者模式ä‹É用了备忘录模å¼?Memento Pattern)暂时ž®†è§‚察者对象存储在被观察者对象里面ã€?br /><br />  <strong>问答é¢?/strong><br /><br />  ½W¬ä¸€é¢˜ã€æˆ‘和妹妹跟妈妈è¯ß_(d¨¢)¼š(x¨¬)“妈妈åQŒæˆ‘和妹妹在院子里玩åQ›é¥­åšå¥½äº†å«æˆ‘们一声ã€?#8221;请问˜q™æ˜¯ä»€ä¹ˆæ¨¡å¼ï¼Ÿèƒ½å¦¾l™å‡º¾cÕd›¾è¯´æ˜ŽåQ?br /><br />  <strong>问答题答æ¡?/strong><br /><br />  ½W¬ä¸€é¢˜ç­”案、这是观察者模式。我和妹妹让妈妈告诉我们饭做好了åQŒè¿™æ ähˆ‘们就可以来吃饭了。换用较为技术化的语­a€æ¥è¯´åQŒå½“¾pȝ»Ÿçš„主题(饭)发生变化æ—Óž¼Œž®±å‘Šè¯‰ç³»¾lŸçš„其它部䆾åQˆè§‚察者们åQŒä¹Ÿž®±æ˜¯å¦ˆå¦ˆã€æˆ‘和妹妹)åQŒä‹É其可以调整内部状态(有开始吃饭的准备åQ‰ï¼Œòq‰™‡‡å–相应的行动åQˆåƒé¥­ï¼‰ã€?br /><br />  ¾pȝ»Ÿçš„类图说明如下ã€?br /><br /><table width="100%" style="width: 667px;"><tbody><tr><td style="font-size: 12px;"><img height="248" alt="" src="http://www.yesky.com/20020603/dinner.gif" width="402" /><br />å›?1、系¾lŸçš„¾cÕd›¾ã€?/td></tr></tbody></table><br /><br /><div fc05="" fc11="" nbw-blog="" ztag="" js-fs2"="" style="line-height: 25px; font-size: 14px; word-wrap: break-word; color: #8b8989; margin: 15px 0px; padding-top: 5px; padding-bottom: 5px; overflow: hidden; font-family: Arial, Helvetica, simsun, u5b8bu4f53; background-color: #000000;"><p style="margin: 0px 0px 10px; padding: 0px;">¾|‘上商店中的商品在名¿U°ã€ä­h(hu¨¢n)格发生变化时åQŒå¿…™å»è‡ªåŠ¨é€šçŸ¥ä¼?x¨¬)员åQŒJavaçš„API为我们提供了Observer接口和Observable¾cÀL¥å®žçŽ°æ‰€è°“è§‚å¯Ÿè€…æ¨¡å¼ã€?br />Observable(可观察者)¾cÕd…è®¸åœ¨è‡ªèín发生改变æ—Óž¼Œé€šçŸ¥å…¶å®ƒå¯¹è±¡åQˆå®žçŽ°æŽ¥å£ObserveråQŒè§‚察者)ã€?/p><p style="margin: 0px 0px 10px; padding: 0px;">下面是一个可观察者(产品¾c»ï¼‰åQ?br />import java.util.*;<br />public class product extends Observable{ <br />   private String name;////产品å?br />   private float price;////ä»äh ¼</p><p style="margin: 0px 0px 10px; padding: 0px;">   public String getName(){ return name;}<br />   public void setName(String name){<br />    this.name=name;<br />   ////讄¡½®å˜åŒ–ç‚?nbsp;<br />    setChanged();<br />    notifyObservers(name);////通知观察è€?/p><p style="margin: 0px 0px 10px; padding: 0px;">   }   </p><p style="margin: 0px 0px 10px; padding: 0px;">   public float getPrice(){ return price;}<br />   public void setPrice(float price){<br />    this.price=price;<br />   ////讄¡½®å˜åŒ–ç‚?br />    setChanged();<br />    notifyObservers(new Float(price));</p><p style="margin: 0px 0px 10px; padding: 0px;">   }</p><p style="margin: 0px 0px 10px; padding: 0px;">   ////以下可以是数据库更新 插入命ä×o(h¨´).<br />   public void saveToDb(){<br />   System.out.println("saveToDb");<br />    }</p><p style="margin: 0px 0px 10px; padding: 0px;">}</p><p style="margin: 0px 0px 10px; padding: 0px;">下面是两个观察者:(x¨¬)<br />import java.util.*;<br />public class NameObserver implements Observer{</p><p style="margin: 0px 0px 10px; padding: 0px;">   private String name=null;<br />   public void update(Observable obj,Object arg){<br />     if (arg instanceof String){<br />      name=(String)arg;<br />      ////产品名称改变值在nameä¸?br />      System.out.println("NameObserver :name changet to "+name);</p><p style="margin: 0px 0px 10px; padding: 0px;">     }</p><p style="margin: 0px 0px 10px; padding: 0px;">      }<br />   }</p><p style="margin: 0px 0px 10px; padding: 0px;">import java.util.*;<br />public class PriceObserver implements Observer{<br />   private float price=0;<br />   public void update(Observable obj,Object arg){<br />     if (arg instanceof Float){</p><p style="margin: 0px 0px 10px; padding: 0px;">      price=((Float)arg).floatValue();<br />  <br />      System.out.println("PriceObserver :price changet to "+price);</p><p style="margin: 0px 0px 10px; padding: 0px;">     }</p><p style="margin: 0px 0px 10px; padding: 0px;"><br />   }</p><p style="margin: 0px 0px 10px; padding: 0px;">}<br />下面是测试类åQ?br />public class Test {</p><p style="margin: 0px 0px 10px; padding: 0px;">   public static void main(String args[]){<br />    Product product=new Product();<br />    NameObserver nameobs=new NameObserver();<br />    PriceObserver priceobs=new PriceObserver();</p><p style="margin: 0px 0px 10px; padding: 0px;">    ////加入观察è€?br />    product.addObserver(nameobs);<br />    product.addObserver(priceobs);</p><p style="margin: 0px 0px 10px; padding: 0px;">    product.setName("applet");<br />    product.setPrice(9.22f);</p>   }<br />}</div><div style="color: #8b8989; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 12px; line-height: normal; background-color: #000000;"></div><div style="color: #8b8989; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 12px; line-height: normal; background-color: #000000;"></div><div style="color: #8b8989; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 12px; line-height: normal; background-color: #000000;"></div><div style="color: #8b8989; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 12px; line-height: normal; background-color: #000000;"><div></div></div><div tbar="" fc03="" clearfix"="" style="zoom: 1; margin: 5px 0px; padding-top: 10px; padding-right: 10px; padding-bottom: 10px; text-align: right; color: #c31010; line-height: 20px; font-family: Arial, Helvetica, simsun, u5b8bu4f53; font-size: 12px; background-color: #000000;"><div style="height: 24px; line-height: 24px;"><div rdif"="" style="float: left; height: 24px;"></div></div></div><p> </p></div><img src ="http://www.aygfsteel.com/qileilove/aggbug/392774.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/qileilove/" target="_blank">™åºå…¶è‡ªç„¶EVO</a> 2012-12-11 11:51 <a href="http://www.aygfsteel.com/qileilove/archive/2012/12/11/392774.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>跟屌丝大哥学设计模式-单例模式http://www.aygfsteel.com/qileilove/archive/2012/12/07/392604.html™åºå…¶è‡ªç„¶EVO™åºå…¶è‡ªç„¶EVOFri, 07 Dec 2012 06:55:00 GMThttp://www.aygfsteel.com/qileilove/archive/2012/12/07/392604.htmlhttp://www.aygfsteel.com/qileilove/comments/392604.htmlhttp://www.aygfsteel.com/qileilove/archive/2012/12/07/392604.html#Feedback0http://www.aygfsteel.com/qileilove/comments/commentRss/392604.htmlhttp://www.aygfsteel.com/qileilove/services/trackbacks/392604.html概念åQ?/span>
  java中单例模式是一¿Uå¸¸è§çš„设计模式åQ?/span>单例模式分三¿Uï¼š(x¨¬)懒汉式单例、饿汉式单例、登记式单例三种ã€?br />哈哈 我们可以˜q™æ ·åˆ?屌丝单例模式åQšæ‡’æ±‰å¼å±Œä¸å•ä¾‹åQŒé¥¿æ±‰å¼å±Œä¸å•例åQŒç™»è®°å¼å±Œä¸å•例ã€?br />
  单例模式有一下特点:(x¨¬)
  1、单例类只能有一个实例�span style="margin: 0px; padding: 0px;">
  2、单例类必须自己自己创徏自己的唯一实例�span style="margin: 0px; padding: 0px;">
  3、单例类必须¾l™æ‰€æœ‰å…¶ä»–对象提供这一实例ã€?br />

单例模式¼‹®ä¿æŸä¸ª¾cÕdªæœ‰ä¸€ä¸ªå®žä¾‹ï¼Œè€Œä¸”è‡ªè¡Œå®žä¾‹åŒ–åÆˆå‘æ•´ä¸ªç³»¾lŸæä¾›è¿™ä¸ªå®žä¾‹ã€?/span>在计½Ž—机¾pȝ»Ÿä¸­ï¼Œ¾U¿ç¨‹æ± ã€ç¼“存、日志对象、对话框、打印机、显卡的驱动½E‹åºå¯¹è±¡å¸¸è¢«è®¾è®¡æˆå•例。这些应用都或多或少å…ähœ‰èµ„源½Ž¡ç†å™¨çš„功能。每台计½Ž—机可以有若òq²ä¸ªæ‰“印机,但只能有一ä¸?/span>Printer SpooleråQŒä»¥é¿å…ä¸¤ä¸ªæ‰“印作业同时输出到打印机中。每台计½Ž—机可以有若òq²é€šä¿¡ç«¯å£åQŒç³»¾lŸåº”当集中管理这些通信端口åQŒä»¥é¿å…ä¸€ä¸ªé€šä¿¡ç«¯å£åŒæ—¶è¢«ä¸¤ä¸ªè¯·æ±‚同时调用。æ€ÖM¹‹åQŒé€‰æ‹©å•例模式ž®±æ˜¯ä¸ÞZº†é¿å…ä¸ä¸€è‡´çŠ¶æ€ï¼Œé¿å…æ”¿å‡ºå¤šå¤´ã€?/span>

首先看一个经典的单例实现�br />

public class Singleton {

    private static Singleton uniqueInstance = null;

 

    private Singleton() {

       // Exists only to defeat instantiation.

    }

 

    public static Singleton getInstance() {

       if (uniqueInstance == null) {

           uniqueInstance = new Singleton();

       }

       return uniqueInstance;

    }

    // Other methods...

}

Singleton通过ž®†æž„é€ æ–¹æ³•é™å®šäØ“(f¨´)private避免了类在外部被实例化,在同一个虚拟机范围内,Singleton的唯一实例只能通过getInstance()æ–ÒŽ(gu¨©)³•讉K—®ã€‚(事实上,通过Javaåå°„æœºåˆ¶æ˜¯èƒ½å¤Ÿå®žä¾‹åŒ–æž„é€ æ–¹æ³•äØ“(f¨´)private的类的,那基本上ä¼?x¨¬)ä‹É所有的Java单例实现失效ã€?/strong>此问题在此处不做讨论åQŒå§‘ä¸”æŽ©è€³ç›—é“ƒåœ°è®¤äØ“(f¨´)反射机制不存在。)

但是以上实现没有考虑¾U¿ç¨‹å®‰å…¨é—®é¢˜ã€‚所谓线½E‹å®‰å…¨æ˜¯æŒ‡ï¼š(x¨¬)如果你的代码所在的˜q›ç¨‹ä¸­æœ‰å¤šä¸ª¾U¿ç¨‹åœ¨åŒæ—¶è¿è¡Œï¼Œè€Œè¿™äº›çº¿½E‹å¯èƒ½ä¼š(x¨¬)同时˜qè¡Œ˜q™æ®µä»£ç ã€‚如果每‹Æ¡è¿è¡Œç»“果和单线½E‹è¿è¡Œçš„¾l“果是一æ ïL(f¨¥ng)š„åQŒè€Œä¸”其他的变量的å€ég¹Ÿå’Œé¢„期的是一æ ïL(f¨¥ng)š„åQŒå°±æ˜¯çº¿½E‹å®‰å…¨çš„。或者说åQšä¸€ä¸ªç±»æˆ–者程序所提供的接口对于线½E‹æ¥è¯´æ˜¯åŽŸå­æ“ä½œæˆ–è€…å¤šä¸ªçº¿½E‹ä¹‹é—´çš„切换不会(x¨¬)坯D‡´è¯¥æŽ¥å£çš„æ‰§è¡Œ¾l“果存在二义æ€?/span>,ä¹Ÿå°±æ˜¯è¯´æˆ‘ä»¬ä¸ç”¨è€ƒè™‘åŒæ­¥çš„é—®é¢˜ã€‚æ˜¾ç„¶ä»¥ä¸Šå®žçŽ°åÆˆä¸æ»¡­‘³çº¿½E‹å®‰å…¨çš„要求åQŒåœ¨òq¶å‘环境下很可能出现多个Singleton实例ã€?br />

public class TestDiaoSiStream {
     private String DiaoSiname;
     public String getDiaoSiname() {
         return DiaoSiname;
     }
     public void setDiaoSiname(String DiaoSiname) {
         this.DiaoSiname = DiaoSiname;
     } 
     //该类只能有一个实ä¾?/div>
     private TestDiaoSiStream(){}    //¿Uæœ‰æ— å‚构造方æ³?/div>
     //该类必须自行创徏
     //æœ?¿Uæ–¹å¼?/div>
     /*private static final TestDiaoSiStream ds=new TestDiaoSiStream();*/
     private static TestDiaoSiStream ds1=null;
     //˜q™ä¸ª¾cÕd¿…™å»è‡ªåŠ¨å‘æ•´ä¸ª¾pȝ»Ÿæä¾›˜q™ä¸ªå®žä¾‹å¯¹è±¡
     public static TestDiaoSiStream getTestDiaoSiTest(){
         if(ds1==null){
             ds1=new TestDiaoSiStream();
         }
         return ds1;
     }
     public void getInfo(){
         System.out.println("output message "+DiaoSiname);
     }
 }

public class TestMain {
     public static void main(String [] args){
         TestDiaoSiStream  ds=TestDiaoSiStream.getTestDiaoSiTest();
         ds.setDiaoSiname("奶娃");
         System.out.println(ds.getDiaoSiname());
         TestDiaoSiStream ds1=TestDiaoSiStream.getTestDiaoSiTest();
         ds1.setDiaoSiname("奶娃");
         System.out.println(ds1.getDiaoSiname());
         ds.getInfo();
         ds1.getInfo();
         if(ds==ds1){
             System.out.println("创徏的是同一个屌丝实ä¾?);
         }else if(ds!=ds1){
             System.out.println("创徏的不是同一个屌丝实ä¾?);
         }else{
             System.out.println("application error");
         }
     }
 }

˜qè¡Œ¾l“æžœåQ?br style="margin: 0px; padding: 0px;" />  奶娃
  奶娃
  output message å¥¶å¨ƒ
  output message å¥¶å¨ƒ
  创徏的是同一�span style="color: #000000; font-family: 宋体; line-height: 20.066667556762695px; text-indent: 28px;">屌丝
实例

¾l“论åQšç”±¾l“果可以得知单例模式ä¸ÞZ¸€ä¸ªé¢å‘对象的应用½E‹åºæä¾›äº†å¯¹è±¡æƒŸä¸€çš„访问点åQŒä¸½Ž¡å®ƒå®žçŽ°ä½•ç§åŠŸèƒ½åQ?span style="margin: 0px; padding: 0px; color: #800000;">整个应用½E‹åºéƒ½ä¼š(x¨¬)同äín一个实例对è±?/span>ã€?/span>

1.饿汉式单例类

//饿汉式单例类.在类初始化时åQŒå·²¾lè‡ªè¡Œå®žä¾‹åŒ– 
 public class Singleton1 {
     //¿Uæœ‰çš„默认构造子
     private Singleton1() {}
     //已经自行实例åŒ?nbsp;
     private static final Singleton1 single = new Singleton1();
     //静态工厂方æ³?nbsp;
     public static Singleton1 getInstance() {
         return single;
     }
 }

2.懒汉式单例类
//懒汉式单例类.在第一‹Æ¡è°ƒç”¨çš„æ—¶å€™å®žä¾‹åŒ– 
 public class Singleton2 {
     //¿Uæœ‰çš„默认构造子
     private Singleton2() {}
     //注意åQŒè¿™é‡Œæ²¡æœ‰final    
     private static Singleton2 single=null;
     //静态工厂方æ³?nbsp;
     public synchronized  static Singleton2 getInstance() {
          if (single == null) {  
              single = new Singleton2();
          }  
         return single;
     }
 }
3.登记式单例类

import java.util.HashMap;
 import java.util.Map;
 //登记式单例类.
 //¾cÖM¼¼Spring里面的方法,ž®†ç±»åæ³¨å†Œï¼Œä¸‹æ¬¡ä»Žé‡Œé¢ç›´æŽ¥èŽ·å–ã€?/div>
 public class Singleton3 {
     private static Map<String,Singleton3> map = new HashMap<String,Singleton3>();
     static{
         Singleton3 single = new Singleton3();
         map.put(single.getClass().getName(), single);
     }
     //保护的默认构造子
     protected Singleton3(){}
     //静态工厂方æ³?˜q”还此类惟一的实ä¾?/div>
     public static Singleton3 getInstance(String name) {
         if(name == null) {
             name = Singleton3.class.getName();
             System.out.println("name == null"+"--->name="+name);
         }
         if(map.get(name) == null) {
             try {
                 map.put(name, (Singleton3) Class.forName(name).newInstance());
             } catch (InstantiationException e) {
                 e.printStackTrace();
             } catch (IllegalAccessException e) {
                 e.printStackTrace();
             } catch (ClassNotFoundException e) {
                 e.printStackTrace();
             }
         }
         return map.get(name);
     }
     //一个示意性的商业æ–ÒŽ(gu¨©)³•
     public String about() {    
         return "Hello, I am RegSingleton.";    
     }    
     public static void main(String[] args) {
         Singleton3 single3 = Singleton3.getInstance(null);
         System.out.println(single3.about());
     }
 }



]]>跟屌丝学设计模式之责任链模式http://www.aygfsteel.com/qileilove/archive/2012/12/06/392531.html™åºå…¶è‡ªç„¶EVO™åºå…¶è‡ªç„¶EVOThu, 06 Dec 2012 03:19:00 GMThttp://www.aygfsteel.com/qileilove/archive/2012/12/06/392531.htmlhttp://www.aygfsteel.com/qileilove/comments/392531.htmlhttp://www.aygfsteel.com/qileilove/archive/2012/12/06/392531.html#Feedback0http://www.aygfsteel.com/qileilove/comments/commentRss/392531.htmlhttp://www.aygfsteel.com/qileilove/services/trackbacks/392531.html阅读全文

]]>
java设计模式-桥接模式åQˆå±Œä¸ç”·å­¦è®¾è®¡æ¨¡å¼ï¼‰http://www.aygfsteel.com/qileilove/archive/2012/12/05/392498.html™åºå…¶è‡ªç„¶EVO™åºå…¶è‡ªç„¶EVOWed, 05 Dec 2012 08:21:00 GMThttp://www.aygfsteel.com/qileilove/archive/2012/12/05/392498.htmlhttp://www.aygfsteel.com/qileilove/comments/392498.htmlhttp://www.aygfsteel.com/qileilove/archive/2012/12/05/392498.html#Feedback0http://www.aygfsteel.com/qileilove/comments/commentRss/392498.htmlhttp://www.aygfsteel.com/qileilove/services/trackbacks/392498.html本文介绍设计模式中的桥接åQ?a target="_self" style="color: #336699; text-decoration: initial;">BridgeåQ‰æ¨¡å¼çš„æ¦‚念åQŒç”¨æ³•,以及(qi¨¢ng)实际应用中怎么样ä‹Éç”?a target="_self" style="color: #336699; text-decoration: initial;">桥接模式˜q›è¡Œå¼€å‘ã€?/span>

Bridge模式的概�/strong>

Bridge 模式是构造型的设计模式之一。Bridge模式åŸÞZºŽ¾cÈš„æœ€ž®è®¾è®¡åŽŸåˆ™ï¼Œé€šè¿‡ä½¿ç”¨ž®è£…åQŒèšåˆä»¥å?qi¨¢ng)ç‘ô承等行äØ?f¨´)来让不同的类承担不同的责仅R€‚它的主要特ç‚ÒŽ(gu¨©)˜¯æŠŠæŠ½è±¡ï¼ˆabstractionåQ‰ä¸Žè¡ŒäØ“(f¨´)实现åQˆimplementationåQ‰åˆ†¼›Õd¼€æ¥ï¼Œä»Žè€Œå¯ä»¥ä¿æŒå„部分的独立性以å?qi¨¢ng)应对它们的功能扩展ã€?br />

Bridge模式的应用场�/strong>

面向对象的程序设计(OOPåQ‰é‡Œæœ‰ç±»¾l§æ‰¿åQˆå­¾cȝ‘ô承父¾c»ï¼‰çš„æ¦‚念,如果一个类或接口有多个具体实现子类åQŒå¦‚果这些子¾cÕd…·æœ‰ä»¥ä¸‹ç‰¹æ€§ï¼š(x¨¬)
- 存在相对òq¶åˆ—的子¾cÕd±žæ€§ã€?br />- 存在概念上的交叉ã€?br />- 可变性ã€?br />我们ž®±å¯ä»¥ç”¨Bridge模式来对其进行抽象与具体åQŒå¯¹ç›¸å…³¾c»è¿›è¡Œé‡æž„ã€?br />

ä¸ÞZº†å®ÒŽ(gu¨©)˜“理解åQŒæˆ‘们ä‹D例说明一下,比如屌丝åQˆDiaoSiåQ‰ï¼Œå‡è®¾æœ?个子¾c»ï¼Œç”·å±Œä¸ç±»åQˆManDiaoSiåQ‰ä¸Žå¥›_±Œä¸ç±»åQˆWomanDiaoåQ‰ï¼Œå®ƒä»¬æœ‰[½IähŒ«çŸ®]˜q™ä¸ªåŠ¨ä½œè¡ŒäØ“(f¨´)åQŒé€šè¿‡ä¸åŒ½IähŒ«çŸ®ç‰¹å¾çš„讄¡½®åQŒå¯ä»¥å°†å®ƒä»¬è®„¡½®ä¸ºæ¯”如䨓(f¨´)拥有黑木耳男屌丝或(拥有撸管王的奛_±Œä¸ï¼‰åQŒå’Œæ‹¥æœ‰ç´«æœ¨è€³ç”·å±Œä¸æˆ–(拥有撸神的女屌丝åQ‰çš„各种屌丝ã€?br />˜q™æ ·åQŒä¸½Ž¡æ˜¯é»‘木耳男屌丝˜q˜æ˜¯ç´«æœ¨è€³ç”·å±Œä¸åQŒåˆæˆ–是有撸½Ž¡çŽ‹çš„å¥³å±Œä¸˜q˜æ˜¯æœ‰æ’¸¼œžçš„奛_±Œä¸ï¼Œå®ƒä»¬éƒ½å¯ä»¥æ˜¯å±Œä¸¾cȝš„子类åQŒè€Œä¸”åQ?br />- 存在相对òq¶åˆ—的子¾cÕd±žæ€§ã€‚屌丝的¿Uç±»åQŒä¸Žå±Œä¸½IähŒ«çŸ®çš„规格是屌丝的2ä¸ªåÆˆåˆ—çš„å±žæ€§ï¼Œæ²¡æœ‰æ¦‚å¿µä¸Šçš„é‡å¤ã€?br />- 存在概念上的交叉。不½Ž¡æ˜¯ç”·å±Œä¸è¿˜æ˜¯å¥³å±Œä¸åQŒéƒ½æ˜¯ç©·æŒ«çŸ®åQŒé»‘½I·ä¸‘的屌丝ã€?br />- 可变性。除了男屌丝åQŒå¥³å±Œä¸ä¹‹å¤–åQŒå¯èƒ½è¿˜æœ‰äh妖屌丝;除了有黑木耻I¼ˆæ’¸ç®¡çŽ‹ï¼‰ä¸Žç‚÷木耻I¼ˆæ’¸ç¥žåQ‰ç‰¹å¾çš„屌丝之外åQŒè¿˜å¯èƒ½æœ‰ç‚÷黑木耻I¼ˆæ’¸åœ£åQ‰çš„屌丝½{‰ç­‰ã€?/p>

˜q™æ ·ä¸€æ¥ï¼Œæˆ‘们怎么来设计屌丝类呢?

æ–ÒŽ(gu¨©)³•一

通过¾l§æ‰¿è®¾è®¡æ‰€æœ‰å¯èƒ½å­˜åœ¨çš„子类。可能我们会(x¨¬)惛_ˆ°ä¸‹é¢çš„è¿™¿Uç‘ô承关¾p»ï¼š(x¨¬)
屌丝æ€È±»åQšDiaoSi
屌丝子类 - 按种¾cÕdˆ†¾c»ï¼š(x¨¬)ManDiaoSiåQ?span style="color: #000000; font-family: verdana, 'courier new'; line-height: 21px;">WomanDiao
屌丝子类 - 按特征分¾c»ï¼š(x¨¬)拥有黑木耳男屌丝åQŒæ‹¥æœ?span style="color: #000000; font-family: verdana, 'courier new'; line-height: 21px;">撸管王的奛_±Œä¸?/span>åQ?span style="color: #000000; font-family: verdana, 'courier new'; line-height: 21px;">拥有紫木耳男屌丝åQ?span style="color: #000000; font-family: verdana, 'courier new'; line-height: 21px;">拥有撸神的女屌丝
˜q™æ ·è®„¡½®ç‰¹å¾˜q™ä¸ªåŠ¨ä½œž®Þq”±å„个子类加以实现ã€?/p>

但如果以后需要增加一¿U?span style="color: #000000; font-family: verdana, 'courier new'; line-height: 21px;">人妖屌丝åQˆGuyDiaoSiåQ‰ï¼Œä»¥åŠ(qi¨¢ng)增加一个特征规格ç‚÷黑木耻I¼Œéœ€è¦å®žçŽ°çš„å­ç±»ž®†ä¼š(x¨¬)有:(x¨¬)
拥有黑木耳男屌丝åQŒæ‹¥æœ?span style="color: #000000; font-family: verdana, 'courier new'; line-height: 21px;">撸管王的奛_±Œä¸?/span>åQ?span style="color: #000000; font-family: verdana, 'courier new'; line-height: 21px;">拥有紫木耳男屌丝åQ?span style="color: #000000; font-family: verdana, 'courier new'; line-height: 21px;">拥有撸神的女屌丝  æ‹¥æœ‰ç´«é»‘木耳男屌丝 æ‹¥æœ‰æ’¸ç®¡çŽ‹çš„äººå¦–å±Œä¸ æ‹¥æœ‰ç´«é»‘木耳äh妖屌ä¸?nbsp;拥有紫木耳äh妖屌ä¸?/span>
 ½{‰ç­‰ã€?br />也就是说åQŒè¿™¿Uè®¾è®¡æ–¹æ³•,子类数目ž®†éšå‡ ä½•¾U§æ•°å¢žé•¿ã€?br />而且åQ?span style="color: #000000; font-family: verdana, 'courier new'; line-height: 21px;">拥有黑木耳男屌丝
åQ?span style="color: #000000; font-family: verdana, 'courier new'; line-height: 21px;">拥有紫木耳äh妖屌ä¸?/span>的特征规格相同,它们的特征设¾|®åŠ¨ä½œåº”è¯¥æ˜¯ä¸€æ ïL(f¨¥ng)š„åQŒä½†çŽ°åœ¨æŠŠå®ƒä»¬åˆ†æˆä¸åŒçš„å­ç±»åQŒéš¾ä»¥é¿å…æ‰§è¡Œé‡å¤çš„åŠ¨ä½œè¡ŒäØ“(f¨´)ã€?/p>

 

æ–ÒŽ(gu¨©)³•äº?/strong>

分别为男屌丝以及(qi¨¢ng)奛_±Œä¸å®žçŽ°è®¾¾|®ä¸åŒç‰¹å¾çš„æ–ÒŽ(gu¨©)³•
屌丝æ€È±»åQšDiaoSi
屌丝子类åQ?span style="color: #000000; font-family: verdana, 'courier new'; line-height: 21px;">ManDiaoSiåQ?span style="color: #000000; font-family: verdana, 'courier new'; line-height: 21px;">WomanDiao

然后在男屌丝¾c»é‡Œåˆ†åˆ«æä¾›é»‘木耻I¼ˆæ’¸ç®¡çŽ‹ï¼‰ä»¥åŠ(qi¨¢ng)紫木耻I¼ˆæ’¸ç¥žåQ‰ç‰¹å¾çš„讄¡½®æ–ÒŽ(gu¨©)³•åQ?br />ManDiaoSi extends DiaoSi
 {
    public setFeatures黑木è€?);
    public setFeatures紫木è€?);
}

在女屌丝¾c»é‡Œä¹Ÿåˆ†åˆ«æä¾›æ’¸½Ž¡çŽ‹ä»¥åŠ(qi¨¢ng)撸神特征的设¾|®æ–¹æ³•:(x¨¬)
WomanDiao extends DiaoSi
 {
    public setFeatures撸管çŽ?);
    public setFeatures撸神();
}

˜q™ç§æƒ…况åQŒå­¾cÈš„æ•°é‡æ˜¯è¢«æŽ§åˆ¶äº†ã€‚但一斚w¢åQŒå¦‚果每增加一¿Uç‰¹å¾è§„æ û|¼Œéœ€è¦ä¿®æ”ÒŽ(gu¨©)‰€æœ‰çš„屌丝子类åQ›å¦ä¸€æ–šw¢åQŒå³ä½¿ç‰¹å¾çš„讄¡½®è¡ŒäØ“(f¨´)ä¸€æ øP¼Œä½†æ˜¯ä¸åŒçš„屌丝子¾cÕd´éœ€è¦æä¾›å®Œå…¨ä¸€æ ïL(f¨¥ng)š„æ–ÒŽ(gu¨©)³•ã€?br />

在实际的应用开发中åQŒä»¥ä¸?¿Uæ–¹æ³•都ä¼?x¨¬)造成˜qä¸€å‘而动全èínåQŒè€Œä¸”ä¼?x¨¬)存在大量的重复代码ã€?/p>

Bridge模式可以很好的解册™¿™¾c»é—®é¢˜ã€?br />Client
    Bridge模式的ä‹É用è€?br />Abstraction
    抽象¾cÀLŽ¥å£ï¼ˆæŽ¥å£æˆ–æŠ½è±¡ç±»åQ?br />    ¾l´æŠ¤å¯¹è¡Œä¸ºå®žçŽŽÍ¼ˆImplementoråQ‰çš„引用
Refined Abstraction
    Abstraction子类
Implementor
    è¡ŒäØ“(f¨´)实现¾cÀLŽ¥å?(Abstraction接口定义了基于Implementor接口的更高层‹Æ¡çš„æ“ä½œ)
ConcreteImplementor
    Implementor子类

 

Bridge模式的应用范�/strong>

我们来看看怎么应用Bridge模式来设计汽车类�/p>

抽象 - Abstraction¾c»ï¼š(x¨¬)屌丝¾cÕdŠ(qi¨¢ng)其子¾c»ï¼š(x¨¬)
屌丝æ€È±»åQšDiaoSi
屌丝子类 - 按种¾cÕdˆ†¾c»ï¼š(x¨¬)ManDiaoSiåQ?span style="color: #000000; font-family: verdana, 'courier new'; line-height: 21px;">WomanDiao
屌丝子类 - 按特征分¾c»ï¼š(x¨¬)拥有黑木耳男屌丝åQŒæ‹¥æœ?span style="color: #000000; font-family: verdana, 'courier new'; line-height: 21px;">撸管王的奛_±Œä¸?/span>åQ?span style="color: #000000; font-family: verdana, 'courier new'; line-height: 21px;">拥有紫木耳男屌丝åQ?span style="color: #000000; font-family: verdana, 'courier new'; line-height: 21px;">拥有撸神的女屌丝

è¡ŒäØ“(f¨´)实现 - ImplementoråQšå±Œä¸ç‰¹å¾è®¾¾|®çš„è¡ŒäØ“(f¨´)¾cÕdŠ(qi¨¢ng)子类
 setFeaturesåQšå±Œä¸ç‰¹å¾çš„讄¡½®æŽ¥å£
 setFeatures黑木è€?);
setFeatures紫木�);

代码åQ?/p>

package ITfarmer.designpatterns.study.bridge;

//‹¹‹è¯•

public class Client
{
    public static void main( String[] argv )
    {
        Features 黑木è€? new  ç”·å±Œä¸ç‰¹å¾?);

         Features ç´?/span>木è€? new  å¥›_±Œä¸ç‰¹å¾?/span>();
       
        DiaoSi æ‹¥æœ‰é»‘木耳的男屌ä¸? new  ManDiaoSi( é»‘木è€?nbsp;);
         DiaoSi æ‹¥æœ‰ç´«æœ¨è€³çš„男屌ä¸? new  ManDiaoSi( ç´«æœ¨è€?nbsp;);
        æ‹¥æœ‰é»‘木耳的男屌ä¸?setFeatures();
        æ‹¥æœ‰ç´«æœ¨è€³çš„男屌ä¸?setFeatures();
       
        DiaoSi æ‹¥æœ‰é»‘木耳的奛_±Œä¸? new WomanDiao( 黑木è€?);
        Vehicle æ‹¥æœ‰ç´«æœ¨è€³çš„奛_±Œä¸? new WomanDiao( 紫木è€?);
      æ‹¥æœ‰é»‘木耳的奛_±Œä¸?setFeatures();
        æ‹¥æœ‰ç´«æœ¨è€³çš„奛_±Œä¸?setFeatures();
       
    }
}

package ITfarmer.designpatterns.study.bridge;


 *
 * @author
 * @since 2012/12/05
 */
public abstract class DiaoSi
{
    private Features features;

    Vehicle( Features features)
    {
        this.setFeatures features);
    }
   
    public abstract void setFeatures();

    public void setFeaturesFeatures features)
    {
        this.featuresfeatures;
    }

    public Features getFeatures()
    {
        return  features;
    }
}

package ITfarmer.designpatterns.study.bridge;

//Abstraction子类åQšè¿™é‡ŒäØ“(f¨´)屌丝抽象¾cȝš„子类

public class ManDiaoSi extends DiaoSi
{
    public ManDiaoSi (Features features
)
    {
        super( features
 );
    }
   
    @Override
    public void setFeatures()
    {
        System.out.print("男屌丝的特征: ");
        getFeatures.setFeatures();
    }
}

package ITfarmer.designpatterns.study.bridge;

//Abstraction子类åQšè¿™é‡ŒäØ“(f¨´)屌丝抽象¾cȝš„子类

public class WomanDiaoSi extends DiaoSi
{
    public WomanDiaoSi ( Features features
 )
    {
        super( features
);
    }

    @Override
    public void  setFeatures()
    {
        System.out.print("奛_±Œä¸çš„特征: ");
        getFeatures().seFeatures();
    }

}

package ITfarmer.designpatterns.study.bridge;

//屌丝¾cȝš„è¡ŒäØ“(f¨´)接口

public interface Features
{
    public void setFeatures();
}

package ITfarmer.designpatterns.study.bridge;

/** ConcreteImplementor */
//è¡ŒäØ“(f¨´)实现子类

public class 男屌丝特å¾?implements Features
{

    public void setFeatures()
    {
        System.out.println("黑木è€?或è€?撸管çŽ?);
    }   
   
}

package ITfarmer.designpatterns.study.bridge;

/** ConcreteImplementor */
//è¡ŒäØ“(f¨´)实现子类

public class  å¥›_±Œä¸ç‰¹å¾?nbsp;implements Features
{

    public void setFeatures()
    {
        System.out.println("黑木è€?或è€?撸管çŽ?);
    }   
   
}

ž®ç»“åQšBridge模式是一¿UæŠ½è±¡ä¸Žå…¶å®žçŽ°ç›¸åˆ†ç¦»çš„æ¨¡å¼ã€‚å®ƒä¸»è¦åº”ç”¨äºŽï¼š(x¨¬)当事物是一¾l„变化量åQŒå’Œå¯¹è¿™äº›äº‹ç‰©çš„æ“ä½œæ–ÒŽ(gu¨©)³•(实现)也是一¾l„变化量的情况,也就是说它们都是多变的ã€?/span>

 



]]>
Ö÷Õ¾Ö©Öë³ØÄ£°å£º ·â¿ªÏØ| ËçÖÐÏØ| ×ñÒåÏØ| ºâÑôÊÐ| ƽÄÏÏØ| Á°Ë®ÏØ| ÒåÂíÊÐ| Æ½ÒØÏØ| ¾®ÚêÏØ| º³ÇÊÐ| À¼ÏªÊÐ| ¹ó¸ÛÊÐ| ÐÂÆ½| ´óÐËÇø| ͳ·¬ÊÐ| °×³ÇÊÐ| ¶þÁ¬ºÆÌØÊÐ| ¹Å½»ÊÐ| ÁÉÔ´ÊÐ| °ØÏçÏØ| Âê¶àÏØ| ³¤µºÏØ| ÐÇ×ÓÏØ| ³çÀñÏØ| ÑÓ´¨ÏØ| ÌÒÔ´ÏØ| Т¸ÐÊÐ| ÐĮ̈ÊÐ| ²ý¼ªÊÐ| ¸ÊÂåÏØ| áÓÖÝÊÐ| ÔÆÄÏÊ¡| ËÄÆ½ÊÐ| ÑÎÍ¤ÏØ| ÄþÏÄ| ´íÄÇÏØ| ƽºþÊÐ| ÙÈʦÊÐ| ×õË®ÏØ| ÎäÇåÇø| ³¤ÐËÏØ|