﻿<?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-我的漫漫程序之旅-文章分类-设计模式</title><link>http://www.blogjava.net/supercrsky/category/31490.html</link><description>专注于JavaWeb开发</description><language>zh-cn</language><lastBuildDate>Tue, 27 May 2008 10:41:41 GMT</lastBuildDate><pubDate>Tue, 27 May 2008 10:41:41 GMT</pubDate><ttl>60</ttl><item><title>Flyweight模式 的学习 </title><link>http://www.blogjava.net/supercrsky/articles/203143.html</link><dc:creator>々上善若水々</dc:creator><author>々上善若水々</author><pubDate>Tue, 27 May 2008 02:42:00 GMT</pubDate><guid>http://www.blogjava.net/supercrsky/articles/203143.html</guid><wfw:comment>http://www.blogjava.net/supercrsky/comments/203143.html</wfw:comment><comments>http://www.blogjava.net/supercrsky/articles/203143.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/supercrsky/comments/commentRss/203143.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/supercrsky/services/trackbacks/203143.html</trackback:ping><description><![CDATA[<span style="font-size: 10pt; font-family: Verdana"><strong>一、Flyweight模式的意图：<br style="font-family: " />
</strong><br style="font-family: " />
缓存(共享)可以共同的对象、属性，避免创建大量的重复对象、内容。<br style="font-family: " />
<br style="font-family: " />
<strong>二、Flyweight模式的特点：<br style="font-family: " />
</strong><br style="font-family: " />
为重复或可共享的对象、属性设置一个缓冲，称为内部属性。这些内部属性一般情况下都是不可修改的，也就是在第一个对象、属性被创建后，就不会去修改了(否则就没意义了)。<br style="font-family: " />
<br style="font-family: " />
除了共享对象、属性之外，还有一些是基于应用环境，或是实时数据，这些无法共享的东西我们称为外部状态。<br style="font-family: " />
<br style="font-family: " />
在Flyweight模式应用中，通常修改的是外部状态属性，而内部状态属性一般都是用于参考或计算时引用。<br style="font-family: " />
<br style="font-family: " />
<strong>三、Flyweight模式的构成：<br />
<img height="292" alt="" src="http://www.blogjava.net/images/blogjava_net/pengpenglin/设计模式/Flyweight.JPG" width="571" border="0" /><br />
<br />
</strong>
<p><strong>Flyweight模式一般由几个部分组成：</strong></p>
<p><span style="color: red">&#183;Flyweight接口(抽象类) </span>：定义了一个可共享的元类<br />
<span style="color: red">&#183;Flyweight实现类</span>：实现了元类中的操作，而且可能会提供一个用于保存内部状态(共享属性)的空间<br />
<span style="color: red">&#183;Flyweight Factory</span>：创建Flyweight的工厂类，创建后将其保存到Flyweight Pool中<br />
<span style="color: red">&#183;Flyweight Pool</span>：缓冲Flyweight对象的池，通常包含在工厂类中<br />
<br />
<br />
<strong>四、Flyweight模式的简单实现<br />
<br />
1.Flyweight:<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"  alt="" /><span style="color: #0000ff">package</span><span style="color: #000000">&nbsp;com.pattern.flyweight2;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">abstract</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;Flyweight<br />
<img id="Codehighlighter1_65_102_Open_Image" onclick="this.style.display='none'; Codehighlighter1_65_102_Open_Text.style.display='none'; Codehighlighter1_65_102_Closed_Image.style.display='inline'; Codehighlighter1_65_102_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_65_102_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_65_102_Closed_Text.style.display='none'; Codehighlighter1_65_102_Open_Image.style.display='inline'; Codehighlighter1_65_102_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /></span><span id="Codehighlighter1_65_102_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_65_102_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">abstract</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;operation();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span></div>
<br />
2.ConcreateFlyweight:<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #0000ff">package</span><span style="color: #000000">&nbsp;com.pattern.flyweight2;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;ConcreateFlyweight&nbsp;</span><span style="color: #0000ff">extends</span><span style="color: #000000">&nbsp;Flyweight<br />
<img id="Codehighlighter1_83_250_Open_Image" onclick="this.style.display='none'; Codehighlighter1_83_250_Open_Text.style.display='none'; Codehighlighter1_83_250_Closed_Image.style.display='inline'; Codehighlighter1_83_250_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_83_250_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_83_250_Closed_Text.style.display='none'; Codehighlighter1_83_250_Open_Image.style.display='inline'; Codehighlighter1_83_250_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /></span><span id="Codehighlighter1_83_250_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_83_250_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;Object&nbsp;key;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;ConcreateFlyweight(Object&nbsp;key)<br />
<img id="Codehighlighter1_147_168_Open_Image" onclick="this.style.display='none'; Codehighlighter1_147_168_Open_Text.style.display='none'; Codehighlighter1_147_168_Closed_Image.style.display='inline'; Codehighlighter1_147_168_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_147_168_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_147_168_Closed_Text.style.display='none'; Codehighlighter1_147_168_Open_Image.style.display='inline'; Codehighlighter1_147_168_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_147_168_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_147_168_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.key&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;key;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&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;operation()<br />
<img id="Codehighlighter1_208_247_Open_Image" onclick="this.style.display='none'; Codehighlighter1_208_247_Open_Text.style.display='none'; Codehighlighter1_208_247_Closed_Image.style.display='inline'; Codehighlighter1_208_247_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_208_247_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_208_247_Closed_Text.style.display='none'; Codehighlighter1_208_247_Open_Image.style.display='inline'; Codehighlighter1_208_247_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_208_247_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_208_247_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">key:</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;key);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span></div>
</strong></span>3.FlyweightFactory:<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #0000ff">package</span><span style="color: #000000">&nbsp;com.pattern.flyweight2;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;java.util.Hashtable;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />@SuppressWarnings(</span><span style="color: #000000">"</span><span style="color: #000000">unchecked</span><span style="color: #000000">"</span><span style="color: #000000">)<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;FlyweightFactory<br />
<img id="Codehighlighter1_123_555_Open_Image" onclick="this.style.display='none'; Codehighlighter1_123_555_Open_Text.style.display='none'; Codehighlighter1_123_555_Closed_Image.style.display='inline'; Codehighlighter1_123_555_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_123_555_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_123_555_Closed_Text.style.display='none'; Codehighlighter1_123_555_Open_Image.style.display='inline'; Codehighlighter1_123_555_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /></span><span id="Codehighlighter1_123_555_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_123_555_Open_Text"><span style="color: #000000">{<br />
　<span style="color: #008000">//</span><span style="color: #008000">Flyweight&nbsp;pool</span><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;Hashtable&nbsp;flyweights&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Hashtable();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;Flyweight&nbsp;getFlyweight(Object&nbsp;key)<br />
<img id="Codehighlighter1_219_485_Open_Image" onclick="this.style.display='none'; Codehighlighter1_219_485_Open_Text.style.display='none'; Codehighlighter1_219_485_Closed_Image.style.display='inline'; Codehighlighter1_219_485_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_219_485_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_219_485_Closed_Text.style.display='none'; Codehighlighter1_219_485_Open_Image.style.display='inline'; Codehighlighter1_219_485_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_219_485_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_219_485_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Flyweight&nbsp;flyweight&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(flyweights.containsKey(key))<br />
<img id="Codehighlighter1_287_339_Open_Image" onclick="this.style.display='none'; Codehighlighter1_287_339_Open_Text.style.display='none'; Codehighlighter1_287_339_Closed_Image.style.display='inline'; Codehighlighter1_287_339_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_287_339_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_287_339_Closed_Text.style.display='none'; Codehighlighter1_287_339_Open_Image.style.display='inline'; Codehighlighter1_287_339_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_287_339_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_287_339_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;flyweight&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(Flyweight)&nbsp;flyweights.get(key);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(</span><span style="color: #000000">!</span><span style="color: #000000">flyweights.containsKey(key))<br />
<img id="Codehighlighter1_379_462_Open_Image" onclick="this.style.display='none'; Codehighlighter1_379_462_Open_Text.style.display='none'; Codehighlighter1_379_462_Closed_Image.style.display='inline'; Codehighlighter1_379_462_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_379_462_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_379_462_Closed_Text.style.display='none'; Codehighlighter1_379_462_Open_Image.style.display='inline'; Codehighlighter1_379_462_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_379_462_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_379_462_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;flyweight&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;ConcreateFlyweight(key);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;flyweights.put(key,&nbsp;flyweight);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;flyweight;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;getFlyweightsSize()<br />
<img id="Codehighlighter1_522_553_Open_Image" onclick="this.style.display='none'; Codehighlighter1_522_553_Open_Text.style.display='none'; Codehighlighter1_522_553_Closed_Image.style.display='inline'; Codehighlighter1_522_553_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_522_553_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_522_553_Closed_Text.style.display='none'; Codehighlighter1_522_553_Open_Image.style.display='inline'; Codehighlighter1_522_553_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_522_553_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_522_553_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;flyweights.size();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span></div>
<br />
4.测试类:<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #0000ff">package</span><span style="color: #000000">&nbsp;com.pattern.flyweight2;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;Client<br />
<img id="Codehighlighter1_53_651_Open_Image" onclick="this.style.display='none'; Codehighlighter1_53_651_Open_Text.style.display='none'; Codehighlighter1_53_651_Closed_Image.style.display='inline'; Codehighlighter1_53_651_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_53_651_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_53_651_Closed_Text.style.display='none'; Codehighlighter1_53_651_Open_Image.style.display='inline'; Codehighlighter1_53_651_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /></span><span id="Codehighlighter1_53_651_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_53_651_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;Flyweight&nbsp;f1&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;Flyweight&nbsp;f2&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;Flyweight&nbsp;f3&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">private</span><span style="color: #000000">&nbsp;Flyweight&nbsp;f4&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;FlyweightFactory&nbsp;factory&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;FlyweightFactory();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;Client()<br />
<img id="Codehighlighter1_246_403_Open_Image" onclick="this.style.display='none'; Codehighlighter1_246_403_Open_Text.style.display='none'; Codehighlighter1_246_403_Closed_Image.style.display='inline'; Codehighlighter1_246_403_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_246_403_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_246_403_Closed_Text.style.display='none'; Codehighlighter1_246_403_Open_Image.style.display='inline'; Codehighlighter1_246_403_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_246_403_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_246_403_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f1&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;factory.getFlyweight(</span><span style="color: #000000">"</span><span style="color: #000000">baidu</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f2&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;factory.getFlyweight(</span><span style="color: #000000">"</span><span style="color: #000000">google</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f3&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;factory.getFlyweight(</span><span style="color: #000000">"</span><span style="color: #000000">baidu</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f4&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;factory.getFlyweight(</span><span style="color: #000000">"</span><span style="color: #000000">google</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&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;show()<br />
<img id="Codehighlighter1_427_553_Open_Image" onclick="this.style.display='none'; Codehighlighter1_427_553_Open_Text.style.display='none'; Codehighlighter1_427_553_Closed_Image.style.display='inline'; Codehighlighter1_427_553_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_427_553_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_427_553_Closed_Text.style.display='none'; Codehighlighter1_427_553_Open_Image.style.display='inline'; Codehighlighter1_427_553_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_427_553_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_427_553_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f1.operation();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f2.operation();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f3.operation();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f4.operation();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(factory.getFlyweightsSize());<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&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)<br />
<img id="Codehighlighter1_597_649_Open_Image" onclick="this.style.display='none'; Codehighlighter1_597_649_Open_Text.style.display='none'; Codehighlighter1_597_649_Closed_Image.style.display='inline'; Codehighlighter1_597_649_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_597_649_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_597_649_Closed_Text.style.display='none'; Codehighlighter1_597_649_Open_Image.style.display='inline'; Codehighlighter1_597_649_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_597_649_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_597_649_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Client&nbsp;client&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Client();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;client.show();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span></div>
也就是在缓冲这一点上，体现了Flyweight模式的精髓。
<img src ="http://www.blogjava.net/supercrsky/aggbug/203143.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/supercrsky/" target="_blank">々上善若水々</a> 2008-05-27 10:42 <a href="http://www.blogjava.net/supercrsky/articles/203143.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java设计模式之Facade模式</title><link>http://www.blogjava.net/supercrsky/articles/202854.html</link><dc:creator>々上善若水々</dc:creator><author>々上善若水々</author><pubDate>Mon, 26 May 2008 03:01:00 GMT</pubDate><guid>http://www.blogjava.net/supercrsky/articles/202854.html</guid><wfw:comment>http://www.blogjava.net/supercrsky/comments/202854.html</wfw:comment><comments>http://www.blogjava.net/supercrsky/articles/202854.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/supercrsky/comments/commentRss/202854.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/supercrsky/services/trackbacks/202854.html</trackback:ping><description><![CDATA[GOF<span style="font-family: 宋体">《设计模式》一书对</span>Facade<span style="font-family: 宋体">模式是这样描述的</span>:
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-family: 宋体">为子系统中的一组接口提供一个统一接口。</span>Facade<span style="font-family: 宋体">模式定义了一个更高层的接口，使子系统更加容易使用。</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-family: 宋体">大致意思是说：使用一种比原有方式更简单的办法与系统交互。例如，我们把一个很文件的文件，放在了第二抽屉里，而第二个抽屉的钥匙放在了第一个抽屉里，我们要想取出这个文件，第一步肯定要拿到第一个抽屉的钥匙，然后打开它再拿出第二个抽屉的钥匙，最后打开第二个抽屉取出文件。</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-family: 宋体">我就上面说的那个情形写一下实现代码，首先我们要实现二个子系统,呵呵，把抽屉比喻成系统，有点夸张了（</span><span style="background: silver; color: black; font-family: 'Courier New'">DrawerOne</span><span style="font-family: 宋体">、</span><span style="color: black; font-family: 'Courier New'">DrawerTwo</span><span style="font-family: 宋体">）：</span></p>
<p style="text-align: left" align="left"><strong><span style="color: #7f0055; font-family: 'Courier New'">class</span></strong><span style="color: black; font-family: 'Courier New'"> DrawerOne {</span></p>
<p style="text-align: left" align="left"><span style="color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp; </span><strong><span style="color: #7f0055; font-family: 'Courier New'">public </span></strong><strong><span style="color: #7f0055; font-family: 'Courier New'">void</span></strong><span style="color: black; font-family: 'Courier New'"> open(){</span></p>
<p style="text-align: left" align="left"><span style="color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.</span><em><span style="color: #0000c0; font-family: 'Courier New'">out</span></em><span style="color: black; font-family: 'Courier New'">.println(</span><span style="color: #2a00ff; font-family: 'Courier New'">"</span><span style="color: #2a00ff; font-family: 宋体">第一个抽屉被打开了</span><span style="color: #2a00ff; font-family: 'Courier New'">"</span><span style="color: black; font-family: 'Courier New'">);</span></p>
<p style="text-align: left" align="left"><span style="color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getKey();</span></p>
<p style="text-align: left" align="left"><span style="color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp; }</span></p>
<p style="text-align: left" align="left"><span style="color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp; </span><strong><span style="color: #7f0055; font-family: 'Courier New'">public </span></strong><strong><span style="color: #7f0055; font-family: 'Courier New'">void</span></strong><span style="color: black; font-family: 'Courier New'"> getKey(){</span></p>
<p style="text-align: left" align="left"><span style="color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.</span><em><span style="color: #0000c0; font-family: 'Courier New'">out</span></em><span style="color: black; font-family: 'Courier New'">.println(</span><span style="color: #2a00ff; font-family: 'Courier New'">"</span><span style="color: #2a00ff; font-family: 宋体">得到第二个抽屉的钥匙</span><span style="color: #2a00ff; font-family: 'Courier New'">"</span><span style="color: black; font-family: 'Courier New'">);</span></p>
<p style="text-align: left" align="left"><span style="color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp; }</span></p>
<p style="text-align: left" align="left"><span style="color: black; font-family: 'Courier New'">}</span></p>
<p style="text-align: left" align="left"><strong><span style="color: #7f0055; font-family: 'Courier New'">class</span></strong><span style="color: black; font-family: 'Courier New'"> DrawerTwo{</span></p>
<p style="text-align: left" align="left"><span style="color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp; </span><strong><span style="color: #7f0055; font-family: 'Courier New'">public </span></strong><strong><span style="color: #7f0055; font-family: 'Courier New'">void</span></strong><span style="color: black; font-family: 'Courier New'"> open(){</span></p>
<p style="text-align: left" align="left"><span style="color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.</span><em><span style="color: #0000c0; font-family: 'Courier New'">out</span></em><span style="color: black; font-family: 'Courier New'">.println(</span><span style="color: #2a00ff; font-family: 'Courier New'">"</span><span style="color: #2a00ff; font-family: 宋体">第二个抽屉被打开了</span><span style="color: #2a00ff; font-family: 'Courier New'">"</span><span style="color: black; font-family: 'Courier New'">);</span></p>
<p style="text-align: left" align="left"><span style="color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getFile();</span></p>
<p style="text-align: left" align="left"><span style="color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp; }</span></p>
<p style="text-align: left" align="left"><span style="color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp; </span><strong><span style="color: #7f0055; font-family: 'Courier New'">public </span></strong><strong><span style="color: #7f0055; font-family: 'Courier New'">void</span></strong><span style="color: black; font-family: 'Courier New'"> getFile(){</span></p>
<p style="text-align: left" align="left"><span style="color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.</span><em><span style="color: #0000c0; font-family: 'Courier New'">out</span></em><span style="color: black; font-family: 'Courier New'">.println(</span><span style="color: #2a00ff; font-family: 'Courier New'">"</span><span style="color: #2a00ff; font-family: 宋体">得到这个重要文件</span><span style="color: #2a00ff; font-family: 'Courier New'">"</span><span style="color: black; font-family: 'Courier New'">);</span></p>
<p style="text-align: left" align="left"><span style="color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp; }</span></p>
<p style="text-align: left" align="left"><span style="color: black; font-family: 'Courier New'">}</span></p>
<p style="text-align: left" align="left"><strong><span style="color: #7f0055; font-family: 'Courier New'">public </span></strong><strong><span style="color: #7f0055; font-family: 'Courier New'">class</span></strong><span style="color: black; font-family: 'Courier New'"> Client{</span></p>
<p style="text-align: left" align="left"><span style="color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp; </span><strong><span style="color: #7f0055; font-family: 'Courier New'">public </span></strong><strong><span style="color: #7f0055; font-family: 'Courier New'">static </span></strong><strong><span style="color: #7f0055; font-family: 'Courier New'">void</span></strong><span style="color: black; font-family: 'Courier New'"> main(String []args){</span></p>
<p style="text-align: left" align="left"><span style="color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DrawerOne darwerOne=</span><strong><span style="color: #7f0055; font-family: 'Courier New'">new</span></strong><span style="color: black; font-family: 'Courier New'"> DrawerOne();</span></p>
<p style="text-align: left" align="left"><span style="color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DrawerTwo darwerTwo=</span><strong><span style="color: #7f0055; font-family: 'Courier New'">new</span></strong><span style="color: black; font-family: 'Courier New'"> DrawerTwo();</span></p>
<p style="text-align: left" align="left"><span style="color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; darwerOne.open();</span></p>
<p style="text-align: left" align="left"><span style="color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; darwerTwo.open();</span></p>
<p style="text-align: left" align="left"><span style="color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp; }</span></p>
<p><span style="color: black; font-family: 'Courier New'">}</span></p>
<p style="text-indent: 21pt"><span style="color: black; font-family: 宋体">由于没有使用</span><span style="color: black; font-family: 'Courier New'">Fa&#231;ade</span><span style="color: black; font-family: 宋体">模式，可以看到要想得到这个文件要首先打开第一个抽屉，然后再打开第二个抽屉，在我们实际所开发的系统中，有时候客户要实现某一操作，并不需要知道实现这一操作的详细步骤，而是简单地点击某一个按钮就可以得到自己想要的结果。下面对上面的代码使用</span><span style="color: black; font-family: 'Courier New'">Fa&#231;ade</span><span style="color: black; font-family: 宋体">模式进行改进，建立一个</span><span style="color: black; font-family: 'Courier New'">FacadeDrawer</span><span style="color: black; font-family: 宋体">类：</span></p>
<p style="text-align: left" align="left"><strong><span style="color: #7f0055; font-family: 'Courier New'">class</span></strong><span style="color: black; font-family: 'Courier New'"> DrawerFacade{</span></p>
<p style="text-align: left" align="left"><span style="color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp; DrawerOne </span><span style="color: #0000c0; font-family: 'Courier New'">darwerOne</span><span style="color: black; font-family: 'Courier New'">=</span><strong><span style="color: #7f0055; font-family: 'Courier New'">new</span></strong><span style="color: black; font-family: 'Courier New'"> DrawerOne();</span></p>
<p style="text-align: left" align="left"><span style="color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp; DrawerTwo </span><span style="color: #0000c0; font-family: 'Courier New'">darwerTwo</span><span style="color: black; font-family: 'Courier New'">=</span><strong><span style="color: #7f0055; font-family: 'Courier New'">new</span></strong><span style="color: black; font-family: 'Courier New'"> DrawerTwo();</span></p>
<p style="text-align: left" align="left"><span style="color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp; </span><strong><span style="color: #7f0055; font-family: 'Courier New'">public </span></strong><strong><span style="color: #7f0055; font-family: 'Courier New'">void</span></strong><span style="color: black; font-family: 'Courier New'"> open(){</span></p>
<p style="text-align: left" align="left"><span style="color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #0000c0; font-family: 'Courier New'">darwerOne</span><span style="color: black; font-family: 'Courier New'">.open();</span></p>
<p style="text-align: left" align="left"><span style="color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color: #0000c0; font-family: 'Courier New'">darwerTwo</span><span style="color: black; font-family: 'Courier New'">.open();</span></p>
<p style="text-align: left" align="left"><span style="color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp; }</span></p>
<p><span style="color: black; font-family: 'Courier New'">}</span></p>
<p><span style="color: black; font-family: 宋体">修改</span><span style="color: black; font-family: 'Courier New'">Client</span><span style="color: black; font-family: 宋体">类：</span></p>
<p style="text-align: left" align="left"><strong><span style="color: #7f0055; font-family: 'Courier New'">public </span></strong><strong><span style="color: #7f0055; font-family: 'Courier New'">class</span></strong><span style="color: black; font-family: 'Courier New'"> DrawerClient{</span></p>
<p style="text-align: left" align="left"><span style="color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp; </span><strong><span style="color: #7f0055; font-family: 'Courier New'">public </span></strong><strong><span style="color: #7f0055; font-family: 'Courier New'">static </span></strong><strong><span style="color: #7f0055; font-family: 'Courier New'">void</span></strong><span style="color: black; font-family: 'Courier New'"> main(String []args){</span></p>
<p style="text-align: left" align="left"><span style="color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DrawerFacade drawer=</span><strong><span style="color: #7f0055; font-family: 'Courier New'">new</span></strong><span style="color: black; font-family: 'Courier New'"> DrawerFacade();</span></p>
<p style="text-align: left" align="left"><span style="color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drawer.open();</span></p>
<p style="text-align: left" align="left"><span style="color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp; }</span></p>
<p><span style="color: black; font-family: 'Courier New'">}</span></p>
<p><span style="color: black; font-family: 宋体">输出结果如下：</span></p>
<p style="text-align: left" align="left"><span style="color: black; font-family: 宋体">第一个抽屉被打开了</span></p>
<p style="text-align: left" align="left"><span style="color: black; font-family: 宋体">得到第二个抽屉的钥匙</span></p>
<p style="text-align: left" align="left"><span style="color: black; font-family: 宋体">第二个抽屉被打开了</span></p>
<p><span style="color: black; font-family: 宋体">得到这个重要文件</span></p>
<p style="text-indent: 21pt"><span style="color: black; font-family: 宋体">正如上面所说，客户端</span><span style="color: black; font-family: 'Courier New'">client</span><span style="color: black; font-family: 宋体">，它并不需要关心子系统，而是关心</span><span style="color: black; font-family: 'Courier New'">DrawerFacade</span><span style="color: black; font-family: 宋体">所留下来的和外部交互的接口，而子系统在</span><span style="color: black; font-family: 'Courier New'">DrawerFacade</span><span style="color: black; font-family: 宋体">的聚合。</span></p>
<p style="text-indent: 21pt"><span style="color: black; font-family: 宋体">以上只是个人拙见，哪里有不正确的地方，希望大家多多批评指正。</span><span style="color: black; font-family: 'Courier New'">^_^</span></p>
<p><span style="color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp; Facade</span><span style="color: black; font-family: 宋体">模式主要适用于以下几种情况</span><span style="color: black; font-family: 'Courier New'">:</span></p>
<p style="margin-left: 18pt; text-indent: -18pt; tab-stops: list 18.0pt"><span style="color: black; font-family: 'Courier New'">1)<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp; </span></span><span style="color: black; font-family: 宋体">不需要使用一个复杂系统的所有功能，而且可以创建一个新的类，包含访问系统的所有规则。如果只需要使用系统的部分功能，那么你为新类所创建的</span><span style="color: black; font-family: 'Courier New'">API</span><span style="color: black; font-family: 宋体">将比原系统的</span><span style="color: black; font-family: 'Courier New'">API</span><span style="color: black; font-family: 宋体">简单的多。</span></p>
<p style="margin-left: 18pt; text-indent: -18pt; tab-stops: list 18.0pt"><span style="color: black; font-family: 'Courier New'">2)<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp; </span></span><span style="color: black; font-family: 宋体">希望封装或者隐藏系统原系统。</span></p>
<p style="margin-left: 18pt; text-indent: -18pt; tab-stops: list 18.0pt"><span style="color: black; font-family: 'Courier New'">3)<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp; </span></span><span style="color: black; font-family: 宋体">希望使用原系统的功能，而且还希望增加一些新的功能。</span></p>
<p style="margin-left: 18pt; text-indent: -18pt; tab-stops: list 18.0pt"><span style="color: black; font-family: 'Courier New'">4)<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp; </span></span><span style="color: black; font-family: 宋体">编写新类的成本小于所有人学会使用或者未来维护原系统上所需的成本。</span></p>
<img src ="http://www.blogjava.net/supercrsky/aggbug/202854.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/supercrsky/" target="_blank">々上善若水々</a> 2008-05-26 11:01 <a href="http://www.blogjava.net/supercrsky/articles/202854.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java设计模式之Bridge</title><link>http://www.blogjava.net/supercrsky/articles/202848.html</link><dc:creator>々上善若水々</dc:creator><author>々上善若水々</author><pubDate>Mon, 26 May 2008 02:38:00 GMT</pubDate><guid>http://www.blogjava.net/supercrsky/articles/202848.html</guid><wfw:comment>http://www.blogjava.net/supercrsky/comments/202848.html</wfw:comment><comments>http://www.blogjava.net/supercrsky/articles/202848.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/supercrsky/comments/commentRss/202848.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/supercrsky/services/trackbacks/202848.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;Bridge定义 :将抽象和行为划分开来,各自独立,但能动态的结合.为什么使用?通常,当一个抽象类或接口有多个具体实现(concrete subclass),这些concrete之间关系可能有以下两种:1. 这多个具体实现之间恰好是并列的,如前面举例,打桩,有两个concrete class:方形桩和圆形桩;这两个形状上的桩是并列的,没有概念上的重复,那么我们只...&nbsp;&nbsp;<a href='http://www.blogjava.net/supercrsky/articles/202848.html'>阅读全文</a><img src ="http://www.blogjava.net/supercrsky/aggbug/202848.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/supercrsky/" target="_blank">々上善若水々</a> 2008-05-26 10:38 <a href="http://www.blogjava.net/supercrsky/articles/202848.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java Prototype模式的学习(原型模式) </title><link>http://www.blogjava.net/supercrsky/articles/202833.html</link><dc:creator>々上善若水々</dc:creator><author>々上善若水々</author><pubDate>Mon, 26 May 2008 01:39:00 GMT</pubDate><guid>http://www.blogjava.net/supercrsky/articles/202833.html</guid><wfw:comment>http://www.blogjava.net/supercrsky/comments/202833.html</wfw:comment><comments>http://www.blogjava.net/supercrsky/articles/202833.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/supercrsky/comments/commentRss/202833.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/supercrsky/services/trackbacks/202833.html</trackback:ping><description><![CDATA[&nbsp;原型模式定义: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.
<p>&nbsp;&nbsp;&nbsp; Prototype模式允许一个对象再创建另外一个可定制的对象，根本无需知道任何如何创建的细节,工作原理是:通过将一个原型对象传给那个要发动创建的对象，这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建。</p>
<p><em><strong>如何使用?</strong></em> 因为Java中的提供clone()方法来实现对象的克隆,所以Prototype模式实现一下子变得很简单.</p>
<p>以勺子为例：</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"  alt="" /><span style="color: #0000ff">package</span><span style="color: #000000">&nbsp;com.pattern.prototype;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img id="Codehighlighter1_32_93_Open_Image" onclick="this.style.display='none'; Codehighlighter1_32_93_Open_Text.style.display='none'; Codehighlighter1_32_93_Closed_Image.style.display='inline'; Codehighlighter1_32_93_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_32_93_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_32_93_Closed_Text.style.display='none'; Codehighlighter1_32_93_Open_Image.style.display='inline'; Codehighlighter1_32_93_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /></span><span id="Codehighlighter1_32_93_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">/**&nbsp;*/</span><span id="Codehighlighter1_32_93_Open_Text"><span style="color: #008000">/**</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;*&nbsp;原型类(以汤匙为例)&nbsp;,注意要实现Cloneable接口<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;*&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;*&nbsp;</span><span style="color: #808080">@author</span><span style="color: #008000">&nbsp;zdw<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;*&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />&nbsp;</span><span style="color: #008000">*/</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">abstract</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;AbstractSpoon&nbsp;</span><span style="color: #0000ff">implements</span><span style="color: #000000">&nbsp;Cloneable<br />
<img id="Codehighlighter1_152_524_Open_Image" onclick="this.style.display='none'; Codehighlighter1_152_524_Open_Text.style.display='none'; Codehighlighter1_152_524_Closed_Image.style.display='inline'; Codehighlighter1_152_524_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_152_524_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_152_524_Closed_Text.style.display='none'; Codehighlighter1_152_524_Open_Image.style.display='inline'; Codehighlighter1_152_524_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /></span><span id="Codehighlighter1_152_524_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_152_524_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;String&nbsp;spoonName;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;String&nbsp;getSpoonName()<br />
<img id="Codehighlighter1_212_240_Open_Image" onclick="this.style.display='none'; Codehighlighter1_212_240_Open_Text.style.display='none'; Codehighlighter1_212_240_Closed_Image.style.display='inline'; Codehighlighter1_212_240_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_212_240_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_212_240_Closed_Text.style.display='none'; Codehighlighter1_212_240_Open_Image.style.display='inline'; Codehighlighter1_212_240_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_212_240_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_212_240_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.spoonName;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&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;setSpoonName(String&nbsp;spoonName)<br />
<img id="Codehighlighter1_288_321_Open_Image" onclick="this.style.display='none'; Codehighlighter1_288_321_Open_Text.style.display='none'; Codehighlighter1_288_321_Closed_Image.style.display='inline'; Codehighlighter1_288_321_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_288_321_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_288_321_Closed_Text.style.display='none'; Codehighlighter1_288_321_Open_Image.style.display='inline'; Codehighlighter1_288_321_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_288_321_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_288_321_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.spoonName&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;spoonName;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img id="Codehighlighter1_325_348_Open_Image" onclick="this.style.display='none'; Codehighlighter1_325_348_Open_Text.style.display='none'; Codehighlighter1_325_348_Closed_Image.style.display='inline'; Codehighlighter1_325_348_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_325_348_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_325_348_Closed_Text.style.display='none'; Codehighlighter1_325_348_Open_Image.style.display='inline'; Codehighlighter1_325_348_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_325_348_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">/**&nbsp;*/</span><span id="Codehighlighter1_325_348_Open_Text"><span style="color: #008000">/**</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;重写clone()方法<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">*/</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;Object&nbsp;clone()<br />
<img id="Codehighlighter1_385_522_Open_Image" onclick="this.style.display='none'; Codehighlighter1_385_522_Open_Text.style.display='none'; Codehighlighter1_385_522_Closed_Image.style.display='inline'; Codehighlighter1_385_522_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_385_522_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_385_522_Closed_Text.style.display='none'; Codehighlighter1_385_522_Open_Image.style.display='inline'; Codehighlighter1_385_522_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_385_522_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_385_522_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">try</span><span style="color: #000000"><br />
<img id="Codehighlighter1_395_424_Open_Image" onclick="this.style.display='none'; Codehighlighter1_395_424_Open_Text.style.display='none'; Codehighlighter1_395_424_Closed_Image.style.display='inline'; Codehighlighter1_395_424_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_395_424_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_395_424_Closed_Text.style.display='none'; Codehighlighter1_395_424_Open_Image.style.display='inline'; Codehighlighter1_395_424_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_395_424_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_395_424_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">super</span><span style="color: #000000">.clone();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">catch</span><span style="color: #000000">&nbsp;(CloneNotSupportedException&nbsp;e)<br />
<img id="Codehighlighter1_465_504_Open_Image" onclick="this.style.display='none'; Codehighlighter1_465_504_Open_Text.style.display='none'; Codehighlighter1_465_504_Closed_Image.style.display='inline'; Codehighlighter1_465_504_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_465_504_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_465_504_Closed_Text.style.display='none'; Codehighlighter1_465_504_Open_Image.style.display='inline'; Codehighlighter1_465_504_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_465_504_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_465_504_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">此对象不支持复制</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">null</span><span style="color: #000000">;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span></div>
<br />
对原型的具体实现:<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #0000ff">package</span><span style="color: #000000">&nbsp;com.pattern.prototype;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img id="Codehighlighter1_32_72_Open_Image" onclick="this.style.display='none'; Codehighlighter1_32_72_Open_Text.style.display='none'; Codehighlighter1_32_72_Closed_Image.style.display='inline'; Codehighlighter1_32_72_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_32_72_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_32_72_Closed_Text.style.display='none'; Codehighlighter1_32_72_Open_Image.style.display='inline'; Codehighlighter1_32_72_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /></span><span id="Codehighlighter1_32_72_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">/**&nbsp;*/</span><span id="Codehighlighter1_32_72_Open_Text"><span style="color: #008000">/**</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;*&nbsp;给原型对象赋值<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;*&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;*&nbsp;</span><span style="color: #808080">@author</span><span style="color: #008000">&nbsp;zdw<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;*&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />&nbsp;</span><span style="color: #008000">*/</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;SoupSpoon&nbsp;</span><span style="color: #0000ff">extends</span><span style="color: #000000">&nbsp;AbstractSpoon<br />
<img id="Codehighlighter1_119_177_Open_Image" onclick="this.style.display='none'; Codehighlighter1_119_177_Open_Text.style.display='none'; Codehighlighter1_119_177_Closed_Image.style.display='inline'; Codehighlighter1_119_177_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_119_177_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_119_177_Closed_Text.style.display='none'; Codehighlighter1_119_177_Open_Image.style.display='inline'; Codehighlighter1_119_177_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /></span><span id="Codehighlighter1_119_177_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_119_177_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;SoupSpoon()<br />
<img id="Codehighlighter1_142_175_Open_Image" onclick="this.style.display='none'; Codehighlighter1_142_175_Open_Text.style.display='none'; Codehighlighter1_142_175_Closed_Image.style.display='inline'; Codehighlighter1_142_175_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_142_175_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_142_175_Closed_Text.style.display='none'; Codehighlighter1_142_175_Open_Image.style.display='inline'; Codehighlighter1_142_175_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_142_175_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_142_175_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setSpoonName(</span><span style="color: #000000">"</span><span style="color: #000000">chinaDrong</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span></div>
<br />
测试类:<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #0000ff">package</span><span style="color: #000000">&nbsp;com.pattern.prototype;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img id="Codehighlighter1_32_145_Open_Image" onclick="this.style.display='none'; Codehighlighter1_32_145_Open_Text.style.display='none'; Codehighlighter1_32_145_Closed_Image.style.display='inline'; Codehighlighter1_32_145_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_32_145_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_32_145_Closed_Text.style.display='none'; Codehighlighter1_32_145_Open_Image.style.display='inline'; Codehighlighter1_32_145_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /></span><span id="Codehighlighter1_32_145_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">/**&nbsp;*/</span><span id="Codehighlighter1_32_145_Open_Text"><span style="color: #008000">/**</span><span style="color: #008000">*****************************************************************************<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;*&nbsp;测试类<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;*&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;*&nbsp;</span><span style="color: #808080">@author</span><span style="color: #008000">&nbsp;zdw<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;*&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />&nbsp;</span><span style="color: #008000">*/</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;Client<br />
<img id="Codehighlighter1_167_436_Open_Image" onclick="this.style.display='none'; Codehighlighter1_167_436_Open_Text.style.display='none'; Codehighlighter1_167_436_Closed_Image.style.display='inline'; Codehighlighter1_167_436_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_167_436_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_167_436_Closed_Text.style.display='none'; Codehighlighter1_167_436_Open_Image.style.display='inline'; Codehighlighter1_167_436_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /></span><span id="Codehighlighter1_167_436_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_167_436_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&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)<br />
<img id="Codehighlighter1_210_434_Open_Image" onclick="this.style.display='none'; Codehighlighter1_210_434_Open_Text.style.display='none'; Codehighlighter1_210_434_Closed_Image.style.display='inline'; Codehighlighter1_210_434_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_210_434_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_210_434_Closed_Text.style.display='none'; Codehighlighter1_210_434_Open_Image.style.display='inline'; Codehighlighter1_210_434_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_210_434_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_210_434_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AbstractSpoon&nbsp;spoon&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;SoupSpoon();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(spoon.getSpoonName());<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;通过对象的clone()方法,即可获得对象的一个copy.</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AbstractSpoon&nbsp;spoon2&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(AbstractSpoon)&nbsp;spoon.clone();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(spoon2.getSpoonName());<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span></div>
<br />
<p>当然也可以结合工厂模式来创建AbstractSpoon实例。</p>
<p>在Java中Prototype模式变成clone()方法的使用，由于Java的纯洁的面向对象特性，使得在Java中使用设计模式变得很自然，两者已经几乎是浑然一体了。这反映在很多模式上，如Interator遍历模式。</p>
<img src ="http://www.blogjava.net/supercrsky/aggbug/202833.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/supercrsky/" target="_blank">々上善若水々</a> 2008-05-26 09:39 <a href="http://www.blogjava.net/supercrsky/articles/202833.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>装饰者模式(Decorator)浅谈与剖析</title><link>http://www.blogjava.net/supercrsky/articles/202691.html</link><dc:creator>々上善若水々</dc:creator><author>々上善若水々</author><pubDate>Sun, 25 May 2008 02:06:00 GMT</pubDate><guid>http://www.blogjava.net/supercrsky/articles/202691.html</guid><wfw:comment>http://www.blogjava.net/supercrsky/comments/202691.html</wfw:comment><comments>http://www.blogjava.net/supercrsky/articles/202691.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/supercrsky/comments/commentRss/202691.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/supercrsky/services/trackbacks/202691.html</trackback:ping><description><![CDATA[Central Perk<span style="font-family: 宋体">的名字因为《老友记》而享誉全球，他们的分店几乎开遍世界各地。他们发展的实在是太快了，所以他们此时正在急于实现一套由计算机管理的自动化记账系统。在第一次研究了他们的需求以后，开发者设计了如下图的类结构：</span>
<p style="margin: 0cm 0cm 0pt"><span><span>
<div align="center"><img height="389" alt="" src="http://www.cnblogs.com/images/cnblogs_com/justinw/decorator1.jpg" width="554" border="0" /></div>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-size: 9pt; color: teal; font-family: 新宋体">Beverage</span><span style="font-family: 宋体">是所有饮料的基类；</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">cost()</span><span style="font-family: 宋体">是抽象方法，所有子类都需要定义它们自己的</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">cost()</span><span style="font-family: 宋体">实现来返回特定饮料的价钱；</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">description</span><span style="font-family: 宋体">变量也是在子类里赋值的，表示特定饮料的描述信息，</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">getDescription()</span><span style="font-family: 宋体">方法可以返回这个描述；</span>&nbsp;&nbsp;
<p style="margin: 0cm 0cm 0pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-family: 宋体">除了咖啡以为，</span>Central Perk<span style="font-family: 宋体">还提供丰富的调味品，比如：炼乳、巧克力、砂糖、牛奶等，而且这些调味品也是要单独按份收费的，所以调味品也是订单系统中重要的一部分。</span></p>
<p style="margin: 0cm 0cm 0pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-family: 宋体">于是，考虑到调味品的管理，开发者又有了下面这样的类结构：</span></p>
<p style="margin: 0cm 0cm 0pt"><span><span>
<div align="center"><img height="478" alt="" src="http://www.cnblogs.com/images/cnblogs_com/justinw/decorator2.jpg" width="553" border="0" /></div>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">看了上面的类图，你一定有话要说！是的！这简直是太恐怖了，好像是整个类图都要爆炸了一样，而且以后随便增加一种调味品，继承于</span>Beverage<span style="font-family: 宋体">的子类还会翻倍！</span>(<span style="font-family: 宋体">因为理论上可能的咖啡种类数</span> = <span style="font-family: 宋体">咖啡类别数&#215;调味品类别数</span>) <span style="font-family: 宋体">我的神啊！全球变暖后连咖啡都&#8220;沸腾&#8221;了吗？还是我们在研制某种自杀式炸弹装置！</span><span style="font-size: 9pt; color: red">(</span><span style="font-size: 9pt; color: red; font-family: 宋体">方便携带，不宜察觉，居家旅游必备，只要将几种调味品混合到一起，就能产生惊人的爆炸力！不错啊！</span><span style="font-size: 9pt; color: red; font-family: Wingdings">J</span><span style="font-size: 9pt; color: red">)</span>&nbsp;&nbsp;
<p style="margin: 0cm 0cm 0pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-family: 宋体">上面的情况绝对是不能容忍的，于是开发者们经过讨论，又提出了下面的设计方案件：</span></p>
<p style="margin: 0cm 0cm 0pt"><span><span>
<div align="center"><img height="329" alt="" src="http://www.cnblogs.com/images/cnblogs_com/justinw/decorator3.jpg" width="554" border="0" /></div>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">如图所示，这是改进后的</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">Beverage</span><span style="font-family: 宋体">基类。首先在基类里增加了表示是否包含特定调味品的布尔变量，如</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">milk</span>, <span style="font-size: 9pt; color: teal; font-family: 新宋体">soy</span><span style="font-family: 宋体">等，然后提供了一些</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">has(get)</span><span style="font-family: 宋体">和</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">set</span><span style="font-family: 宋体">方法来设置这些布尔值；其次在</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">Beverage</span><span style="font-family: 宋体">类里实现</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">cost()</span><span style="font-family: 宋体">方法来计算调味品的价钱。所有咖啡子类将仍然覆盖</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">cost()</span><span style="font-family: 宋体">方法，只是这次它们需要同时调用基类的</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">cost()</span><span style="font-family: 宋体">方法，以便获得咖啡加上调味品后的总价。</span>&nbsp;&nbsp;
<p style="margin: 0cm 0cm 0pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-family: 宋体">看上去似乎这是一个不错的设计，那么下面我们再来给</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">Beverage</span><span style="font-family: 宋体">增加子类，如下图所示：</span></p>
<p style="margin: 0cm 0cm 0pt"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<div align="center"><img height="369" alt="" src="http://www.cnblogs.com/images/cnblogs_com/justinw/decorator4.jpg" width="553" border="0" />&nbsp;</div>
<p style="margin: 0cm 0cm 0pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-family: 宋体">基类的</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">cost()</span><span style="font-family: 宋体">方法将计算所有调味品的价钱</span>(<span style="font-family: 宋体">当然是只包括布尔值为</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">true</span><span style="font-family: 宋体">的调味品</span>)<span style="font-family: 宋体">，子类里的</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">cost()</span><span style="font-family: 宋体">方法将扩展其功能，以包含特定类型饮料的价钱。</span></p>
<p style="margin: 0cm 0cm 0pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OK! <span style="font-family: 宋体">现在我们似乎已经有了一个看上去还不错的设计，那么</span>Central Perk<span style="font-family: 宋体">的这个记账系统就按这个设计来实现就万事大吉了吗？等一下，还是让我们先从以前学习过的&#8220;<span style="color: red">找到系统中变化的部分，将变化的部分同其它稳定的部分隔开。</span>&#8221;这个设计原则出发，重新推敲一下这个设计。</span></p>
<p style="margin: 0cm 0cm 0pt; text-indent: 21pt"><span style="font-family: 宋体">那么对于一家咖啡店来说，都有那些变化点呢？调味品的品种和价格会变吗？咖啡的品种和价格会变吗？咖啡和调味品的组合方式会变吗？</span><strong>YES!</strong><span style="font-family: 宋体">对于一家咖啡店来说，这些方面肯定会经常发生改变的！那么，当这些改变发生的时候，我们的记账系统要如何应对呢？</span> <span style="font-family: 宋体">如果调味品发生改变，那么我们只能从代码的层次重新调整</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">Beverage</span><span style="font-family: 宋体">基类，这太糟糕了；如果咖啡发生改变，我们可以增加或删除一个子类即可，这个似乎还可以忍受；那么咖啡和调味品的组合方式发生改变呢？如果顾客点了一杯纯黑咖啡外加两份砂糖和一份巧克力，或者顾客点了一杯脱咖啡因咖啡</span>(<span style="font-size: 9pt; color: teal; font-family: 新宋体">Decaf</span>)<span style="font-family: 宋体">外加三份炼乳和一份砂糖呢？我倒！突然意识到，上面的设计根本不支持组合一份以上同种调味品的情况，因为基类里的布尔值只能记录是否包含某种调味品，而并不能表示包含几份，连基本的功能需求都没有满足，看来这些开发者可以卷铺盖滚蛋了！</span><span style="font-size: 9pt; color: red">(</span><span style="font-size: 9pt; color: red; font-family: 宋体">似乎他们改行去做炸弹更合适！</span><span style="font-size: 9pt; color: red">)</span></p>
<p style="margin: 0cm 0cm 0pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-family: 宋体">好吧！让我们来接手这个设计！我们已经分析了前面设计的失败之处，我们应该实现支持调味品的品种和价格任意改变而不需要修改已有代码的设计；我们还要实现支持咖啡品种和价格任意改变而不需要修改已有代码的设计</span>(<span style="font-family: 宋体">这点上面的设计通过继承算是实现了</span>)<span style="font-family: 宋体">；还有就是支持咖啡和调味品的品种和份数任意组合而不需要修改已有代码的设计；还有就是代码重用越多越好了，内聚越高越好了，耦合越低越好了；</span><span style="font-size: 9pt; color: red">(</span><span style="font-size: 9pt; color: red; font-family: 宋体">还有最重要的，报酬越高越好啦！</span><span style="font-size: 9pt; color: red">)</span></p>
<p style="margin: 0cm 0cm 0pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-family: 宋体">看来我们要实现的目标还真不少，那么我们到底该怎么做呢？说实话，我现在也不知道！我们需要先去拜访一下今天的主角—装饰者模式，看看她能给我们带来什么惊喜吧！</span></p>
<h3 style="margin: 13pt 0cm"><span style="font-family: 宋体"><font size="5">这就是装饰者模式</font></span></h3>
<p style="margin: 0cm 0cm 0pt; text-indent: 21pt"><span style="font-family: 宋体">我们还是先看一下官方的定义：</span></p>
<p style="margin: 0cm 0cm 0pt; text-indent: 21pt"><strong><span style="color: red">The Decorator Pattern</span></strong><span style="color: red"> attaches additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.</span> (<span style="font-family: 宋体">装饰者模式可以动态地给一个对象增加其他职责。就扩展对象功能来说，装饰者模式比生成子类更为灵活。</span>)</p>
<p style="margin: 0cm 0cm 0pt; text-indent: 21pt"><span style="font-family: 宋体">这里我们要重点注意那个</span>dynamically<span style="font-family: 宋体">（动态的），什么是动态？静态又是什么？这是我们要重点区分的地方，后面我们还会专门讨论这个问题。下面先看看装饰者模式的类图和顺序图：</span></p>
<p style="margin: 0cm 0cm 0pt"><strong><span>
<div align="center"><img height="278" alt="" src="http://www.cnblogs.com/images/cnblogs_com/justinw/decorator5.gif" width="554" border="0" /></div>
Component</span></strong><strong><span style="font-family: 宋体">（被装饰对象基类）</span></strong>&nbsp;&nbsp;
<p style="margin: 0cm 0cm 0pt 42pt; text-indent: -21pt"><span style="font-family: Wingdings">l<span style="font: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">定义对象的接口，可以给这些对象动态增加职责；</span></p>
<p style="margin: 0cm 0cm 0pt"><strong>ConcreteComponent</strong><strong><span style="font-family: 宋体">（具体被装饰对象）</span></strong></p>
<p style="margin: 0cm 0cm 0pt 42pt; text-indent: -21pt"><span style="font-family: Wingdings">l<span style="font: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">定义具体的对象，</span>Decorator<span style="font-family: 宋体">可以给它增加额外的职责；</span> </p>
<p style="margin: 0cm 0cm 0pt"><strong>Decorator</strong><strong><span style="font-family: 宋体">（装饰者抽象类）</span></strong></p>
<p style="margin: 0cm 0cm 0pt 42pt; text-indent: -21pt"><span style="font-family: Wingdings">l<span style="font: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="color: red; font-family: 宋体">维护一个指向</span><span style="color: red">Component</span><span style="color: red; font-family: 宋体">实例的引用</span><span style="font-family: 宋体">，并且定义了与</span>Component<span style="font-family: 宋体">一致的接口；</span> </p>
<p style="margin: 0cm 0cm 0pt"><strong>ConcreteDecorator</strong><strong><span style="font-family: 宋体">（具体装饰者）</span></strong></p>
<p style="margin: 0cm 0cm 0pt 42pt; text-indent: -21pt"><span style="font-family: Wingdings">l<span style="font: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">具体的装饰对象，<span style="color: red">给内部持有的具体被装饰对象增加具体的职责；</span></span></p>
<p style="margin: 0cm 0cm 0pt"><span><span>
<div align="center"><img height="280" alt="" src="http://www.cnblogs.com/images/cnblogs_com/justinw/decorator6.gif" width="543" border="0" /></div>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">怎么样？大家都看懂了吧</span>!<span style="font-family: 宋体">看懂了我就不解释了！—</span> <span style="font-family: 宋体">呵呵，开玩笑的！</span>
<p style="margin: 0cm 0cm 0pt; text-indent: 21pt"><span style="font-family: 宋体">我们先来说说上面提到的动态和静态的问题，所谓动态是说可以在系统运行时</span>(RunTime)<span style="font-family: 宋体">动态给对象增加其它职责而不需要修改代码或重新编译；所谓静态是说必须通过调整代码</span>(DesignTime)<span style="font-family: 宋体">才能给对象增加职责</span>,<span style="font-family: 宋体">而且系统还需要重新编译；从具体技术层面来说，对象的组合和继承正好对应于前面的动态和静态，因为通过对象组合建立的交互关系不是在代码中</span>(DesignTime)<span style="font-family: 宋体">固定死的，而是在运行时</span>(RunTime)<span style="font-family: 宋体">动态组合的；而通过继承建立的关系是僵硬的难以改变的，因为它是在代码中</span>(DesignTime)<span style="font-family: 宋体">固定死了的，根本不存在运行时</span>(RunTime)<span style="font-family: 宋体">改变的可能。换个角度说：我们应该多使用对象组合来保持系统的运行时扩展性，尽量少使用继续，因为继承让程序变得僵硬！这句话听着是不是很熟悉啊？恩！这就是我们前面文章里提过多次的一个设计原则：</span><strong><span style="color: red">Favor composition over inheritance.</span></strong><span style="font-family: 宋体">（优先使用对象组合，而非类继承），更多的就不需要再解释了吧？</span></p>
<p style="margin: 0cm 0cm 0pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-family: 宋体">那么回到装饰者模式，跟前面介绍过的模式一样，装饰者同样是一个很简单的模式，特别是画出类图和顺序图之后，一切都很清楚明了。这里只有一个地方需要特殊强调一下：</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">Decorator</span><span style="font-family: 宋体">是装饰者模式里非常特殊的一个类，它既继承于</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">Component</span><span style="font-family: 宋体">【</span>IS A<span style="font-family: 宋体">关系】</span>,<span style="font-family: 宋体">又维护一个指向</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">Component</span><span style="font-family: 宋体">实例的引用【</span>HAS A<span style="font-family: 宋体">关系】，换个角度来说，</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">Decorator</span><span style="font-family: 宋体">跟</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">Component</span><span style="font-family: 宋体">之间，既有动态组合关系又有静态继承关系，</span><strong>WHY? </strong><span style="font-family: 宋体">这里为什么要这么来设计？上面我们说过，组合的好处是可以在运行时给对象增加职责，</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">Decorator</span><span style="font-family: 宋体">【</span>HAS A<span style="font-family: 宋体">】</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">Component</span><span style="font-family: 宋体">的目的是让</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">ConcreteDecorator</span><span style="font-family: 宋体">可以在运行时动态给</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">ConcreteComponent</span><span style="font-family: 宋体">增加职责，这一点相对来说还比较好理解；那么</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">Decorator</span><span style="font-family: 宋体">继承于</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">Component</span><span style="font-family: 宋体">的目的是什么？在这里，继承的目的<strong><span style="color: red">只有一个</span></strong>，那就是可以统一装饰者和被装饰者的接口，换个角度来说，不管是</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">ConcretComponent</span><span style="font-family: 宋体">还是</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">ConcreteDecorator</span><span style="font-family: 宋体">，它们都是</span> <span style="font-size: 9pt; color: teal; font-family: 新宋体">Component</span><span style="font-family: 宋体">，用户代码可以把它们统一看作</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">Component</span><span style="font-family: 宋体">来处理，这样带来的更深一层的好处就是，装饰者对象对被装饰者对象的功能职责扩展对用户代码来说是<strong><span style="color: red">完全透明</span></strong>的，因为用户代码引用的都是</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">Component</span><span style="font-family: 宋体">，所以就不会因为被装饰者对象在被装饰后，引用它的用户代码发生错误，实际上不会有任何影响，因为装饰前后，用户代码引用的都是</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">Component</span><span style="font-family: 宋体">类型的对象，这真是太完美了！装饰者模式通过继承实现统一了装饰者和被装饰者的接口，通过组合获得了在运行时动态扩展被装饰者对象的能力。</span></p>
<p style="margin: 0cm 0cm 0pt; text-indent: 21pt"><span style="font-family: 宋体">我们再举个生活中的例子，俗话说&#8220;人在衣着马在鞍&#8221;，把这就话用装饰者模式的语境翻译一下，&#8220;人通过漂亮的衣服装饰后，男人变帅了，女人变漂亮了；&#8221;。对应上面的类图，这里人对应于</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">ConcreteComponent</span>,<span style="font-family: 宋体">而漂亮衣服则对应于</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">ConcreteDecorator</span><span style="font-family: 宋体">；换个角度来说，人和漂亮衣服组合在一起【</span>HAS A<span style="font-family: 宋体">】，有了帅哥或美女，但是他们还是人【</span>IS A<span style="font-family: 宋体">】，还要做人该做的事情，但是可能会对异性更有吸引力了</span>(<span style="font-family: 宋体">扩展功能</span>)<span style="font-family: 宋体">！</span>&nbsp;&nbsp;&nbsp;&nbsp; </p>
<p style="margin: 0cm 0cm 0pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-family: 宋体">现在我们已经认识了装饰者模式，知道了动态关系和静态关系是怎么回事，是时候该解决咖啡店的问题了，从装饰者模式的角度来考虑问题，咖啡和调味品的关系应该是：咖啡是被装饰对象而调味品是装饰者，咖啡和调味品可以任意组合，但是不管怎么组合，咖啡还是咖啡！原来这么简单啊！具体看下面的类图：</span></p>
<p style="margin: 0cm 0cm 0pt"><span><span>
<div align="center"><img height="394" alt="" src="http://www.cnblogs.com/images/cnblogs_com/justinw/decorator7.jpg" width="553" border="0" /></div>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">如图所示，</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">Beverage</span><span style="font-family: 宋体">还是所有饮料的基类，它对应于装饰者模式类图里的</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">Component</span>,<span style="font-family: 宋体">是所有被装饰对象的基类；</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">HouseBlend</span>, <span style="font-size: 9pt; color: teal; font-family: 新宋体">DarkRoast</span>, <span style="font-size: 9pt; color: teal; font-family: 新宋体">Espresso</span>, <span style="font-size: 9pt; color: teal; font-family: 新宋体">Decaf</span><span style="font-family: 宋体">是具体的饮料</span>(<span style="font-family: 宋体">咖啡</span>)<span style="font-family: 宋体">种类，对应于前面的</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">ConcreteComponent</span><span style="font-family: 宋体">，即是具体的被装饰对象；</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">CondimentDecorator</span><span style="font-family: 宋体">对应于前面的</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">Decorator</span><span style="font-family: 宋体">，是装饰者的抽象类；而</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">Milk</span><span style="font-family: 宋体">，</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">Mocha</span><span style="font-family: 宋体">，</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">Soy</span><span style="font-family: 宋体">，</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">Whip</span><span style="font-family: 宋体">则都是具体的调味品，对于前面的</span><span style="font-size: 9pt; color: teal; font-family: 新宋体">ConcreteDecorator</span><span style="font-family: 宋体">，也就是具体的装饰者。下面我们通过具体的代码再进一步理解一下基于装饰者模式的记账系统的实现。</span>&nbsp;</span></span>
<img src ="http://www.blogjava.net/supercrsky/aggbug/202691.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/supercrsky/" target="_blank">々上善若水々</a> 2008-05-25 10:06 <a href="http://www.blogjava.net/supercrsky/articles/202691.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>学习装饰者模式(Decorator)</title><link>http://www.blogjava.net/supercrsky/articles/202690.html</link><dc:creator>々上善若水々</dc:creator><author>々上善若水々</author><pubDate>Sun, 25 May 2008 01:58:00 GMT</pubDate><guid>http://www.blogjava.net/supercrsky/articles/202690.html</guid><wfw:comment>http://www.blogjava.net/supercrsky/comments/202690.html</wfw:comment><comments>http://www.blogjava.net/supercrsky/articles/202690.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/supercrsky/comments/commentRss/202690.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/supercrsky/services/trackbacks/202690.html</trackback:ping><description><![CDATA[<p>1、定义及作用</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 该模式以对客户端透明的方式扩展对象的功能。</p>
<p>2、涉及角色<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 抽象构件角色：定义一个抽象接口，来规范准备附加功能的类。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 具体构件角色：将要被附加功能的类，实现抽象构件角色接口。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 抽象装饰者角色：持有对具体构件角色的引用并定义与抽象构件角色一致的接口。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 具体装饰角色：实现抽象装饰者角色，负责为具体构件添加额外功能。</p>
<p>&nbsp; <br />
&nbsp; 3、简单实现 <br />
抽象构件角色java 代码:</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"  alt="" /><span style="color: #0000ff">package</span><span style="color: #000000">&nbsp;com.pattern.decorator2;<br />
<img id="Codehighlighter1_32_66_Open_Image" onclick="this.style.display='none'; Codehighlighter1_32_66_Open_Text.style.display='none'; Codehighlighter1_32_66_Closed_Image.style.display='inline'; Codehighlighter1_32_66_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_32_66_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_32_66_Closed_Text.style.display='none'; Codehighlighter1_32_66_Open_Image.style.display='inline'; Codehighlighter1_32_66_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /></span><span id="Codehighlighter1_32_66_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">/**&nbsp;*/</span><span id="Codehighlighter1_32_66_Open_Text"><span style="color: #008000">/**</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;*&nbsp;抽象构件角色<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;*&nbsp;</span><span style="color: #808080">@author</span><span style="color: #008000">&nbsp;zdw<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;*<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />&nbsp;</span><span style="color: #008000">*/</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">interface</span><span style="color: #000000">&nbsp;Component<br />
<img id="Codehighlighter1_95_125_Open_Image" onclick="this.style.display='none'; Codehighlighter1_95_125_Open_Text.style.display='none'; Codehighlighter1_95_125_Closed_Image.style.display='inline'; Codehighlighter1_95_125_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_95_125_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_95_125_Closed_Text.style.display='none'; Codehighlighter1_95_125_Open_Image.style.display='inline'; Codehighlighter1_95_125_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /></span><span id="Codehighlighter1_95_125_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_95_125_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">默认方法A</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;functionA();<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span></div>
<br />
具体构件角色:<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #0000ff">package</span><span style="color: #000000">&nbsp;com.pattern.decorator2;<br />
<img id="Codehighlighter1_32_66_Open_Image" onclick="this.style.display='none'; Codehighlighter1_32_66_Open_Text.style.display='none'; Codehighlighter1_32_66_Closed_Image.style.display='inline'; Codehighlighter1_32_66_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_32_66_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_32_66_Closed_Text.style.display='none'; Codehighlighter1_32_66_Open_Image.style.display='inline'; Codehighlighter1_32_66_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /></span><span id="Codehighlighter1_32_66_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">/**&nbsp;*/</span><span id="Codehighlighter1_32_66_Open_Text"><span style="color: #008000">/**</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;*&nbsp;具体构件角色<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;*&nbsp;</span><span style="color: #808080">@author</span><span style="color: #008000">&nbsp;zdw<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;*<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />&nbsp;</span><span style="color: #008000">*/</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;ConcreateComponent&nbsp;</span><span style="color: #0000ff">implements</span><span style="color: #000000">&nbsp;Component<br />
<img id="Codehighlighter1_121_193_Open_Image" onclick="this.style.display='none'; Codehighlighter1_121_193_Open_Text.style.display='none'; Codehighlighter1_121_193_Closed_Image.style.display='inline'; Codehighlighter1_121_193_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_121_193_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_121_193_Closed_Text.style.display='none'; Codehighlighter1_121_193_Open_Image.style.display='inline'; Codehighlighter1_121_193_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /></span><span id="Codehighlighter1_121_193_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_121_193_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&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;functionA()<br />
<img id="Codehighlighter1_151_190_Open_Image" onclick="this.style.display='none'; Codehighlighter1_151_190_Open_Text.style.display='none'; Codehighlighter1_151_190_Closed_Image.style.display='inline'; Codehighlighter1_151_190_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_151_190_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_151_190_Closed_Text.style.display='none'; Codehighlighter1_151_190_Open_Image.style.display='inline'; Codehighlighter1_151_190_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_151_190_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_151_190_Open_Text"><span style="color: #000000">{<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">Function&nbsp;A</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />}</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span></div>
<br />
抽象装饰者角色:<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #0000ff">package</span><span style="color: #000000">&nbsp;com.pattern.decorator2;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img id="Codehighlighter1_33_73_Open_Image" onclick="this.style.display='none'; Codehighlighter1_33_73_Open_Text.style.display='none'; Codehighlighter1_33_73_Closed_Image.style.display='inline'; Codehighlighter1_33_73_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_33_73_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_33_73_Closed_Text.style.display='none'; Codehighlighter1_33_73_Open_Image.style.display='inline'; Codehighlighter1_33_73_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /></span><span id="Codehighlighter1_33_73_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">/**&nbsp;*/</span><span id="Codehighlighter1_33_73_Open_Text"><span style="color: #008000">/**</span><span style="color: #008000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;*&nbsp;抽象装饰者角色<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;*&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;*&nbsp;</span><span style="color: #808080">@author</span><span style="color: #008000">&nbsp;zdw<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top"  alt="" />&nbsp;*&nbsp;<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"  alt="" />&nbsp;</span><span style="color: #008000">*/</span></span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;Decorator&nbsp;</span><span style="color: #0000ff">implements</span><span style="color: #000000">&nbsp;Component<br />
<img id="Codehighlighter1_119_299_Open_Image" onclick="this.style.display='none'; Codehighlighter1_119_299_Open_Text.style.display='none'; Codehighlighter1_119_299_Closed_Image.style.display='inline'; Codehighlighter1_119_299_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top"  alt="" /><img id="Codehighlighter1_119_299_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_119_299_Closed_Text.style.display='none'; Codehighlighter1_119_299_Open_Image.style.display='inline'; Codehighlighter1_119_299_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top"  alt="" /></span><span id="Codehighlighter1_119_299_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"  alt="" /></span><span id="Codehighlighter1_119_299_Open_Text"><span style="color: #000000">{<br />
<