﻿<?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-桢知卓见-文章分类-java设计模式</title><link>http://www.blogjava.net/jalion/category/23705.html</link><description /><language>zh-cn</language><lastBuildDate>Mon, 02 Jul 2007 00:36:33 GMT</lastBuildDate><pubDate>Mon, 02 Jul 2007 00:36:33 GMT</pubDate><ttl>60</ttl><item><title>设计模式结构模式之——适配器模式(adapter)</title><link>http://www.blogjava.net/jalion/articles/127330.html</link><dc:creator>李桢</dc:creator><author>李桢</author><pubDate>Sun, 01 Jul 2007 02:21:00 GMT</pubDate><guid>http://www.blogjava.net/jalion/articles/127330.html</guid><wfw:comment>http://www.blogjava.net/jalion/comments/127330.html</wfw:comment><comments>http://www.blogjava.net/jalion/articles/127330.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jalion/comments/commentRss/127330.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jalion/services/trackbacks/127330.html</trackback:ping><description><![CDATA[<p>类的适配器模式是把适配的类的API转换为目标类的API.在以下各种情况需要使用适配器模式:</p>
<p>1)系统需要使用现有的类,而此类的接口不符合系统的需要.</p>
<p>2)想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作.这些原类不一定有很复杂的接口.</p>
<p>3)(对对象的适配器模式)在设计里,需要改变多个已有的子类的接口,如果使用类的适配器模式,就要针对每一个子类做一个适配器类,而这不太实际.</p>
<p>下面通过一个实际的问题来理解适配器模式.</p>
<p>问题:请做一个Kittie具体类,并实现miao(),catchRat(),run(),sleep()方法,再做一个Puppie的接口,要求有wao(),fetchBall(),run(),sleep()方法.</p>
<p>假设现在客户需要一只Puppie,可是只找到一只Kittie,所以需要适配器Jalion把Kittie适配成Puppie.</p>
<p>代码如下:</p>
<p>===============================================================================</p>
<p>类Kittie</p>
<p>public class Kittie {<br>&nbsp;public void miao()<br>&nbsp;{<br>&nbsp;&nbsp;<br>&nbsp;}<br>&nbsp;public void run()<br>&nbsp;{<br>&nbsp;&nbsp;<br>&nbsp;}<br>&nbsp;public void sleep()<br>&nbsp;{<br>&nbsp;&nbsp;<br>&nbsp;}<br>}<br></p>
<p>接口Puppie</p>
<p>public interface Puppie {<br>&nbsp;public void wao();<br>&nbsp;public void fetchBall();<br>&nbsp;public void run();<br>&nbsp;public void sleep();<br>}<br></p>
<p>适配器Jalion</p>
<p><br>public class Jalion extends Kittie implements Puppie {</p>
<p>&nbsp;public void fetchBall() {<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;<br>&nbsp;}</p>
<p>&nbsp;public void wao() {<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;<br>&nbsp;}<br>&nbsp;public void run()<br>&nbsp;{<br>&nbsp;&nbsp;super.run();<br>&nbsp;}<br>&nbsp;public void sleep()<br>&nbsp;{<br>&nbsp;&nbsp;super.sleep();<br>&nbsp;}</p>
<p>}<br></p>
<p>================================================================================</p>
<p>在本例中,系统需要的是一个Puppie类,但现在只找到一个Kittie类,通过一个适配器,把功能和Puppie相近的类转换成了符合要求的Puppie类.</p>
<p><img style="DISPLAY: block; MARGIN: 0px auto 10px; TEXT-ALIGN: center" alt="" src="http://117.img.pp.sohu.com/images/blog/2007/5/8/16/13/11302c137f7.jpg" border=0></p>
<p>&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;</p>
<p>适配器模式之缺省适配器模式<br>当一个接口定义了n个方法</p>
<p>public interface interfaceA {<br>&nbsp;public void method1();<br>&nbsp;public void method2();<br>&nbsp;public void method3();<br>&nbsp;public void method4();<br>&nbsp;public void method5();<br>&nbsp;public void method6();<br>&nbsp;public void method7();<br>}</p>
<p>当一个类需要实现这个接口时,必须实现所有的方法,即使是你不需要的恶方法也得默认空实现.造成了浪费和麻烦.</p>
<p>使用适配器模式可以解决此问题</p>
<p>定义一个抽象类,实现接口interfaceA</p>
<p>public&nbsp; abstract class AbstractA implements interfaceA {</p>
<p>&nbsp;public void method1() {}<br>&nbsp;public void method2() {}<br>&nbsp;public void method3() {}<br>&nbsp;public void method4() {}<br>&nbsp;public void method5() {}<br>&nbsp;public void method6() {}<br>&nbsp;public void method7() {}<br>}</p>
<p>然后让实体类继承抽象类</p>
<p>public class ClassA extends AbstractA {<br>&nbsp;public void method1()<br>&nbsp;{<br>&nbsp;&nbsp;<br>&nbsp;}<br>&nbsp;public void method7()<br>&nbsp;{<br>&nbsp;&nbsp;<br>&nbsp;}<br>}<br>这样就可以在类中添加感兴趣的方法了.在awt事件监听器中,许多都是用了缺省适配器模式.</p>
<p><img style="DISPLAY: block; MARGIN: 0px auto 10px; TEXT-ALIGN: center" alt="" src="http://115.img.pp.sohu.com/images/blog/2007/5/8/17/28/11302e7c6dc.jpg" border=0></p>
<img src ="http://www.blogjava.net/jalion/aggbug/127330.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jalion/" target="_blank">李桢</a> 2007-07-01 10:21 <a href="http://www.blogjava.net/jalion/articles/127330.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>设计模式之结构模式—— 合成模式</title><link>http://www.blogjava.net/jalion/articles/127331.html</link><dc:creator>李桢</dc:creator><author>李桢</author><pubDate>Sun, 01 Jul 2007 02:21:00 GMT</pubDate><guid>http://www.blogjava.net/jalion/articles/127331.html</guid><wfw:comment>http://www.blogjava.net/jalion/comments/127331.html</wfw:comment><comments>http://www.blogjava.net/jalion/articles/127331.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jalion/comments/commentRss/127331.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jalion/services/trackbacks/127331.html</trackback:ping><description><![CDATA[<p>设计模式中的合成模式</p>
<p>合成模式即是来描述整体和部分关系的模式。使得客户端把一个个单独的成分对象和由他们复合成的对象同等对待。根据实现细节不同，分为两种方式：安全方式和透明方式。下面以一个几何图形的例子来了解下这2种方式.</p>
<p>一个简单的几何图形是有圆,直线,矩形组成.其中几何图形就是由一个或多个单独的直线,圆,矩形对象组成的符合对象.</p>
<p>所以本例一共有4个类,一个接口.Graphics 接口,line类,rectangle类,circle类,Picture类.根据两个UML注意区别安全方式和透明方式的实现细节.</p>
<p><font color=#0000ff size=4><strong>1)安全方式</strong></font></p>
<p><img style="DISPLAY: block; MARGIN: 0px auto 10px; TEXT-ALIGN: center" alt="" src="http://116.img.pp.sohu.com/images/blog/2007/5/9/11/17/11306c37d85.JPG" border=0></p>
<p>=====================================================================================</p>
<p><font color=#ff0000>接口 Graphics</font></p>
<p>public interface Graphics {<br>&nbsp;public void draw();<br>}</p>
<p><font color=#ff0000>类Line</font></p>
<p>public class Line&nbsp; implements Graphics&nbsp; {<br>&nbsp;public void draw()<br>&nbsp;{<br>&nbsp;&nbsp;System.out.println("画一条直线");<br>&nbsp;}</p>
<p>}<br></p>
<p><font color=#ff0000>类Circle</font></p>
<p>public class Circle implements Graphics {</p>
<p>&nbsp;public void draw() {<br>&nbsp;&nbsp;System.out.println("画一个圆");<br>&nbsp;}<br>&nbsp;<br>}</p>
<p><font color=#ff0000>类Rectangle</font></p>
<p>public class Rectangle implements Graphics{<br>&nbsp;public void draw()<br>&nbsp;{<br>&nbsp;&nbsp;System.out.println("画一个矩形");<br>&nbsp;}<br>}<br></p>
<p><font color=#ff0000>类Picture</font></p>
<p>import java.util.*;</p>
<p>public class Picture implements Graphics {<br>&nbsp;private List list=new ArrayList();<br>&nbsp;<br>&nbsp;public void draw()<br>&nbsp;{<br>&nbsp;&nbsp;for(int i=0;i&lt;list.size();i++)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;Graphics g=(Graphics)list.get(i);<br>&nbsp;&nbsp;&nbsp;g.draw();<br>&nbsp;&nbsp;}<br>&nbsp;}<br>&nbsp;public void add(Graphics g)<br>&nbsp;{<br>&nbsp;&nbsp;list.add(g);<br>&nbsp;}<br>&nbsp;public void remove(Graphics g)<br>&nbsp;{<br>&nbsp;&nbsp;list.remove(g);<br>&nbsp;}<br>&nbsp;public Graphics getGraphics(int i)<br>&nbsp;{<br>&nbsp;&nbsp;return (Graphics)list.get(i);<br>&nbsp;}<br>&nbsp;<br>}<br></p>
<p>=========================================================================================</p>
<p><font color=#0000ff size=4><strong>2)透明方式<img style="DISPLAY: block; MARGIN: 0px auto 10px; TEXT-ALIGN: center" alt="" src="http://116.img.pp.sohu.com/images/blog/2007/5/9/11/0/11306cf760e.JPG" border=0></strong></font></p>
<p>=====================================================================================</p>
<p><font color=#ff0000>接口 Graphics</font></p>
<p>&nbsp;public interface Graphics {<br>&nbsp;public void draw();<br>&nbsp;public void add(Graphics g);<br>&nbsp;public void remove(Graphics g);<br>&nbsp;public Graphics getGraphics(int i);<br>}</p>
<p><font color=#ff0000>类Line</font></p>
<p>&nbsp;</p>
<p>public class Line implements Graphics{</p>
<p>&nbsp;public void add(Graphics g) {&nbsp;<br>&nbsp;}</p>
<p>&nbsp;public void draw() {<br>&nbsp;&nbsp;System.out.println("画一条直线");<br>&nbsp;&nbsp;<br>&nbsp;}</p>
<p>&nbsp;public Graphics getGraphics(int i) {<br>&nbsp;&nbsp;return null;<br>&nbsp;}</p>
<p>&nbsp;public void remove(Graphics g) {<br>&nbsp;}</p>
<p>}<br></p>
<p><font color=#ff0000>类Circle</font></p>
<p>&nbsp;</p>
<p>public class Circle implements Graphics{</p>
<p>&nbsp;public void add(Graphics g) {<br>&nbsp;}</p>
<p>&nbsp;public void draw() {<br>&nbsp;&nbsp;System.out.println("画一个圆");<br>&nbsp;&nbsp;<br>&nbsp;}</p>
<p>&nbsp;public Graphics getGraphics(int i) {<br>&nbsp;&nbsp;return null;<br>&nbsp;}</p>
<p>&nbsp;public void remove(Graphics g) {<br>&nbsp;}</p>
<p>}</p>
<p><font color=#ff0000>类Rectangle</font></p>
<p>&nbsp;</p>
<p>public class Rectangle implements Graphics {</p>
<p>&nbsp;public void add(Graphics g) {<br>&nbsp;}</p>
<p>&nbsp;public void draw() {<br>&nbsp;&nbsp;System.out.println("画一个矩形");<br>&nbsp;&nbsp;<br>&nbsp;}</p>
<p>&nbsp;public Graphics getGraphics(int i) {<br>&nbsp;&nbsp;return null;<br>&nbsp;}</p>
<p>&nbsp;public void remove(Graphics g) {<br>&nbsp;&nbsp;<br>&nbsp;}</p>
<p>}<br></p>
<p><font color=#ff0000>类Picture</font></p>
<p>&nbsp;public class Picture implements Graphics {<br>&nbsp;private List list=new ArrayList();<br>&nbsp;<br>&nbsp;public void draw()<br>&nbsp;{<br>&nbsp;&nbsp;for(int i=0;i&lt;list.size();i++)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;Graphics g=(Graphics)list.get(i);<br>&nbsp;&nbsp;&nbsp;g.draw();<br>&nbsp;&nbsp;}<br>&nbsp;}<br>&nbsp;public void add(Graphics g)<br>&nbsp;{<br>&nbsp;&nbsp;list.add(g);<br>&nbsp;}<br>&nbsp;public void remove(Graphics g)<br>&nbsp;{<br>&nbsp;&nbsp;list.remove(g);<br>&nbsp;}<br>&nbsp;public Graphics getGraphics(int i)<br>&nbsp;{<br>&nbsp;&nbsp;return (Graphics)list.get(i);<br>&nbsp;}<br>&nbsp;<br>}</p>
<p>=========================================================================================</p>
<p><font color=#9966ff>在安全方式和透明方式中,不同之处是实现对子类的管理方法:add(),remove(),getGraphics()的位置不同,是在Graphics接口中实现,还是在复合类Picture中实现.</font></p>
<p><font color=#9966ff>在安全方式中,管理方法在复合类Picture中实现,如果客户端在对Line()等单独的成分对象发送add()等消息时,无法编译通过.</font></p>
<p><font color=#9966ff>在透明方式中,将管理方法在接口中定义,所有单独成分对象(如:Line()等)由于实现了Graphics接口,必须实现add()等管理方法,即使是方法中不需要任何操作,当客户端在对单独成分对象发送add()等消息时,编译通过,但在程序运行时,则可能会抛出异常.这样做的好处是都有相同的接口,客户端可以同等的对待对象.</font></p>
<p><strong><font color=#0000ff>适合使用合成模式的条件:</font></strong></p>
<p><strong><font color=#0000ff>1)需要描述对象的部分和整体的等级结构</font></strong></p>
<p><strong><font color=#0000ff>2)客户端需要忽略掉整体构件和个体构件的区别</font></strong></p>
<p><strong><font color=#ff00ff>合成模式的优点:</font></strong></p>
<p><strong><font color=#ff00ff>1.可以很容易的增加新种类的构件</font></strong></p>
<p><strong><font color=#ff00ff>2.使用合成模式可以使客户端变得很容易设计,因为客户端不需要知道构件是个体构件还是整体构件</font></strong></p>
<p><strong><font color=#ff00ff>缺点:</font></strong></p>
<p><strong><font color=#ff00ff>1.控制整体构件的类型比较困难</font></strong></p>
<p><strong><font color=#ff00ff>2.用继承方法增加新的行为很困难.</font></strong></p>
<img src ="http://www.blogjava.net/jalion/aggbug/127331.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jalion/" target="_blank">李桢</a> 2007-07-01 10:21 <a href="http://www.blogjava.net/jalion/articles/127331.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java  设计模式——工厂模式之单例模式</title><link>http://www.blogjava.net/jalion/articles/127329.html</link><dc:creator>李桢</dc:creator><author>李桢</author><pubDate>Sun, 01 Jul 2007 02:20:00 GMT</pubDate><guid>http://www.blogjava.net/jalion/articles/127329.html</guid><wfw:comment>http://www.blogjava.net/jalion/comments/127329.html</wfw:comment><comments>http://www.blogjava.net/jalion/articles/127329.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jalion/comments/commentRss/127329.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jalion/services/trackbacks/127329.html</trackback:ping><description><![CDATA[<p>单例模式 因该是最简单的一个设计模式，只要满足：1）某个类只能有一个实例，2）这个实例是由本身创建，3）类本身向整个系统提供实例</p>
<p>单例模式的写法：</p>
<p>第一种</p>
<p><strong><font color=#ff0000>public class EagerSingle {<br>&nbsp;private static final EagerSingle s=new EagerSingle();<br>&nbsp;private EagerSingle()<br>&nbsp;{<br>&nbsp;}<br>&nbsp;public static EagerSingle getInstance()<br>&nbsp;{<br>&nbsp;&nbsp;return s;<br>&nbsp;}</font></strong></p>
<p><strong><font color=#ff0000>}</font></strong></p>
<p>第二种：<br><strong><font color=#ff0000>public class LazySingle {<br>private static LazySingle ls=null;<br>&nbsp;private LazySingle()<br>&nbsp;{<br>&nbsp;&nbsp;}<br>synchronized static LazySingle getIntance()<br>{<br>&nbsp;if(ls==null)<br>&nbsp;{<br>&nbsp;&nbsp;ls=new LazySingle();<br>&nbsp;}<br>&nbsp;return ls;<br>}<br>}</font></strong></p>
<p><strong><font color=#000000>两种写法的比较：</font></strong></p>
<p><strong>第一种在加载时就将自己实例化，资源利用率低，效率和反应速度高。</strong></p>
<p><strong>第二种在首次用到类的时候实例化，效率和反映率相对低，但有效的利用资源。</strong></p>
<p>单例模式的扩展：</p>
<p>&nbsp;不完全单例模式：构造子为public </p>
<p>&nbsp;多例模式</p>
<img src ="http://www.blogjava.net/jalion/aggbug/127329.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jalion/" target="_blank">李桢</a> 2007-07-01 10:20 <a href="http://www.blogjava.net/jalion/articles/127329.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java  设计模式——工厂模式之 抽象工厂模式</title><link>http://www.blogjava.net/jalion/articles/127328.html</link><dc:creator>李桢</dc:creator><author>李桢</author><pubDate>Sun, 01 Jul 2007 02:19:00 GMT</pubDate><guid>http://www.blogjava.net/jalion/articles/127328.html</guid><wfw:comment>http://www.blogjava.net/jalion/comments/127328.html</wfw:comment><comments>http://www.blogjava.net/jalion/articles/127328.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jalion/comments/commentRss/127328.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jalion/services/trackbacks/127328.html</trackback:ping><description><![CDATA[<p>抽象工厂模式面对的问题是多个产品等级结构的设计。抽象工厂模式可以向客户端提供一个接口，使得客户端在不必指定产品具体类型的情况下，创建多个产品族中的产品对象。先看一下UML：</p>
<p><img style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 601px; HEIGHT: 262px; TEXT-ALIGN: center" height=262 alt="" src="http://img45.pp.sohu.com/images/blog/2007/4/26/16/1/112c491c0a6.jpg" width=572 border=0></p>
<p>在上图中，假设农场现在可以生产水果和蔬菜，从地域上划分，又分为南方和北方。所以产品等级图分为：南方水果，南方蔬菜，北方水果，北方蔬菜；抽象工厂模式与工厂方法模式最大的区别在于：工厂方法模式针对的是一个产品等级结构，而抽象工厂模式则需要面对多个产品等级结构。</p>
<p>&nbsp; 有多少个产品等级结构，就会在工厂角色中发现多少个工厂方法。 每个产品等级结构中有多少具体产品，就有多少个产品族，也就会在工厂等级结构中发现多少个具体工厂；例如在上图中，产品等级结构：蔬菜（vegetable）和水果(Fruit），相应的工厂角色中就有public Fruit createFruit()和public Vegetable CreateVegetable()方法。有2个产品族：North和South，对应两个具体工厂，NorthFactory和SouthFactory;<br>关于抽象模式和开闭原则：</p>
<p>当增加产品等级结构时，即当我们增加一个新产品：花卉时，需要修改工厂角色的工厂方法，这显然是不支持开闭原则的；</p>
<p>当增加产品族时，即添加了新的产品角色，这时，只需添加新的工厂角色就可以了，符合开闭原则；</p>
<p>工厂模式的变通：工厂的工厂</p>
<p>可以把简单工厂模式应用到抽象工厂中，抽象工厂类可以配备静态方法，根据需要返回相应的工厂角色。返回值应该是抽象工厂类型，这样才能保证多态性。下面是一个按照此方法改进的 抽象工厂模式UML</p>
<p><img style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 100%; HEIGHT: 100%; TEXT-ALIGN: center" height=30 alt="" src="http://img114.pp.sohu.com/images/blog/2007/4/25/17/3/112bfb4b788.jpg" width=117 border=0></p>
<img src ="http://www.blogjava.net/jalion/aggbug/127328.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jalion/" target="_blank">李桢</a> 2007-07-01 10:19 <a href="http://www.blogjava.net/jalion/articles/127328.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>设计模式之创建模式——简单工厂模式</title><link>http://www.blogjava.net/jalion/articles/127326.html</link><dc:creator>李桢</dc:creator><author>李桢</author><pubDate>Sun, 01 Jul 2007 02:17:00 GMT</pubDate><guid>http://www.blogjava.net/jalion/articles/127326.html</guid><wfw:comment>http://www.blogjava.net/jalion/comments/127326.html</wfw:comment><comments>http://www.blogjava.net/jalion/articles/127326.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jalion/comments/commentRss/127326.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jalion/services/trackbacks/127326.html</trackback:ping><description><![CDATA[<p>&nbsp;简单工厂模式的 代码示例：本例实现了一个 水果工厂，有一个果农负责生产客户需要的水果。 客户只需要告诉果农：我要苹果或者草莓等，果农就可以提供相应的产品给客户。下面是简单工厂模式完全应用的UML</p>
<p><img style="DISPLAY: block; MARGIN: 0px auto 10px; TEXT-ALIGN: center" alt="" src="http://img45.pp.sohu.com/images/blog/2007/4/23/16/4/112b52ce6cc.jpg" border=0></p>
<p>接口Fruits的代码如下：</p>
<p><font color=#ff0000>public interface Fruits {<br>&nbsp;public void grow();<br>&nbsp;public void harvest();<br>&nbsp;public void plant();<br>&nbsp;<br>}</font></p>
<p>类Apple的源代码</p>
<p><font color=#ff0000>public class Apple implements Fruits {</font></p>
<p><font color=#ff0000>&nbsp;/*<br>&nbsp; * 苹果的特有属性。苹果数的树龄<br>&nbsp; */<br>&nbsp;private int treeage;<br>&nbsp;public int getTreeage() {<br>&nbsp;&nbsp;return treeage;<br>&nbsp;}</font></p>
<p><font color=#ff0000>&nbsp;public void setTreeage(int treeage) {<br>&nbsp;&nbsp;this.treeage = treeage;<br>&nbsp;}</font></p>
<p><font color=#ff0000>&nbsp;public void grow() {<br>&nbsp;&nbsp;System.out.println("苹果的生长方法");</font></p>
<p><font color=#ff0000>&nbsp;}</font></p>
<p><font color=#ff0000>&nbsp;public void harvest() {<br>&nbsp;&nbsp;System.out.println("苹果的收获方法");</font></p>
<p><font color=#ff0000>&nbsp;}</font></p>
<p><font color=#ff0000>&nbsp;public void plant() {<br>&nbsp;&nbsp;System.out.println("苹果的种植方法");</font></p>
<p><font color=#ff0000>&nbsp;}</font></p>
<p><font color=#ff0000>}</font></p>
<p>类Grape的源代码</p>
<p><font color=#ff0000>public class Grape implements Fruits {</font></p>
<p><font color=#ff0000>&nbsp;/*<br>&nbsp; * 葡萄的特有属性：有籽和无籽<br>&nbsp; */<br>&nbsp;private boolean seedless;<br>&nbsp;public boolean isSeedless() {<br>&nbsp;&nbsp;return seedless;<br>&nbsp;}</font></p>
<p><font color=#ff0000>&nbsp;public void setSeedless(boolean seedless) {<br>&nbsp;&nbsp;this.seedless = seedless;<br>&nbsp;}</font></p>
<p><font color=#ff0000>&nbsp;public void grow() {<br>&nbsp;System.out.println("葡萄的生长方法");</font></p>
<p><font color=#ff0000>&nbsp;}</font></p>
<p><font color=#ff0000>&nbsp;public void harvest() {<br>&nbsp;&nbsp;System.out.println("葡萄的收获方法");&nbsp;</font></p>
<p><font color=#ff0000>&nbsp;}</font></p>
<p><font color=#ff0000>&nbsp;public void plant() {<br>&nbsp;&nbsp;System.out.println("葡萄的种植方法");</font></p>
<p><font color=#ff0000>&nbsp;}</font></p>
<p><font color=#ff0000>}</font></p>
<p>StrawBerry的源代码</p>
<p><font color=#ff0000>public class StrawBerry implements Fruits {</font></p>
<p><font color=#ff0000>&nbsp;public void grow() {<br>&nbsp;&nbsp;System.out.println("草莓的生长方法");<br>&nbsp;}</font></p>
<p><font color=#ff0000>&nbsp;public void harvest() {<br>&nbsp;&nbsp;System.out.println("草莓的收获方法");</font></p>
<p><font color=#ff0000>&nbsp;}</font></p>
<p><font color=#ff0000>&nbsp;public void plant() {<br>&nbsp;&nbsp;System.out.println("草莓的种植方法");<br>&nbsp;}</font></p>
<p><font color=#ff0000>}<br></font>水果工厂的原代码</p>
<p><font color=#ff0000>public class FruitsGrower {<br>&nbsp;public static Fruits fruitFactory(String fruitType) throws BadFruitException<br>&nbsp;{<br>&nbsp;&nbsp;if(fruitType.equalsIgnoreCase("grape"))<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;return new Grape();<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;else if(fruitType.equalsIgnoreCase("apple"))<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;return new Apple();<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;else if(fruitType.equalsIgnoreCase("strawberry"))<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;return new StrawBerry();&nbsp;<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;else <br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;throw new BadFruitException("这个水果工厂不能生产类型为"+fruitType+"的水果");<br>&nbsp;&nbsp;}<br>&nbsp;}<br>}<br></font></p>
<p>如果请求的类型错误，抛出BadFruitException异常</p>
<p><font color=#ff0000>public class BadFruitException extends Exception {<br>&nbsp;/**<br>&nbsp; * <br>&nbsp; */<br>&nbsp;private static final long serialVersionUID = 4036317488144249503L;</font></p>
<p><font color=#ff0000>&nbsp;public BadFruitException(String msg) {<br>&nbsp;&nbsp;super(msg);<br>&nbsp;}<br>}</font></p>
<p><font color=#000000>工厂方法的使用</font></p>
<p><font color=#ff0000>&nbsp;public static void main(String args[])<br>&nbsp;{<br>&nbsp;&nbsp;try {<br>&nbsp;&nbsp;&nbsp;FruitsGrower.fruitFactory("grape");<br>&nbsp;&nbsp;} catch (BadFruitException e) {<br>&nbsp;&nbsp;&nbsp;// TODO 自动生成 catch 块<br>&nbsp;&nbsp;&nbsp;e.printStackTrace();<br>&nbsp;&nbsp;}<br>&nbsp;}</font></p>
<p><font color=#000000>====================================================================</font></p>
<p>以上代码演示了一个完整的简单工厂模式（SimpleFactory）,在实际应用中，可以省略产品的抽象,即Fruits接口，直接产生产品；也可以将工厂与抽象产品合并，即抽象产品也是也是生产子类的工厂；也可以将3个角色全部合并。</p>
<p>1。简单工厂模式的优点：</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 模式的核心是工厂类，这个类含有必要的判断逻辑，可以决定在什么时候创建哪个产品的实例。而客户端可以免除直接创建产品对象的责任，而仅仅负责&#8220;消费&#8221;产品。实现了责任分隔。</p>
<p>2。缺点：</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;上面的例子中，果农类无疑是整个模式的核心类，当他不能工作了，整个工厂就随之瘫痪。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 可扩展性：当需要添加新的产品时，就必须更改果农类的代码，增加必要的 判断逻辑。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 由于果农类使用了静态方法为工厂方法，而静态方法无法由子类继承，因此工厂角色无法形成基于继承的等级结构。</p>
<p>================================================================</p>
<p>简单工厂模式作为一个最基本的设计模式，在JDK的API中得到了很好的应用。、</p>
<p>DateFormat 类：</p>
<p>&nbsp;&nbsp;&nbsp; 一个日期和时间的格式化类，&nbsp;查看代码可以发现：DateFormat类是一个抽象类，但DateFormat.getDateInstance()为什么又会得到一个实例呢？原来DateFormat.getDateInstance()并没有调用DateFormat()来构造自己的实例，而是使用了静态方法，经过逻辑判断生成了SimpleDateFormat实例。SimpleDateFormat则是DateFormat的一个子类。</p>
<p>下面是DateFormat的示意图：</p>
<p><img style="DISPLAY: block; MARGIN: 0px auto 10px; TEXT-ALIGN: center" alt="" src="http://img44.pp.sohu.com/images/blog/2007/4/23/16/5/112b52d77b1.gif" border=0></p>
<img src ="http://www.blogjava.net/jalion/aggbug/127326.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jalion/" target="_blank">李桢</a> 2007-07-01 10:17 <a href="http://www.blogjava.net/jalion/articles/127326.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>设计模式之创建模式——工厂方法模式</title><link>http://www.blogjava.net/jalion/articles/127327.html</link><dc:creator>李桢</dc:creator><author>李桢</author><pubDate>Sun, 01 Jul 2007 02:17:00 GMT</pubDate><guid>http://www.blogjava.net/jalion/articles/127327.html</guid><wfw:comment>http://www.blogjava.net/jalion/comments/127327.html</wfw:comment><comments>http://www.blogjava.net/jalion/articles/127327.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jalion/comments/commentRss/127327.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jalion/services/trackbacks/127327.html</trackback:ping><description><![CDATA[<p>在<a href="http://jalion.blog.sohu.com/43202803.html" target=_blank><u><font color=#0000ff>上一篇</font></u></a>中学习了简单工厂模式，在简单工厂模式（Simple Factory Pattern）中，只是有限的支持了开-闭原则（一个系统的设计要求允许系统在无修改的情况下，扩展其功能）。当我们需要增加一种产品时，我们就不得不做一件很头疼的事：修改FruitsGrower类(creator)，以使他能生产出新增的产品。而接下来的工厂方法模式则是体现了java的多态性，完全符合了开闭原则。工厂方法模式的实现依赖于工厂角色和产品角色的多态性。当在某些特殊情况下，这个模式可以退化，例如退化成简单工厂模式，特征就是多态性的丧失。</p>
<p>继续水果为例：首先UML图如下：</p>
<p><img style="DISPLAY: block; MARGIN: 0px auto 10px; TEXT-ALIGN: center" height=145 alt="" src="http://img114.pp.sohu.com/images/blog/2007/4/25/12/17/112be937c48.jpg" width=500 border=0></p>
<p>源代码：</p>
<p>接口：FruitFactory</p>
<p><strong><font color=#ff0000>public interface FruitFactory {<br>&nbsp;public Fruits factory();<br>}</font><br></strong></p>
<p>接口：Fruits</p>
<p><font color=#ff0000><strong>public interface Fruits {<br>&nbsp;public void grow();<br>&nbsp;public void plant();<br>&nbsp;public void harvest();<br>&nbsp;<br>}<br></strong></font></p>
<p>类：AppleFactory</p>
<p><font color=#ff0000><strong>public class AppleFactory implements FruitFactory {</strong></font></p>
<p><font color=#ff0000><strong>&nbsp;public Fruits factory() {<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;return new Apple();<br>&nbsp;}</strong></font></p>
<p><font color=#ff0000><strong>}</strong></font><br></p>
<p>类：GrapeFactory</p>
<p><font color=#ff0000><strong>public class GrapeFactory implements FruitFactory {</strong></font></p>
<p><font color=#ff0000><strong>&nbsp;public Fruits factory() {<br>&nbsp;&nbsp;// TODO 自动生成方法存根<br>&nbsp;&nbsp;return new Grape();<br>&nbsp;}</strong></font></p>
<p><font color=#ff0000><strong>}</strong></font><br></p>
<p>类：Apple</p>
<p><font color=#ff0000><strong>public class Apple implements Fruits {</strong></font></p>
<p><font color=#ff0000><strong>&nbsp;/*<br>&nbsp; * 苹果的特有属性。苹果数的树龄<br>&nbsp; */<br>&nbsp;private int treeage;<br>&nbsp;public int getTreeage() {<br>&nbsp;&nbsp;return treeage;<br>&nbsp;}</strong></font></p>
<p><font color=#ff0000><strong>&nbsp;public void setTreeage(int treeage) {<br>&nbsp;&nbsp;this.treeage = treeage;<br>&nbsp;}</strong></font></p>
<p><font color=#ff0000><strong>&nbsp;public void grow() {<br>&nbsp;&nbsp;System.out.println("苹果的生长方法");</strong></font></p>
<p><font color=#ff0000><strong>&nbsp;}</strong></font></p>
<p><font color=#ff0000><strong>&nbsp;public void harvest() {<br>&nbsp;&nbsp;System.out.println("苹果的收获方法");</strong></font></p>
<p><font color=#ff0000><strong>&nbsp;}</strong></font></p>
<p><font color=#ff0000><strong>&nbsp;public void plant() {<br>&nbsp;&nbsp;System.out.println("苹果的种植方法");</strong></font></p>
<p><font color=#ff0000><strong>&nbsp;}</strong></font></p>
<p><br><font color=#ff0000><strong>}<br></strong></font></p>
<p><font color=#000000>类：Grape</font></p>
<p><font color=#ff0000><strong>public class Grape implements Fruits {</strong></font></p>
<p><font color=#ff0000><strong>&nbsp;public boolean seedless;<br>&nbsp;public void grow() {<br>&nbsp;&nbsp;System.out.println("葡萄的生长");</strong></font></p>
<p><font color=#ff0000><strong>&nbsp;}</strong></font></p>
<p><font color=#ff0000><strong>&nbsp;public void harvest() {<br>&nbsp;&nbsp;System.out.println("葡萄的收获");</strong></font></p>
<p><font color=#ff0000><strong>&nbsp;}</strong></font></p>
<p><font color=#ff0000><strong>&nbsp;public void plant() {<br>&nbsp;&nbsp;System.out.println("葡萄的种植");</strong></font></p>
<p><font color=#ff0000><strong>&nbsp;}</strong></font></p>
<p><font color=#ff0000><strong>&nbsp;public boolean isSeedless() {<br>&nbsp;&nbsp;return seedless;<br>&nbsp;}</strong></font></p>
<p><font color=#ff0000><strong>&nbsp;public void setSeedless(boolean seedless) {<br>&nbsp;&nbsp;this.seedless = seedless;<br>&nbsp;}</strong></font></p>
<p><font color=#ff0000><strong>}</strong></font></p>
<p>测试方法：Test.java</p>
<p><font color=#9900ff>public static void main(String args[])<br>&nbsp;{<br>&nbsp;&nbsp;FruitFactory create; //声明工厂<br>&nbsp;&nbsp;Fruits product; //声明产品<br>&nbsp;&nbsp;create=new AppleFactory();<br>&nbsp;&nbsp;&nbsp;product=create.factory();<br>&nbsp;&nbsp;&nbsp;&nbsp;product.grow(); //调用产品的方法<br>&nbsp;}&nbsp;</font></p>
<p><font color=#9900ff>&nbsp;工厂方法返回的应该是抽象类型，而不是具体类型，只有这样，才能保证多态性。当需要一个新产品时，只要创建一个产品类，一个工厂类，并实现相应的接口就OK。</font></p>
<p><strong><font color=#000000>工厂方法模式在jDK API中的 应用：</font></strong></p>
<p><font color=#9900ff></font>&nbsp;工厂方法模式在JDK中的应用到处可见，例如：Collection </p>
<p><img style="DISPLAY: block; MARGIN: 0px auto 10px; TEXT-ALIGN: center" alt="" src="http://img114.pp.sohu.com/images/blog/2007/4/25/13/23/112beeb9fc7.gif" border=0></p>
所有的实现Collection的类必须实现iteratror()方法，返回一个具体的Iterator类 
<img src ="http://www.blogjava.net/jalion/aggbug/127327.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jalion/" target="_blank">李桢</a> 2007-07-01 10:17 <a href="http://www.blogjava.net/jalion/articles/127327.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>