﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-cuiyi's blog（崔毅 crazycy）-随笔分类-Design Pattern、JEE Pattern</title><link>http://www.blogjava.net/crazycy/category/11615.html</link><description>记录点滴 鉴往事之得失 以资于发展 </description><language>zh-cn</language><lastBuildDate>Fri, 07 Mar 2008 22:29:26 GMT</lastBuildDate><pubDate>Fri, 07 Mar 2008 22:29:26 GMT</pubDate><ttl>60</ttl><item><title>我对设计模式的理解：AOP vs 动态代理（Dynamic Proxy）</title><link>http://www.blogjava.net/crazycy/archive/2006/10/29/77903.html</link><dc:creator>crazycy</dc:creator><author>crazycy</author><pubDate>Sun, 29 Oct 2006 07:15:00 GMT</pubDate><guid>http://www.blogjava.net/crazycy/archive/2006/10/29/77903.html</guid><wfw:comment>http://www.blogjava.net/crazycy/comments/77903.html</wfw:comment><comments>http://www.blogjava.net/crazycy/archive/2006/10/29/77903.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/crazycy/comments/commentRss/77903.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/crazycy/services/trackbacks/77903.html</trackback:ping><description><![CDATA[
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #000000">
						<font style="BACKGROUND-COLOR: #deb887">非常感谢你的阅读，如果你觉得好或者对你有一定的帮助，请积极参与评论以示鼓励。</font> </span>
		</div>
		<br />曾遇到“<font color="#0000ff">AOP与动态代理有什么联系</font>”的问题，现把个人观点整理如下：<br /><br />我觉得，动态代理是AOP的主要实现手段之一，AOP是动态代理的一种应用深化 
<p>AOP是一种思想，或者是方法论，类似OOP，是OOP的有力补充；<br />OOP侧重于主要业务功能设计（一般关注点）；<br />AOP侧重于横切关注点（事务、日志、安全等，贯穿于多个模块的功能）<br />小分析：<br />OOP在横切关注点问题的不足是：1)代码混乱 2）代码分散<br />AOP很好的解决了这个问题，并且可以很好的解决“侵入问题”。<br /><br />AOP的实现，必然要求对截获的对象进行代理，这个地方无疑要用的是动态代理机制。</p><p>如果非要说谁是谁的实现手段，我更倾向于AOP主要应用了动态代理，动态代理是AOP的实现手段。<br /><br /><font style="BACKGROUND-COLOR: #ff1493">附记</font>：<br />记得一个文章提及：<br />AOP是设计模式的延续；<br />GoF侧重于接口、抽象函数来解除耦合；却对对象的内部无能为力。<br />AOP却恰恰从对象的内部着手，实现调用者和被调用者的分离。<br /><br />常思考之，甚是！</p><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><font style="BACKGROUND-COLOR: #deb887"><span style="COLOR: #000000">Thanks very much to visit blog,  welcome your feedback,  your feedback is the Driver </span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000"> Power to me.</span></font></div><img src ="http://www.blogjava.net/crazycy/aggbug/77903.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/crazycy/" target="_blank">crazycy</a> 2006-10-29 15:15 <a href="http://www.blogjava.net/crazycy/archive/2006/10/29/77903.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>我对设计模式的理解：工厂方法模式(Factory Mehod)  与 抽象工厂模式(Abstract Factory)</title><link>http://www.blogjava.net/crazycy/archive/2006/10/08/73858.html</link><dc:creator>crazycy</dc:creator><author>crazycy</author><pubDate>Sun, 08 Oct 2006 08:39:00 GMT</pubDate><guid>http://www.blogjava.net/crazycy/archive/2006/10/08/73858.html</guid><wfw:comment>http://www.blogjava.net/crazycy/comments/73858.html</wfw:comment><comments>http://www.blogjava.net/crazycy/archive/2006/10/08/73858.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/crazycy/comments/commentRss/73858.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/crazycy/services/trackbacks/73858.html</trackback:ping><description><![CDATA[
		<p>
				<span lang="EN-US" style="LINE-HEIGHT: 150%; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt">
						<font style="BACKGROUND-COLOR: #ffa500">非常感谢你的阅读，如果你觉得好或者对你有帮助，请<strong>积极给一个留言反馈</strong>以示鼓励。<br /></font>
				</span>
				<br />两者都系工厂模式。<br /><br />本质都是将创建具体对象的职责和过程从代码中提取出来，从而实现调用者和被调用者解耦的（设计模式）目标。<br /><br />但之所以会存在两个分支，我们可以从其各自的实质来看：<br />工厂方法模式(Factory Mehod Pattern) 只产生一类对象；<br />抽象工厂模式(Abstract Factory Pattern)产生一系列对象；这些对象具有如下特征：<font color="#ff1493">相关或者相互依赖</font>。<br /><br />工厂方法模式可以通过带参数的变种（即结合j2ee Service Location Pattern方式），从而产生多种产品（即一类对象的多个不同的实例）。<br /><br />抽象工厂模式更注重是相关或者相互依赖的一系列对象，<font color="#a52a2a">一旦需要改动，只修改某一个具体工厂即可到达修改整个产品系列的目的</font>。<br />从这一点，如果是涉及一个系列的产品一起工作，我们就应该放弃采用（工厂方法模式的）多个工厂方法来达到与（抽象工厂）相同目的的做法。<br />因为：<font color="#ffc0cb">如果一个系列的产品一起工作时，一个应用一次只能使用同一个产品系列中一个对象</font>，只需要一个具体工厂类（抽象工厂模式），或者 多个具体工场类（工厂方法模式）。如果这一点可以接受，那修改呢？！<br /><br /><font style="BACKGROUND-COLOR: #ffa500" face="Verdana">Thanks very much to visit blog,  <strong>welcome your feedback</strong>,  your feedback is the Driver &amp;&amp; Power to me</font><font face="Arial"></font></p>
<img src ="http://www.blogjava.net/crazycy/aggbug/73858.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/crazycy/" target="_blank">crazycy</a> 2006-10-08 16:39 <a href="http://www.blogjava.net/crazycy/archive/2006/10/08/73858.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>单例模式(SingLeton Pattern)的误区</title><link>http://www.blogjava.net/crazycy/archive/2006/07/15/58268.html</link><dc:creator>crazycy</dc:creator><author>crazycy</author><pubDate>Fri, 14 Jul 2006 16:02:00 GMT</pubDate><guid>http://www.blogjava.net/crazycy/archive/2006/07/15/58268.html</guid><wfw:comment>http://www.blogjava.net/crazycy/comments/58268.html</wfw:comment><comments>http://www.blogjava.net/crazycy/archive/2006/07/15/58268.html#Feedback</comments><slash:comments>13</slash:comments><wfw:commentRss>http://www.blogjava.net/crazycy/comments/commentRss/58268.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/crazycy/services/trackbacks/58268.html</trackback:ping><description><![CDATA[
		<span style="font-size: 10pt; line-height: 150%; font-family: 宋体; color: black;">单例(</span>SingLeton<span style="font-size: 10pt; line-height: 150%; font-family: 宋体; color: black;">)故名思义就是在一个</span><span style="font-size: 10pt; line-height: 150%; font-family: Verdana; color: black;" lang="EN-US">JVM</span><span style="font-size: 10pt; line-height: 150%; font-family: 宋体; color: black;">运行中只有一个对象存在；请你务必注意到是在一个</span><span style="font-size: 10pt; line-height: 150%; font-family: Verdana; color: black;" lang="EN-US">JVM</span><span style="font-size: 10pt; line-height: 150%; font-family: 宋体; color: black;">虚拟机内。<br /><br />今天一个朋友问过这样一个问题：为什么他的单例每次都进入构造函数，程序如下：</span><span style="font-size: 10pt; line-height: 150%; font-family: Verdana; color: black;" lang="EN-US"><o:p></o:p></span><p class="MsoNormal" style="text-indent: 21pt; line-height: 150%;"><span style="font-size: 10pt; line-height: 150%; font-family: Verdana; color: black;" lang="EN-US"><o:p></o:p></span></p><p class="MsoNormal" style="text-indent: 21pt; line-height: 150%;"><span style="font-size: 10pt; line-height: 150%; font-family: Verdana; color: black;" lang="EN-US"><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> ServerThread </span><span style="color: rgb(0, 0, 255);">implements</span><span style="color: rgb(0, 0, 0);"> Runnable{<br /><br />     </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);"> ServerThread instance </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">;  <br /><br />     </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> ServerThread() {<br /><br />         </span><span style="color: rgb(0, 0, 255);">try</span><span style="color: rgb(0, 0, 0);"> {<br /><br />             </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (socket </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">) {<br /><br />                 socket </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> DatagramSocket(Constants.SERVER_PORT);<br /><br />             }<br /><br />          } </span><span style="color: rgb(0, 0, 255);">catch</span><span style="color: rgb(0, 0, 0);"> (Exception e) {<br /><br />                 e.printStackTrace();<br /><br />           }<br /><br />       }<br /><br />     </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">final</span><span style="color: rgb(0, 0, 0);"> ServerThread getInstance() {<br /><br />        </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (instance </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">) {<br />           System.out.println(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">instance is null<img src="http://www.blogjava.net/images/dot.gif" /> new generate<img src="http://www.blogjava.net/images/dot.gif" />.</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />           instance </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> ServerThread();<br />        }<br />        </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> instance;<br /><br />      }<br /><br />    </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> Thread getThreadInstance() {<br /><br />        </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (threadInstance </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">) {<br /><br />            threadInstance </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> Thread(instance);<br />        }<br />        </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> threadInstance;<br />    }<br /><br />。。。。。。。。<br /><br />}<br /></span></div><br /></span></p><p class="MsoNormal" style="text-indent: 21pt; line-height: 150%;"><span style="font-size: 10pt; line-height: 150%; font-family: Verdana; color: black;" lang="EN-US"><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> Main {<br /><br />      main函数有servTr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> ServerThread.getInstance().getThreadInstance();一句<br /></span></div><br /></span></p><p class="MsoNormal" style="text-indent: 21pt; line-height: 150%;"><span style="font-size: 10pt; line-height: 150%; font-family: 宋体; color: black;"></span><span style="font-size: 10pt; line-height: 150%; font-family: Verdana; color: black;" lang="EN-US"><o:p></o:p></span></p><p class="MsoNormal" style="text-indent: 21pt; line-height: 150%;"><span style="font-size: 10pt; line-height: 150%; font-family: 宋体; color: black;">代码没有问题吧；为什么他的单例每次都进入构造函数呢？</span><span style="font-size: 10pt; line-height: 150%; font-family: Verdana; color: black;" lang="EN-US"><o:p></o:p></span></p><p class="MsoNormal" style="text-indent: 21pt; line-height: 150%;"><span style="font-size: 10pt; line-height: 150%; font-family: 宋体; color: black;">细问之下才知道了他启动了两次</span><span style="font-size: 10pt; line-height: 150%; font-family: Verdana; color: black;" lang="EN-US">Main</span><span style="font-size: 10pt; line-height: 150%; font-family: 宋体; color: black;">类；启动一个</span><span style="font-size: 10pt; line-height: 150%; font-family: Verdana; color: black;" lang="EN-US">Main</span><span style="font-size: 10pt; line-height: 150%; font-family: 宋体; color: black;">类便在一个</span><span style="font-size: 10pt; line-height: 150%; font-family: Verdana; color: black;" lang="EN-US">JVM</span><span style="font-size: 10pt; line-height: 150%; font-family: 宋体; color: black;">，两次的单例怎么能是同一个呢？！</span><span style="font-size: 10pt; line-height: 150%; font-family: Verdana; color: black;" lang="EN-US"><o:p></o:p></span></p><p class="MsoNormal" style="text-indent: 21pt; line-height: 150%;"><font color="#000000"><span style="font-size: 10pt; line-height: 150%; font-family: 宋体; color: black;">记住：是在同一个</span><span style="font-size: 10pt; line-height: 150%; font-family: Verdana; color: black;" lang="EN-US">JVM</span><span style="font-size: 10pt; line-height: 150%; font-family: 宋体; color: black;">中唯一，不是在一个物理内存中唯一。当然后者不是不能做到的，分布式对象嘛，呵呵。</span></font></p><p class="MsoNormal" style="text-indent: 21pt; line-height: 150%;"><br /><font color="#000000"><span style="font-size: 10pt; line-height: 150%; font-family: 宋体; color: black;"></span></font><span style="font-size: 10pt; line-height: 150%; font-family: Verdana; color: black;" lang="EN-US"><o:p></o:p></span></p><p class="MsoNormal" style="text-indent: 21pt; line-height: 150%;"><span style="font-size: 10pt; line-height: 150%; font-family: 宋体; color: black;">第二点就是：单例的构造</span><span style="font-size: 10pt; line-height: 150%; font-family: Verdana; color: black;" lang="EN-US">:<o:p></o:p></span></p><p class="MsoNormal" style="text-indent: 21pt; line-height: 150%;"><span style="font-size: 10pt; line-height: 150%; font-family: 宋体; color: black;">目前方式多种，我认为只有两种是正确的：</span><span style="font-size: 10pt; line-height: 150%; font-family: Verdana; color: black;" lang="EN-US"><o:p></o:p></span></p><p class="MsoNormal" style="text-indent: 21pt; line-height: 150%;"><span style="font-size: 10pt; line-height: 150%; font-family: 宋体; color: black;">第一：</span><span style="font-size: 10pt; line-height: 150%; font-family: Verdana; color: black;"><span lang="EN-US">private final static DaoFactory instance = new DaoFactory();<o:p></o:p></span></span></p><p class="MsoNormal" style="text-indent: 21pt; line-height: 150%;"><span style="font-size: 10pt; line-height: 150%; font-family: 宋体; color: black;">第二：</span><span style="font-size: 10pt; line-height: 150%; font-family: Verdana; color: black;" lang="EN-US"><o:p></o:p></span></p><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);"> DaoFactory instance </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">;<br /><br />      </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> Properties props </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">;<br /><br />       </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> Map daos </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">;<br /><br />      </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> DaoFactory() {<br /><br />           props </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> Properties();<br /><br />           daos </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> HashMap();<br /><br />      }<br /><br />     <br /><br />      </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);"> DaoFactory getInstance() {<br /><br />           </span><span style="color: rgb(0, 0, 255);">while</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> instance) {<br /><br />                 </span><span style="color: rgb(0, 0, 255);">synchronized</span><span style="color: rgb(0, 0, 0);">(DaoFactory.</span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);">) {<br /><br />                      </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> instance) {<br /><br />                            instance </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> DaoFactory();<br /><br />                            instance.initDaoFactroy();<br /><br />                      }<br /><br />                 }<br /><br />           }<br /><br />           </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> instance;<br /><br />      }<br /><br /></span></div><br /><p class="MsoNormal" style="text-indent: 21pt; line-height: 150%;"><span style="font-size: 10pt; line-height: 150%; font-family: 宋体; color: black;">看清楚了，这里用的是</span><span style="font-size: 10pt; line-height: 150%; font-family: Verdana; color: black;" lang="EN-US">while</span><span style="font-size: 10pt; line-height: 150%; font-family: 宋体; color: black;">；不是</span><span style="font-size: 10pt; line-height: 150%; font-family: Verdana; color: black;" lang="EN-US">if</span><span style="font-size: 10pt; line-height: 150%; font-family: 宋体; color: black;">。</span><span style="font-size: 10pt; line-height: 150%; font-family: Verdana; color: black;" lang="EN-US"><o:p></o:p></span></p><p class="MsoNormal" style="text-indent: 21pt; line-height: 150%;"><span style="font-size: 10pt; line-height: 150%; font-family: 宋体; color: black;">为什么不能用</span><span style="font-size: 10pt; line-height: 150%; font-family: Verdana; color: black;" lang="EN-US">if</span><span style="font-size: 10pt; line-height: 150%; font-family: 宋体; color: black;">呢？下面的一个例子说明</span><span style="font-size: 10pt; line-height: 150%; font-family: Verdana; color: black;" lang="EN-US"><o:p></o:p></span></p><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> DomainFactory {<br /><br />      </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> List provinces;<br /> <br />           </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> Map domains;<br /><br />      </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);"> DomainFactory instance;<br /><br />      </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> DomainFactory() {<br /><br />           generateDomainTree();<br /><br />      }<br /><br />      </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);"> DomainFactory getInstance() {<br /><br />           </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> instance) {<br /><br />                 </span><span style="color: rgb(0, 0, 255);">synchronized</span><span style="color: rgb(0, 0, 0);"> (DomainFactory.</span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);">) {<br /><br />                      </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> instance) {<br /><br />                            instance </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> DomainFactory();<br /><br />                      }<br /><br />                 }<br /><br />           }<br /><br />           </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> instance;<br /><br />      }<br /><br />      </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> generateDomainTree() {<br /><br />。。。。。<br /><br />}<br /><br /></span></div><br /><p class="MsoNormal" style="margin-left: 21pt; text-indent: 21pt; line-height: 150%;"><span style="font-size: 10pt; line-height: 150%; font-family: Verdana; color: black;" lang="EN-US"><o:p> <div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> CategoryFactory {<br /><br />      </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> Map map;     <br /><br />      </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);"> CategoryFactory instance;<br />     <br /><br />      </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> CategoryFactory() {<br /><br />           map </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> HashMap();<br /><br />           generateCategoryTree();<br /><br />      }     <br /><br />      </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);"> CategoryFactory getInstance() {<br /><br />           </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> instance) {<br /><br />                 </span><span style="color: rgb(0, 0, 255);">synchronized</span><span style="color: rgb(0, 0, 0);"> (CategoryFactory.</span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);">) {<br /><br />                      </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);"> (</span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);"> instance) {<br /><br />                            instance </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> CategoryFactory();<br /><br />                      }<br /><br />                 }<br /><br />           }<br /><br />           </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> instance;<br /><br />      }     <br /><br />      </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> generateCategoryTree() {<br /><br />。。。。。。<br /><br />}<br /></span></div><br /> </o:p></span></p><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> SearchAction </span><span style="color: rgb(0, 0, 255);">extends</span><span style="color: rgb(0, 0, 0);"> DispatchAction {<br /><br />      </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> ActionForward getCatalogData(ActionMapping mapping, ActionForm form,<br /><br />                 HttpServletRequest request, HttpServletResponse response) {<br /><br />           DomainObject domainObject </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> DomainObject();<br /><br />           domainObject.setCity(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">b</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br /><br />           request.getSession().setAttribute(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">domainObject</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, domainObject);<br /><br />           request.setAttribute(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">domains</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, DomainFactory.getInstance().getCity(domainObject.getCity()));<br /><br />           </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> mapping.findForward(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">left</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br /><br />      }    <br /> <br /><br />      </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> ActionForward getCatalogDataCategory(ActionMapping mapping, ActionForm form,<br /><br />                 HttpServletRequest request, HttpServletResponse response) {<br /><br />           request.setAttribute(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">productCategories</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, CategoryFactory.getInstance().getRootProductCategories());<br /><br />           </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> mapping.findForward(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">body</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br /><br />      }<br /></span></div><br /><p class="MsoNormal" style="margin-left: 42pt; text-indent: 21pt; line-height: 150%;"><span style="font-size: 10pt; line-height: 150%; font-family: Verdana; color: black;" lang="EN-US"><o:p></o:p></span></p><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">frameset rows</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">80,668*</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> cols</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">*</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> frameborder</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">no</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> border</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> framespacing</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br /><br />    </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">frame name</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">header</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> src</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">./search_header.jsp</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> scrolling</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">no</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> title</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">header</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> noresize</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">noresize</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br /><br />    </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">frameset cols</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">180,*</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> frameborder</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">yes</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> border</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> framespacing</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br /><br />       </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">frame name</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">left</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> scrolling</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">no</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> src</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">search.html?method=getCatalogData</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> target</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">_self</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> noresize</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">noresize</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br /><br />       </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);">frame name</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">body</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> scrolling</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">yes</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> src</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">search.html?method=getCatalogDataCategory</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> scrolling</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">yes</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> target</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">_self</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> noresize</span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">noresize</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />  </span><span style="color: rgb(0, 0, 0);">&lt;/</span><span style="color: rgb(0, 0, 0);">frameset</span><span style="color: rgb(0, 0, 0);">&gt;</span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 0, 0);">&lt;/</span><span style="color: rgb(0, 0, 0);">frameset</span><span style="color: rgb(0, 0, 0);">&gt;</span></div><br /><p class="MsoNormal" style="margin-left: 21pt; text-indent: 21pt; line-height: 150%;"><span style="font-size: 10pt; line-height: 150%; font-family: Verdana; color: black;" lang="EN-US"><o:p></o:p></span></p>

用if 出错了吧?为什么,同时进入了if(null == instance)的判断,然后争夺锁;结果争夺不到的只能在争夺到后容易出现问题,具体这里说不清楚,希望明白人跟贴进一步讨论之<br /><p class="MsoNormal" style="margin-left: 21pt; text-indent: 21pt; line-height: 150%;"><span style="background: white none repeat scroll 0%; font-size: 10pt; line-height: 150%; font-family: &quot;Courier New&quot;; color: teal; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" lang="EN-US"></span><span style="font-size: 10pt; line-height: 150%; font-family: Verdana; color: black;" lang="EN-US"><o:p></o:p></span></p><img src ="http://www.blogjava.net/crazycy/aggbug/58268.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/crazycy/" target="_blank">crazycy</a> 2006-07-15 00:02 <a href="http://www.blogjava.net/crazycy/archive/2006/07/15/58268.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>QQ群:Java技术联盟 第三次技术讨论之设计模式(完整版)</title><link>http://www.blogjava.net/crazycy/archive/2006/07/05/56866.html</link><dc:creator>crazycy</dc:creator><author>crazycy</author><pubDate>Wed, 05 Jul 2006 14:34:00 GMT</pubDate><guid>http://www.blogjava.net/crazycy/archive/2006/07/05/56866.html</guid><wfw:comment>http://www.blogjava.net/crazycy/comments/56866.html</wfw:comment><comments>http://www.blogjava.net/crazycy/archive/2006/07/05/56866.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.blogjava.net/crazycy/comments/commentRss/56866.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/crazycy/services/trackbacks/56866.html</trackback:ping><description><![CDATA[<ol>
    <li>首先介绍方法论，参考了《大道至简 — 软件工程实践者的思想》
    </li>
    <li>DP与Spring、SOA类比，皆出于实践
    </li>
    <li>DP的必要性和要点，辅助代码简要说明
    </li>
    <li>抛砖引玉，介绍几个DP：
    <ul>
        <ul>
            <li>&nbsp;&nbsp;Factory Pattern
            </li>
            <li>Decorator Pattern
            </li>
            <li>&nbsp;Proxy Pattern
            </li>
            <li>SingLeton Pattern
            </li>
            <li>Command Pattern
            </li>
            <li>其它 </li>
        </ul>
        <li>介绍点：
        <ul>
            <li>a)&nbsp;使用一些可与现实结合的生动例子（引用网上资源）
            </li>
            <li>介绍其本质（个人理解）
            </li>
            <li>简要介绍其如何使用 </li>
        </ul>
        </li>
    </ul>
    </li>
</ol>
<p><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;一&gt;开幕</p>
<p>大家好，我是crazycy，今天我们讨论的主题是Design Pattern</p>
<p>首先感谢千年一叹的安排和付出，虽然他极其的忙。</p>
<p>今天的话题可能不很适合初学者,对于初学者的建议可以看我的文章:<a href="http://www.blogjava.net/crazycy/archive/2006/07/07/57106.html">http://www.blogjava.net/crazycy/archive/2006/07/07/57106.html</a><br />
</p>
<p><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;二&gt; 设计模式的起因</p>
<p>在谈设计模式之前，我们想一下：为什么会有设计模式？</p>
<p>Christopher Alexander说：每一个模式描述了一个在我们周围不断重复发生的问题以及该问题的解决方案的核心。</p>
<p>咱们大多是做研发的，往往有自己的体会，遇到问题--解决问题，这个过程中会发现有一些问题及其解决方案不断变换面孔重复出现，其后面的有着共同的本质。实际上这些本质就是模式。<br />
<br />
从哲学角度说，设计模式的出现是实践经验的结晶，是产生于实践并指导实践。<br />
</p>
<p><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;三&gt;联想</p>
<p>说到这里，我们现在用的、谈的比较火爆的就是Spring Hibernate之类的框架。是吧？</p>
<p>Struts直接革新了Web Model 2的应用。<br />
Hibernate直接解决了持久层的非面向对象的尴尬。<br />
Spring直接挑战了原先的Java EE框架。<br />
<br />
这些都是源于实践。选择一种架构、一种技术的依据是什么？ Rod Johnson 认为，应该是基于实践的依据、来自历史项目或亲自试验的经验，而不是任何形式的偶像崇拜或者门户之见。 这个是循序方法：实践的反复总结。（十足的哲学）<br />
<br />
为什么说Spring是实践的总结：大家可以看一下我的blog的一片文章<a href="http://www.blogjava.net/crazycy/archive/2006/06/05/50519.aspx">http://www.blogjava.net/crazycy/archive/2006/06/05/50519.aspx</a>&nbsp; 比较简略。</p>
<p><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;四&gt; 哲学</p>
<p>周爱民先生的《大道至简 — 软件工程实践者的思想》对方法、方法论有如下描述：<br />
============================================================================================================<br />
<span style="line-height: 150%; font-family: Verdana;" lang="EN-US">3. </span><span style="line-height: 150%; font-family: 宋体;">方法</span><span style="line-height: 150%; font-family: Verdana;" lang="EN-US"><o:p></o:p></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21pt; line-height: 150%;"><span style="font-family: 宋体;">推动这种逻辑向前发展的，是</span> <span lang="EN-US">&#8220;</span> <span style="font-family: 宋体;">方法</span> <span lang="EN-US">&#8221;</span> <span style="font-family: 宋体;">和</span> <span lang="EN-US">&#8220;</span> <span style="font-family: 宋体;">方法论</span> <span lang="EN-US">&#8221;</span> <span style="font-family: 宋体;">的出现。长期的编程实践，自然的归演与总结，必须沉淀为某种</span> <span lang="EN-US">(</span> <span style="font-family: 宋体;">软件开发</span> <span lang="EN-US">)</span> <span style="font-family: 宋体;">方法，于是</span> <span lang="EN-US">&#8220;</span> <span style="font-family: 宋体;">过程</span> <span lang="EN-US">&#8221;</span> <span style="font-family: 宋体;">出现了，于是</span> <span lang="EN-US">&#8220;</span> <span style="font-family: 宋体;">对象</span> <span lang="EN-US">&#8221;</span> <span style="font-family: 宋体;">出现了，于是相关的方法论也就出现了。</span> </p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21pt; line-height: 150%;"><span style="font-family: 宋体;">这是实践的成果。方法不是某个人或者某个组织创造的。瓜熟而蒂落，实践积累达到一定的程度，微软不提出某个方法，</span> <span lang="EN-US">IBM</span> <span style="font-family: 宋体;">也会提出这个方法。即便他们都不提出，可能你自己已经在使用这个方法了。</span> </p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21pt; line-height: 150%;"><span style="font-family: 宋体;">方法并不神秘，因为它就是你今天正在做的、从事的和实现的。正如</span> <span lang="EN-US">&#8220;</span> <span style="font-family: 宋体;">模式</span> <span lang="EN-US">&#8221;</span> <span style="font-family: 宋体;">是一种方法，而模式就是你昨天书写代码的那个行为。只不过，</span> <span lang="EN-US">GoF</span> <span style="font-family: 宋体;">归纳、抽取、提升了这些行为的内在规律。</span> </p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21pt; line-height: 150%;"><span style="font-family: 宋体;">你看不到你做事的行为，也就不能理解</span> <span lang="EN-US">&#8220;</span> <span style="font-family: 宋体;">模式</span> <span lang="EN-US">&#8221;</span> <span style="font-family: 宋体;">作为一种方法的价值。所以大师们众口一词：模式需要一定的编程经验才能理解。</span> </p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21pt; line-height: 150%;"><span style="font-family: 宋体;">同理，理解过程也需要编程经验，理解对象也需要编程经验，理解</span> <span lang="EN-US">MDA</span> <span style="font-family: 宋体;">与</span> <span lang="EN-US">SOA</span> <span style="font-family: 宋体;">还是需要编程经验。</span> </p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21pt; line-height: 150%;"><span lang="EN-US">——</span> <span style="font-family: 宋体;">这可能就发生在你去回顾你上一行代码编写的经过，或者上一个项目失败的经历的那一瞬息。经验来源于回顾、理解与分析，而不是你将要写的下一行代码。</span> </p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21pt; line-height: 150%;"><span style="font-family: 宋体;">有人在寺院扫了一辈子的落叶而得道，也有人因为一句话而得道。</span> </p>
<div style="border-style: none none double; border-color: -moz-use-text-color; border-width: medium medium 2.25pt; padding: 0cm 0cm 1pt;">
<p class="MsoNormal" style="border: medium none ; margin: 0cm 0cm 0pt; padding: 0cm; text-indent: 21pt; line-height: 150%;"><span lang="EN-US">GoF</span> <span style="font-family: 宋体;">因为无数次的代码回顾而得道。</span> </p>
</div>
<p>感觉不过瘾可以看一下我的blog文章：<br />
<a href="http://www.blogjava.net/crazycy/archive/2006/05/24/47799.html">http://www.blogjava.net/crazycy/archive/2006/05/24/47799.html</a></p>
<p>而对于方法论，查了一下大概阐述如下：方法论是一套完整的实践引导体系，是指导实践的理论基础，是人们在长期社会实践中总结和摸索出来的，符合客观发展规律的，符合人们对研究对象进行科学分析与判断的社会实践进程或步骤。方法是实践的成果，如同瓜熟蒂落，实践积累达到一定程度，必然会提出方法。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;五&gt;DP产生的必要性和目标</p>
<p>咱们大家对OO编程都熟悉，OO的三个基本特征：封装、继承、多态。<br />
<br />
OO解决不了的问题--Java为例子：<br />
java语言要求将一个类实例化时，必须调用这个类的具体类的构造子，所以java语言给出的类的实例化方法无法做到只依赖抽象类型。<br />
这造成了调用者合被调用者的一种紧耦合<br />
<br />
<font color="#ff1493">设计模式追求的目标是调用者和被调用者之间的解耦。</font><br />
<br />
示例：<br />
消费一个对象的客户端只依赖于对象的抽象类型，而不是具体类型</p>
<p>A类：<br />
State state = new StartState();<br />
工厂类：<br />
public class StateFactory {<br />
public State static createState() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; State state&nbsp; =&nbsp; new. StartState();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return state;<br />
&nbsp;&nbsp;&nbsp; }&nbsp;<br />
}<br />
A类：<br />
State state = StateFactory.createState();<br />
这样就很容易理解工厂类就是生产对象，也就是创建对象，把对象的创建过程从类A中摘取出来.</p>
<p>这样也就达到了DP的目标，也正是因为这个目标的提出，才诞生了IoC。<br />
可以参考的我blog文章：<a href="http://www.blogjava.net/crazycy/archive/2006/03/19/36068.aspx">http://www.blogjava.net/crazycy/archive/2006/03/19/36068.aspx</a><br />
</p>
<p><br />
这里有朋友问抽象工厂和工厂方法两个模式的区别，<br />
可以参考我的blog文章：<a href="http://www.blogjava.net/crazycy/archive/2006/10/08/73858.html">http://www.blogjava.net/crazycy/archive/2006/10/08/73858.html</a></p>
<p><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;六&gt;介绍几个模式<br />
Decorator模式是<br />
1.&nbsp;对真实对象进行包装 <br />
2.&nbsp;使其功能扩展 <br />
3.&nbsp;表现形式：new 包装类1（new 包装类2(真实对象)）；这样真实对象就具备了本身、包装类1、包装类2的功能；<br />
4.&nbsp;实现时只需要把真实对象做为包装类的聚合对象； <br />
实在不行就想想ML时，如果带上TT后，原来的不影响，而且还安全了。主要就是包装原先的对象。</p>
<p>可参考我的blog文章：<a href="http://www.blogjava.net/crazycy/archive/2006/04/30/44169.html">http://www.blogjava.net/crazycy/archive/2006/04/30/44169.html</a></p>
<p><br />
<br />
Dynamic Proxy模式是<br />
代理模式（Proxy，这里侧重于Dynamic Proxy）可以理解成给一个对象提供一个代理对象，这个代理对象就是把原对象进行包装，使其与调用处理器相关联。<br />
因为代理对象和真实对象具有相同的接口，客户访问时，通过接口调用代理实例的方法，这个调用会被分发到该实例对应的处理器。处理器在把客户端调用传递给真实的对象之前或者之后，可执行某个操作，也可以选择不把这个调用传递给真实的对象。<br />
1.&nbsp;将真实对象包装 <br />
2.&nbsp;使其与调用处理类绑定 <br />
3.&nbsp;表现形式：Proxy.newProxyInstance(realObject.getClass(). getClassLoader(), realObject.getClass().getInterfaces(), new InvocationHandler(realObj))；这样真实对象就与InvocationHandler类邦定了，对外是一个代理类的形式；<br />
4.&nbsp;实现时只需要把真实对象做为调用处理器的聚合对象 <br />
实在不行就想想：垂帘听政：犹如清朝康熙年间的四大府臣，很多权利不在皇帝手里，必须通过辅佐大臣去办；<br />
具体示例参加blog：<br />
<a href="http://www.blogjava.net/crazycy/archive/2006/04/29/44006.html">http://www.blogjava.net/crazycy/archive/2006/04/29/44006.html</a></p>
<p><br />
Command模式<br />
本质：将调用操作的对象 和 知道如何实现改操作的对象 解耦。<br />
1 调用者<br />
&nbsp;发出请求的对象，请求被包装成请求对象的形式（侧重于对象）<br />
2 接收者<br />
&nbsp;知道如何处理某个请求的对象。<br />
3 关联者<br />
&nbsp;具备调用者传入的请求对象；<br />
&nbsp;&nbsp; 并且绑定接收者。</p>
<p>大家都用过Struts吧？<br />
或许Struts的Action就是一个很好的说明示例：<br />
&nbsp;Public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest req, HttpServletResponse res)<br />
方法的action就是关联者<br />
方法的req可以理解成请求者<br />
方法的form 就是请求对象 <br />
方法的mapping就是接收者</p>
<p>&nbsp;</p>
<img src ="http://www.blogjava.net/crazycy/aggbug/56866.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/crazycy/" target="_blank">crazycy</a> 2006-07-05 22:34 <a href="http://www.blogjava.net/crazycy/archive/2006/07/05/56866.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>QQ群:Java技术联盟 第三次技术讨论之设计模式(大纲)</title><link>http://www.blogjava.net/crazycy/archive/2006/07/04/56595.html</link><dc:creator>crazycy</dc:creator><author>crazycy</author><pubDate>Tue, 04 Jul 2006 13:52:00 GMT</pubDate><guid>http://www.blogjava.net/crazycy/archive/2006/07/04/56595.html</guid><wfw:comment>http://www.blogjava.net/crazycy/comments/56595.html</wfw:comment><comments>http://www.blogjava.net/crazycy/archive/2006/07/04/56595.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/crazycy/comments/commentRss/56595.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/crazycy/services/trackbacks/56595.html</trackback:ping><description><![CDATA[大纲:<br /><br />1.    首先介绍方法论，参考了《大道至简—软件工程者实践》<br />2.    DP与Spring、SOA类比，皆出于实践<br />3.    DP的必要性和要点，辅助代码简要说明<br />4.    抛砖引玉，介绍几个DP：<br />    a)    Factory Pattern<br />    b)    Decorator Pattern<br />    c)    Proxy Pattern<br />    d)    SingLeton Pattern<br />    e)    Command Pattern<br />    f)    其它看情况<br />介绍点：<br />    a)    使用一些可与现实结合的生动例子<br />    b)    介绍其本质（个人理解）<br />    c)    简要介绍其如何使用<br /><br />具体内容:<br /><img src ="http://www.blogjava.net/crazycy/aggbug/56595.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/crazycy/" target="_blank">crazycy</a> 2006-07-04 21:52 <a href="http://www.blogjava.net/crazycy/archive/2006/07/04/56595.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>我对设计模式的理解：模式的目标</title><link>http://www.blogjava.net/crazycy/archive/2006/07/03/56381.html</link><dc:creator>crazycy</dc:creator><author>crazycy</author><pubDate>Mon, 03 Jul 2006 09:06:00 GMT</pubDate><guid>http://www.blogjava.net/crazycy/archive/2006/07/03/56381.html</guid><wfw:comment>http://www.blogjava.net/crazycy/comments/56381.html</wfw:comment><comments>http://www.blogjava.net/crazycy/archive/2006/07/03/56381.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/crazycy/comments/commentRss/56381.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/crazycy/services/trackbacks/56381.html</trackback:ping><description><![CDATA[
		<p class="MsoNormal">
				<span style="font-size: 12pt; font-family: 宋体;">设计模式（Design Pattern）追求的目标是调用者和被调用者之间的解耦。</span>
				<span style="font-size: 12pt;" lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</p>
		<span style="font-size: 12pt; font-family: 宋体;">
				<br />
		</span>
<img src ="http://www.blogjava.net/crazycy/aggbug/56381.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/crazycy/" target="_blank">crazycy</a> 2006-07-03 17:06 <a href="http://www.blogjava.net/crazycy/archive/2006/07/03/56381.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>我对设计模式的理解：命令模式（Command Pattern）</title><link>http://www.blogjava.net/crazycy/archive/2006/07/03/56380.html</link><dc:creator>crazycy</dc:creator><author>crazycy</author><pubDate>Mon, 03 Jul 2006 09:05:00 GMT</pubDate><guid>http://www.blogjava.net/crazycy/archive/2006/07/03/56380.html</guid><wfw:comment>http://www.blogjava.net/crazycy/comments/56380.html</wfw:comment><comments>http://www.blogjava.net/crazycy/archive/2006/07/03/56380.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/crazycy/comments/commentRss/56380.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/crazycy/services/trackbacks/56380.html</trackback:ping><description><![CDATA[
		<font size="3">
				<span style="font-size: 12pt; font-family: 宋体;">本质：将调用操作的对象</span>
				<span style="font-size: 12pt;">
				</span>
				<span style="font-size: 12pt; font-family: 宋体;">和</span>
				<span style="font-size: 12pt;">
				</span>
				<span style="font-size: 12pt; font-family: 宋体;">知道如何实现改操作的对象</span>
				<span style="font-size: 12pt;">
				</span>
				<span style="font-size: 12pt; font-family: 宋体;">解耦。</span>
				<span style="font-size: 12pt;" lang="EN-US">
						<o:p>
						</o:p>
				</span>
		</font>
		<p class="MsoNormal">
				<font size="3">
						<span style="font-size: 12pt;" lang="EN-US">1 </span>
						<span style="font-size: 12pt; font-family: 宋体;">调用者</span>
						<span style="font-size: 12pt;" lang="EN-US">
								<o:p>
								</o:p>
						</span>
				</font>
		</p>
		<p class="MsoNormal">
				<font size="3">
						<span style="font-size: 12pt;" lang="EN-US">
								<span style="">       </span>
						</span>
						<span style="font-size: 12pt; font-family: 宋体;">发出请求   的对象，请求被包装成请求对象的形式（重点是封装成了请求对象）</span>
						<span style="font-size: 12pt;" lang="EN-US">
								<o:p>
								</o:p>
						</span>
				</font>
		</p>
		<p class="MsoNormal">
				<font size="3">
						<span style="font-size: 12pt;" lang="EN-US">2 </span>
						<span style="font-size: 12pt; font-family: 宋体;">接收者</span>
						<span style="font-size: 12pt;" lang="EN-US">
								<o:p>
								</o:p>
						</span>
				</font>
		</p>
		<p class="MsoNormal">
				<font size="3">
						<span style="font-size: 12pt;" lang="EN-US">
								<span style="">       是    </span>
						</span>
						<span style="font-size: 12pt; font-family: 宋体;">知道如何处理某个请求   的对象。</span>
						<span style="font-size: 12pt;" lang="EN-US">
								<o:p>
								</o:p>
						</span>
				</font>
		</p>
		<p class="MsoNormal">
				<font size="3">
						<span style="font-size: 12pt;" lang="EN-US">3 </span>
						<span style="font-size: 12pt; font-family: 宋体;">关联者</span>
						<span style="font-size: 12pt;" lang="EN-US">
								<o:p>
								</o:p>
						</span>
				</font>
		</p>
		<ul>
				<li>
						<font size="3">
								<span style="font-size: 12pt;" lang="EN-US">
										<span style="">   </span>
								</span>
								<span style="font-size: 12pt; font-family: 宋体;">具有调用者传入的请求对象；</span>
								<span style="font-size: 12pt;" lang="EN-US">
										<o:p>
										</o:p>
								</span>
						</font>
				</li>
		</ul>
		<ul>
				<li>
						<font size="3">
								<span style="font-size: 12pt;" lang="EN-US">
										<span style="">   </span>
								</span>
								<span style="font-size: 12pt; font-family: 宋体;">并且绑定接收者。</span>
								<span style="font-size: 12pt;" lang="EN-US">
										<o:p>
										</o:p>
								</span>
						</font>
				</li>
		</ul>
		<p class="MsoNormal">
				<font size="3">
						<span style="font-size: 12pt; font-family: 宋体;">
								<br />
						</span>
				</font>
		</p>
		<p class="MsoNormal">
				<font size="3">
						<span style="font-size: 12pt; font-family: 宋体;">或许</span>
						<span style="font-size: 12pt;" lang="EN-US">Struts</span>
						<span style="font-size: 12pt; font-family: 宋体;">的Action就是一个很好的说明示例：</span>
						<span style="font-size: 12pt;" lang="EN-US">
								<o:p>
								</o:p>
						</span>
				</font>
		</p>
		<p class="MsoNormal">
				<font size="3">
						<span style="font-size: 12pt;" lang="EN-US">
								<o:p> </o:p>Public
ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest req, HttpServletResponse res)<o:p></o:p></span>
				</font>
		</p>
		<p class="MsoNormal">
				<font size="3">
						<span style="font-size: 12pt;" lang="EN-US">
								<o:p>方法的</o:p>action</span>
						<span style="font-size: 12pt; font-family: 宋体;">就是关联者</span>
						<span style="font-size: 12pt;" lang="EN-US">
								<o:p>
								</o:p>
						</span>
				</font>
		</p>
		<p class="MsoNormal">
				<font size="3">
						<span style="font-size: 12pt;" lang="EN-US">方法的req可以理解成请求者<br /></span>
				</font>
		</p>
		<p class="MsoNormal">
				<font size="3">
						<span style="font-size: 12pt;" lang="EN-US">方法的form </span>
						<span style="font-size: 12pt; font-family: 宋体;">就是请求对象</span>
						<span style="font-size: 12pt;" lang="EN-US">
								<br />
						</span>
				</font>
		</p>
		<p class="MsoNormal">
				<font size="3">
						<span style="font-size: 12pt;" lang="EN-US">方法的mapping</span>
						<span style="font-size: 12pt; font-family: 宋体;">就是接收者</span>
						<span style="font-size: 12pt;" lang="EN-US">
								<o:p>
								</o:p>
						</span>
				</font>
		</p>
<img src ="http://www.blogjava.net/crazycy/aggbug/56380.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/crazycy/" target="_blank">crazycy</a> 2006-07-03 17:05 <a href="http://www.blogjava.net/crazycy/archive/2006/07/03/56380.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>最近突然觉得设计模式很美</title><link>http://www.blogjava.net/crazycy/archive/2006/05/29/48689.html</link><dc:creator>crazycy</dc:creator><author>crazycy</author><pubDate>Mon, 29 May 2006 02:21:00 GMT</pubDate><guid>http://www.blogjava.net/crazycy/archive/2006/05/29/48689.html</guid><wfw:comment>http://www.blogjava.net/crazycy/comments/48689.html</wfw:comment><comments>http://www.blogjava.net/crazycy/archive/2006/05/29/48689.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/crazycy/comments/commentRss/48689.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/crazycy/services/trackbacks/48689.html</trackback:ping><description><![CDATA[    GoF，Java与模式摆在电脑桌旁已有半年，说实话就是把GoF看了不到10页的内容，一直束之高阁。<br /><br />    在大概一年半左右的开发后，代码量累计至少有7.5w，无意间打开GoF的Design Pattern，发现许多思想真的很美，如同一朵散发奇香的花。<br />    <br />    平时大量的单例使用，Singleton模式再次更新了一些认识;<br /><br />    因为AOP的服务截获,让我痴迷上动态代理（Dynamic Proxy）；<br /><br />    因为多层继承的不方便，让我很是欢喜装饰模式（Decorator）；而且我还用男女“欢乐”之事给朋友（男）生动介绍这个模式的本质。<br /><br />    因为Struts的action机制，以及web modle的发展历程，让我很是感慨于命令模式（Command）。<br />    <br />    对这几个模式由衷的喜爱着，也在脑海中不断品味，呵呵，记录一下，为日后更加成熟认识备案初涉之痕迹。<br /><img src ="http://www.blogjava.net/crazycy/aggbug/48689.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/crazycy/" target="_blank">crazycy</a> 2006-05-29 10:21 <a href="http://www.blogjava.net/crazycy/archive/2006/05/29/48689.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>我对设计模式的理解：观察者模式（Observer Pattern）</title><link>http://www.blogjava.net/crazycy/archive/2006/05/29/48685.html</link><dc:creator>crazycy</dc:creator><author>crazycy</author><pubDate>Mon, 29 May 2006 02:01:00 GMT</pubDate><guid>http://www.blogjava.net/crazycy/archive/2006/05/29/48685.html</guid><wfw:comment>http://www.blogjava.net/crazycy/comments/48685.html</wfw:comment><comments>http://www.blogjava.net/crazycy/archive/2006/05/29/48685.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/crazycy/comments/commentRss/48685.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/crazycy/services/trackbacks/48685.html</trackback:ping><description><![CDATA[
		<p class="MsoNormal" style="TEXT-INDENT: 21pt; LINE-HEIGHT: 150%">
				<span style="LINE-HEIGHT: 150%; FONT-FAMILY: 宋体">在</span>
				<span lang="EN-US" style="LINE-HEIGHT: 150%; FONT-FAMILY: Arial">GoF P194 5.7Section”</span>
				<span style="LINE-HEIGHT: 150%; FONT-FAMILY: 宋体">动机</span>
				<span lang="EN-US" style="LINE-HEIGHT: 150%; FONT-FAMILY: Arial">”</span>
				<span style="LINE-HEIGHT: 150%; FONT-FAMILY: 宋体">中有应用的描述，如果对应用的</span>
				<span lang="EN-US" style="LINE-HEIGHT: 150%; FONT-FAMILY: Arial">Obersers</span>
				<span style="LINE-HEIGHT: 150%; FONT-FAMILY: 宋体">进行再一次抽象，其可以继承一个公用的接口</span>
				<span lang="EN-US" style="LINE-HEIGHT: 150%; FONT-FAMILY: Arial">Listener</span>
				<span style="LINE-HEIGHT: 150%; FONT-FAMILY: 宋体">。这是这一步抽象，对这个模式将有更好的理解。</span>
				<span lang="EN-US" style="LINE-HEIGHT: 150%; FONT-FAMILY: Arial">
						<?xml:namespace prefix = o /?>
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="TEXT-INDENT: 21pt; LINE-HEIGHT: 150%">
				<span style="LINE-HEIGHT: 150%; FONT-FAMILY: 宋体">而最初在接触观察者模式前，我花费了大概4天左右的时间，一直在考虑Java提供的事件机制，尤其是GUI方面的使用，因为对GUI可以说是我的一个盲点，因此尝试从思想上有所截获。最终我归纳如下：</span>
				<span lang="EN-US" style="LINE-HEIGHT: 150%; FONT-FAMILY: Arial">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; LINE-HEIGHT: 150%">
				<span lang="EN-US" style="LINE-HEIGHT: 150%; FONT-FAMILY: Arial">
						<span>1.<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">      </span></span>
				</span>
				<span style="LINE-HEIGHT: 150%; FONT-FAMILY: 宋体">监听者注册即调用时间源的注册方法，并以监听者接口为参数；</span>
				<span lang="EN-US" style="LINE-HEIGHT: 150%; FONT-FAMILY: Arial">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; LINE-HEIGHT: 150%">
				<span lang="EN-US" style="LINE-HEIGHT: 150%; FONT-FAMILY: Arial">
						<span>2.<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">      </span></span>
				</span>
				<span style="LINE-HEIGHT: 150%; FONT-FAMILY: 宋体">事件源通知即调用监听者方法传递消息；</span>
				<span lang="EN-US" style="LINE-HEIGHT: 150%; FONT-FAMILY: Arial">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; LINE-HEIGHT: 150%">
				<span lang="EN-US" style="LINE-HEIGHT: 150%; FONT-FAMILY: Arial">
						<span>3.<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">      </span></span>
				</span>
				<span style="LINE-HEIGHT: 150%; FONT-FAMILY: 宋体">通知的消息可以是一个事件对象；</span>
				<span lang="EN-US" style="LINE-HEIGHT: 150%; FONT-FAMILY: Arial">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; LINE-HEIGHT: 150%">
				<span lang="EN-US" style="LINE-HEIGHT: 150%; FONT-FAMILY: Arial">
						<span>4.<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">      </span></span>
				</span>
				<span style="LINE-HEIGHT: 150%; FONT-FAMILY: 宋体">通知的方式就是监听者接口的方法，且以事件对象为参数。</span>
				<span lang="EN-US" style="LINE-HEIGHT: 150%; FONT-FAMILY: Arial">
						<o:p>
						</o:p>
				</span>
		</p>   现在读GoF的Observer描述，很是有醍醐灌顶之感。<br />    <br />   不过如果没有那段时间的摸索，估计难有如此的体验。<br /><img src ="http://www.blogjava.net/crazycy/aggbug/48685.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/crazycy/" target="_blank">crazycy</a> 2006-05-29 10:01 <a href="http://www.blogjava.net/crazycy/archive/2006/05/29/48685.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>我对设计模式的理解：Decorator模式与Dynamic Proxy模式</title><link>http://www.blogjava.net/crazycy/archive/2006/04/30/44169.html</link><dc:creator>crazycy</dc:creator><author>crazycy</author><pubDate>Sun, 30 Apr 2006 04:51:00 GMT</pubDate><guid>http://www.blogjava.net/crazycy/archive/2006/04/30/44169.html</guid><wfw:comment>http://www.blogjava.net/crazycy/comments/44169.html</wfw:comment><comments>http://www.blogjava.net/crazycy/archive/2006/04/30/44169.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/crazycy/comments/commentRss/44169.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/crazycy/services/trackbacks/44169.html</trackback:ping><description><![CDATA[<p>Decorator模式是</p>
<ol>
    <li>对真实对象进行包装
    <li>使其功能扩展
    <li>表现形式：new 包装类1（new 包装类2(真实对象)）；这样真实对象就具备了本身、包装类1、包装类2的功能；实现时只需要把真实对象做为包装类的聚合对象； </li>
</ol>
<p>&nbsp;</p>
<p>Dynamic Proxy模式是</p>
<ol>
    <li>将真实对象包装
    <li>使其与调用处理类绑定
    <li>表现形式：Proxy.newProxyInstance(realObject.getClass().getClassLoader(), realObject.getClass().getInterfaces(), new InvocationHandler(realObj))；这样真实对象就与InvocationHandler类邦定了，对外是一个代理类的形式；实现时只需要把真实对象做为调用处理器的聚合对象 </li>
</ol>
<p>&nbsp;</p>
<p>==============以下是引用，2007年05月01日增加===============</p>
<p>首先我们来明确一下动态代理的定义：<font color=#000080>一个动态代理类在运行期implements一组interface，使得interface实现类的方法调用被分派至其他的类(另外的interface实现类或者任意的类)的方法</font>。讲得更通俗一些，要了解动态代理，我们就要知道什么东西动态了，代理了什么？首先，一个Proxy代理了一组interface的方法。注意，<font color=#000080>代理的是interface</font>，而不是Class，也不是abstract Class；其次，<font color=#000080>Proxy具有的型别由绑定的interface所决定的</font>，动态就体现在此。也许看着这样的定义，还是会一头雾水，那么我们画幅图来看看吧。 </p>
<p align=center><img height=326 alt=dynamicProxy.gif src="http://www.cnblogs.com/images/cnblogs_com/perhaps/dynamicProxy.gif" width=509 border=0> </p>
<p>从图中，我们可以看到Dynamic Proxy并没有实现Resource这个接口，但是包含了Resource接口实现类的实例；在Dynamic Proxy的create方法中，通过调用Proxy.newProxyInstance创建一个Proxy，并将该Proxy与Resource接口绑定，最后将Proxy显式类型转换成Resource接口类型并返回，这样调用者就可以通过Proxy调用interface定义的方法了；由于Proxy与Resource接口绑定了，对Resource接口的方法调用，都会交由Proxy的invoke方法去处理。而invoke方法会根据不同的方法，或给以全新的实现，或直接将方法调用交给Proxy中包含的Resource接口实现类的实例去处理。综合上面所说的，作为一个Dynamic Proxy，它必须满足以下三个条件： <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1、实现了InvocationHandler接口，实现接口中定义的invoke方法； <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2、包含接口实现类的实例； <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3、通过Proxy.newProxyInstance方法实现Proxy与接口之间的绑定。 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 以下代码给出了一个简单的Dynamic Proxy实现： </p>
<div style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<div><font face="Courier New"><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">interface</span><span style="COLOR: #000000">&nbsp;Resource&nbsp;</span><span id=Codehighlighter1_26_88_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"></span></font><span id=Codehighlighter1_26_88_Open_Text><font face="Courier New"><span style="COLOR: #000000">{ <br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span></font><font face="Courier New"><span style="COLOR: #000000">&nbsp;operationA(); <br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span></font><span style="COLOR: #000000"><font face="Courier New">&nbsp;operationB(); <br>}</font></span></span> </div>
</div>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font face=Arial> <br></p>
<div style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<div><font face="Courier New"><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;ConcreteResource&nbsp;implements&nbsp;Resource&nbsp;</span><span id=Codehighlighter1_50_204_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"></span></font><span id=Codehighlighter1_50_204_Open_Text><font face="Courier New"><span style="COLOR: #000000">{ <br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;operationA()&nbsp;</span><span id=Codehighlighter1_81_124_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"></span></font><span id=Codehighlighter1_81_124_Open_Text><font face="Courier New"><span style="COLOR: #000000">{ <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.</span><span style="COLOR: #0000ff">out</span><span style="COLOR: #000000">.println(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Operation&nbsp;A.</span><span style="COLOR: #000000">"</span></font><span style="COLOR: #000000"><font face="Courier New">); <br>&nbsp;&nbsp;&nbsp;&nbsp;}</font></span></span><span style="COLOR: #000000"> <br><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;</font></span><font face="Courier New"><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;operationB()&nbsp;</span><span id=Codehighlighter1_155_202_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"></span></font><span id=Codehighlighter1_155_202_Open_Text><font face="Courier New"><span style="COLOR: #000000">{ <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.</span><span style="COLOR: #0000ff">out</span><span style="COLOR: #000000">.println(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Operation&nbsp;B.</span><span style="COLOR: #000000">"</span></font><span style="COLOR: #000000"><font face="Courier New">); <br>&nbsp;&nbsp;&nbsp;&nbsp;}</font></span></span><span style="COLOR: #000000"> <br><font face="Courier New">}</font></span></span> </div>
</div>
<p></font><font face=Verdana>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font face=Arial> <br></font></p>
<div style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<div><font face="Courier New"><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;DynamicProxy&nbsp;implements&nbsp;InvocationHandler&nbsp;</span><span id=Codehighlighter1_55_828_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"></span></font><span id=Codehighlighter1_55_828_Open_Text><font face="Courier New"><span style="COLOR: #000000">{ <br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">private</span></font><font face="Courier New"><span style="COLOR: #000000">&nbsp;Resource&nbsp;resource; <br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;DynamicProxy()&nbsp;</span><span id=Codehighlighter1_115_164_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"></span></font><span id=Codehighlighter1_115_164_Open_Text><font face="Courier New"><span style="COLOR: #000000">{ <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resource&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span></font><span style="COLOR: #000000"><font face="Courier New">&nbsp;ConcreteResource(); <br>&nbsp;&nbsp;&nbsp;&nbsp;}</font></span></span><span style="COLOR: #000000"> <br><font face="Courier New"><br>&nbsp;&nbsp;&nbsp;&nbsp;</font></span><font face="Courier New"><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;Resource&nbsp;create()&nbsp;</span><span id=Codehighlighter1_196_421_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"></span></font><span id=Codehighlighter1_196_421_Open_Text><font face="Courier New"><span style="COLOR: #000000">{ <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Resource&nbsp;returnResource&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">null</span></font><font face="Courier New"><span style="COLOR: #000000">; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;returnResource&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;(Resource)&nbsp;Proxy.newProxyInstance(Resource.</span><span style="COLOR: #0000ff">class</span></font><span style="COLOR: #000000"> <br><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.getClassLoader(),&nbsp;</font></span><font face="Courier New"><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;Class[]&nbsp;</span><span id=Codehighlighter1_359_376_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"></span><span id=Codehighlighter1_359_376_Open_Text><span style="COLOR: #000000">{&nbsp;Resource.</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;}</span></span><span style="COLOR: #000000">,&nbsp; <br></span><span style="COLOR: #0000ff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this</span></font><font face="Courier New"><span style="COLOR: #000000">); <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span></font><span style="COLOR: #000000"><font face="Courier New">&nbsp;returnResource; <br>&nbsp;&nbsp;&nbsp;&nbsp;}</font></span></span><span style="COLOR: #000000"> <br><font face="Courier New"><br>&nbsp;&nbsp;&nbsp;&nbsp;</font></span><font face="Courier New"><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;Object&nbsp;invoke(Object&nbsp;obj,&nbsp;Method&nbsp;method,&nbsp;Object[]&nbsp;args)&nbsp;</span><span id=Codehighlighter1_491_826_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"></span></font><span id=Codehighlighter1_491_826_Open_Text><font face="Courier New"><span style="COLOR: #000000">{ <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object&nbsp;o&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">null</span></font><font face="Courier New"><span style="COLOR: #000000">; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">try</span><span style="COLOR: #000000">&nbsp;</span><span id=Codehighlighter1_530_737_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"></span></font><span id=Codehighlighter1_530_737_Open_Text><font face="Courier New"><span style="COLOR: #000000">{ <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(method.getName().equals(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">operationA</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">))&nbsp;</span><span id=Codehighlighter1_587_660_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"></span></font><span id=Codehighlighter1_587_660_Open_Text><font face="Courier New"><span style="COLOR: #000000">{ <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.</span><span style="COLOR: #0000ff">out</span><span style="COLOR: #000000">.println(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">OperationA&nbsp;in&nbsp;Proxy</span><span style="COLOR: #000000">"</span></font><span style="COLOR: #000000"><font face="Courier New">); <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</font></span></span><font face="Courier New"><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000">&nbsp;</span><span id=Codehighlighter1_667_727_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"></span></font><span id=Codehighlighter1_667_727_Open_Text><font face="Courier New"><span style="COLOR: #000000">{ <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;o&nbsp;</span><span style="COLOR: #000000">=</span></font><span style="COLOR: #000000"><font face="Courier New">&nbsp;method.invoke(obj,&nbsp;args); <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</font></span></span><span style="COLOR: #000000"> <br><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</font></span></span><font face="Courier New"><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">catch</span><span style="COLOR: #000000">&nbsp;(Exception&nbsp;e)&nbsp;</span><span id=Codehighlighter1_759_802_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"></span></font><span id=Codehighlighter1_759_802_Open_Text><span style="COLOR: #000000"><font face="Courier New">{ <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</font></span></span><span style="COLOR: #000000"> <br><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font></span><span style="COLOR: #0000ff"><font face="Courier New">return</font></span><span style="COLOR: #000000"><font face="Courier New">&nbsp;o; <br>&nbsp;&nbsp;&nbsp;&nbsp;}</font></span></span><span style="COLOR: #000000"> <br><font face="Courier New">}</font></span></span> </div>
</div>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font face=Arial> <br></p>
<div style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
<div><font face="Courier New"><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;Test&nbsp;</span><span id=Codehighlighter1_18_186_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"></span></font><span id=Codehighlighter1_18_186_Open_Text><font face="Courier New"><span style="COLOR: #000000">{ <br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;main(String[]&nbsp;args)&nbsp;</span><span id=Codehighlighter1_63_184_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"></span></font><span id=Codehighlighter1_63_184_Open_Text><font face="Courier New"><span style="COLOR: #000000">{ <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DynamicProxy&nbsp;proxy&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span></font><font face="Courier New"><span style="COLOR: #000000">&nbsp;DynamicProxy(); <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Resource&nbsp;resource&nbsp;</span><span style="COLOR: #000000">=</span></font><span style="COLOR: #000000"><font face="Courier New">&nbsp;proxy.create(); <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resource.operationA(); <br>&nbsp;&nbsp;&nbsp;&nbsp;}</font></span></span><span style="COLOR: #000000"> <br><font face="Courier New">}</font></span></span> </div>
</div>
<br><br><br>
<div class=postTitle><a id=viewpost1_TitleUrl href="http://www.cnblogs.com/simpleobject/archive/2005/10/10/251402.html"><font color=#000080>用Java动态代理实现AOP</font></a> </div>
<div class=postText>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 目前整个开发社区对AOP(Aspect Oriented Programing)推崇备至，也涌现出大量支持AOP的优秀Framework,--Spring, JAC, Jboss AOP 等等。AOP似乎一时之间成了潮流。Java初学者不禁要发出感慨，OOP还没有学通呢，又来AOP。本文不是要在理论上具体阐述何为AOP, 为何要进行AOP . 要详细了解学习AOP可以到它老家http://aosd.net去瞧瞧。这里只是意图通过一个简单的例子向初学者展示一下如何来进行AOP.<br><br>　　为了简单起见，例子没有没有使用任何第三方的AOP Framework, 而是利用Java语言本身自带的动态代理功能来实现AOP. <br><br>　　让我们先回到AOP本身，AOP主要应用于日志记录，性能统计，安全控制,事务处理等方面。它的主要意图就要将日志记录，性能统计，安全控制等等代码从商业逻辑代码中清楚的划分出来，我们可以把这些行为一个一个单独看作系统所要解决的问题，就是所谓的面向问题的编程(不知将AOP译作面向问题的编程是否欠妥)。通过对这些行为的分离，我们希望可以将它们独立地配置到商业方法中，而要改变这些行为也不需要影响到商业方法代码。 <br><br>　　假设系统由一系列的BusinessObject所完成业务逻辑功能，系统要求在每一次业务逻辑处理时要做日志记录。这里我们略去具体的业务逻辑代码。 <br><br>
<table borderColor=#ffcc66 width="90%" align=center bgColor=#e6e4dd border=1>
    <tbody>
        <tr>
            <td>public interface BusinessInterface { <br>　public void processBusiness(); <br>} <br><br>public class BusinessObject implements BusinessInterface { <br>　private Logger logger = Logger.getLogger(this.getClass().getName()); <br>　public void processBusiness(){ <br>　　try { <br>　　　logger.info("start to processing..."); <br>　　　//business logic here. <br>　　　System.out.println(&#8220;here is business logic&#8221;); <br>　　　logger.info("end processing..."); <br>　　} catch (Exception e){ <br>　　　logger.info("exception happends..."); <br>　　　//exception handling <br>　　} <br>　} <br>} </td>
        </tr>
    </tbody>
</table>
<br>　　这里处理商业逻辑的代码和日志记录代码混合在一起，这给日后的维护带来一定的困难，并且也会造成大量的代码重复。完全相同的log代码将出现在系统的每一个BusinessObject中。 <br><br><span class=f14>　　按照AOP的思想，我们应该把日志记录代码分离出来。要将这些代码分离就涉及到一个问题，我们必须知道商业逻辑代码何时被调用，这样我们好插入日志记录代码。一般来说要截获一个方法，我们可以采用回调方法或者动态代理。动态代理一般要更加灵活一些，目前多数的AOP Framework也大都采用了动态代理来实现。这里我们也采用动态代理作为例子。 <br><br>　　JDK1.2以后提供了动态代理的支持，程序员通过实现java.lang.reflect.InvocationHandler接口提供一个执行处理器，然后通过java.lang.reflect.Proxy得到一个代理对象，通过这个代理对象来执行商业方法,在商业方法被调用的同时，执行处理器会被自动调用。 <br><br>　　有了JDK的这种支持，我们所要做的仅仅是提供一个日志处理器。 <br><br>
<table borderColor=#ffcc66 width="90%" align=center bgColor=#e6e4dd border=1>
    <tbody>
        <tr>
            <td>public class LogHandler implements InvocationHandler { <br><br>　private Logger logger ＝ Logger.getLogger(this.getClass().getName()); <br>　　private Object delegate; <br>　　public LogHandler(Object delegate){ <br>　　　this.delegate = delegate; <br>　　} <br><br>　public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { <br>　　Object o = null; <br>　　try { <br>　　　logger.info("method stats..." ＋ method); <br>　　　o = method.invoke(delegate,args); <br>　　　logger.info("method ends..." + method); <br>　　} catch (Exception e){ <br>　　　logger.info("Exception happends..."); <br>　　　//excetpion handling. <br>　　} <br>　　return o; <br>　} <br>} </td>
        </tr>
    </tbody>
</table>
<br>　　现在我们可以把BusinessObject里面的所有日志处理代码全部去掉了。 <br><br>
<table borderColor=#ffcc66 width="90%" align=center bgColor=#e6e4dd border=1>
    <tbody>
        <tr>
            <td>public class BusinessObject implements BusinessInterface { <br><br>　private Logger logger = Logger.getLogger(this.getClass().getName()); <br>　public void processBusiness(){ <br>　　//business processing <br>　　System.out.println(&#8220;here is business logic&#8221;); <br>　} <br>} </td>
        </tr>
    </tbody>
</table>
<br>　　客户端调用商业方法的代码如下：<br><br>
<table borderColor=#ffcc66 width="90%" align=center bgColor=#e6e4dd border=1>
    <tbody>
        <tr>
            <td>BusinessInterface businessImp = new BusinessObject(); <br><br>InvocationHandler handler = new LogHandler(businessImp); <br><br>BusinessInterface proxy = (BusinessInterface) Proxy.newProxyInstance( <br>　businessImp.getClass().getClassLoader(), <br>　businessImp.getClass().getInterfaces(), <br>　handler); <br><br>proxy.processBusiness(); </td>
        </tr>
    </tbody>
</table>
<br>　　程序输出如下： <br><br>
<table borderColor=#ffcc66 width="90%" align=center bgColor=#e6e4dd border=1>
    <tbody>
        <tr>
            <td>INFO: method stats... <br>here is business logic <br>INFO: method ends... </td>
        </tr>
    </tbody>
</table>
<br>　　至此我们的第一次小尝试算是完成了。可以看到，采用AOP之后，日志记录和业务逻辑代码完全分开了，以后要改变日志记录的话只需要修改日志记录处理器就行了，而业务对象本身（BusinessObject）无需做任何修改。并且这个日志记录不会造成重复代码了，所有的商业处理对象都可以重用这个日志处理器。 <br><br>　　当然在实际应用中，这个例子就显得太粗糙了。由于JDK的动态代理并没有直接支持一次注册多个InvocationHandler，那么我们对业务处理方法既要日志记录又要性能统计时，就需要自己做一些变通了。一般我们可以自己定义一个Handler接口，然后维护一个队列存放所有Handler, 当InvocationHandler被触发的时候我们依次调用自己的Handler。所幸的是目前几乎所有的AOP Framework都对这方面提供了很好的支持.这里推荐大家使用Spring。<br></span></div>
</font>
<img src ="http://www.blogjava.net/crazycy/aggbug/44169.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/crazycy/" target="_blank">crazycy</a> 2006-04-30 12:51 <a href="http://www.blogjava.net/crazycy/archive/2006/04/30/44169.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>我对设计模式的理解：Dynamic Proxy模式</title><link>http://www.blogjava.net/crazycy/archive/2006/04/29/44006.html</link><dc:creator>crazycy</dc:creator><author>crazycy</author><pubDate>Sat, 29 Apr 2006 06:12:00 GMT</pubDate><guid>http://www.blogjava.net/crazycy/archive/2006/04/29/44006.html</guid><wfw:comment>http://www.blogjava.net/crazycy/comments/44006.html</wfw:comment><comments>http://www.blogjava.net/crazycy/archive/2006/04/29/44006.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/crazycy/comments/commentRss/44006.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/crazycy/services/trackbacks/44006.html</trackback:ping><description><![CDATA[
		<p>代理模式（Proxy，这里侧重于Dynamic Proxy）可以理解成给一个对象提供一个代理对象，这个代理对象就是把原对象进行包装，使其与调用处理器相关联。<br />    因为代理对象和真实对象具有相同的接口，客户访问时，通过接口调用代理实例的方法，这个调用会被分发到该实例对应的处理器。处理器在把客户端调用传递给真实的对象之前或者之后，可执行某个操作，也可以选择不把这个调用传递给真实的对象。<br />   <br />   产生代理对象的过程就是将原对象和调用处理器邦定的过程，如下：<br />Proxy.newProxyInstance(真实对象实例.getClass().getClassLoader(), 真实对象实例.getClass().getInterfaces(), 与真实对象关联的调用处理器实例);<br /><br />   示例：<br />public interface AnInterface {<br /> void say();<br />}<br /><br /><br />public class AClass implements AnInterface {<br /> public AClass() {<br />  System.out.println("AClass:AClass()");<br /> }<br /> public void say() {<br />  System.out.println("AClass:say()");<br /> }<br />}<br /><br /><br />public class MyHandler implements InvocationHandler {<br /> private Object realObj;<br /> private MyHandler() {<br />  }<br /> public Object bind(Object realObj) {<br />    this.realObj = realObj;<br />    return Proxy.newProxyInstance(realObj.getClass().getClassLoader(),<br />    realObj.getClass().getInterfaces(), this);<br /> }<br /> public Object invoke(Object proxy, Method md, Object[] args) throws Throwable {<br />  Object obj = null;<br />  System.out.println("invoke()");<br />  obj = md.invoke(realObj, args);<br />  return obj;<br /> }<br />}<br /><br />public class Test {<br /> public static void main(String[] args) {<br />  MyHandler  handler = new MyHandler ();<br />  AnInterface proxyObj = handler.bind(new AClass());<br />  proxyObj.say();<br /> }<br />}</p>
<img src ="http://www.blogjava.net/crazycy/aggbug/44006.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/crazycy/" target="_blank">crazycy</a> 2006-04-29 14:12 <a href="http://www.blogjava.net/crazycy/archive/2006/04/29/44006.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>