﻿<?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/J2EEHOME/category/36243.html</link><description>One Target,One Dream</description><language>zh-cn</language><lastBuildDate>Wed, 26 Nov 2008 01:11:51 GMT</lastBuildDate><pubDate>Wed, 26 Nov 2008 01:11:51 GMT</pubDate><ttl>60</ttl><item><title>[转]Java工厂设计模式论文</title><link>http://www.blogjava.net/J2EEHOME/articles/242701.html</link><dc:creator>J2EE Home工作室</dc:creator><author>J2EE Home工作室</author><pubDate>Wed, 26 Nov 2008 00:11:00 GMT</pubDate><guid>http://www.blogjava.net/J2EEHOME/articles/242701.html</guid><wfw:comment>http://www.blogjava.net/J2EEHOME/comments/242701.html</wfw:comment><comments>http://www.blogjava.net/J2EEHOME/articles/242701.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/J2EEHOME/comments/commentRss/242701.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/J2EEHOME/services/trackbacks/242701.html</trackback:ping><description><![CDATA[<p>一. 程序设计目标</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; 我们组写了个简单的水果生产程序，描述农场种植水果的过程，旨在通过此次设计更进一步了解工程设计模式，加强编程的结构化能力。</p>
<p>&nbsp;&nbsp;&nbsp; 开发环境：JDK1.5</p>
<p>开发工具：JBuilder 2006</p>
<p>&nbsp;</p>
<p>二．程序设计介绍</p>
<p>&nbsp;</p>
<p>1.程序结构</p>
<p>&nbsp;&nbsp; 我们组为一个水果公司写了个简单的生产程序，该公司专门向市场销售各类水果。我们为程序建立了一个名为farm的工程，程序结构比较简单，总共有7个类，并且都放在一个默认的包中。其层次结构可从下图体现出来：</p>
<p><br />
对各个类的说明：</p>
<p>&nbsp;</p>
<p>Fruit类：水果接口，实现水果方法</p>
<p>Apple类：苹果类，实现Fruit接口</p>
<p>Grape类：葡萄类，实现Fruit接口</p>
<p>Strawberry类：草莓类，实现Fruit接口</p>
<p>FruitGardener类：园丁类，可种植各种水果</p>
<p>BadFruitException类：要种植的水果不在公司经营的水果范围之内，抛出种植异常</p>
<p>PlantFruit类：实现main()方法</p>
<p>&nbsp;</p>
<p>2.程序设计步骤</p>
<p>在这个系统里需要描述下列的水果：</p>
<p>葡萄 Grape</p>
<p>草莓 Strawberry</p>
<p>苹果 Apple</p>
<p>水果与其他的植物有很大的不同，就是水果最终是可以采摘食用的。那么一个自然的</p>
<p>作法就是建立一个各种水果都适用的接口，以便与农场里的其他植物区分开。如下图所示。</p>
<p>&nbsp;</p>
<p>水果接口规定出所有的水果必须实现的接口，包括任何水果类必须具备的方法：种植plant()，生长grow()以及收获harvest()。接口Fruit 的类图如下所示。</p>
<p><br />
这个水果接口的源代码如下所示。</p>
<p>&nbsp;</p>
<p>代码清单1：接口Fruit 的源代码</p>
<p>public interface Fruit {</p>
<p>// 生长</p>
<p>void grow();</p>
<p>&nbsp;</p>
<p>//收获</p>
<p>void harvest();</p>
<p>&nbsp;</p>
<p>//种植</p>
<p>void plant();</p>
<p>}描述苹果的Apple 类的源代码的类图如下所示。</p>
<p>&nbsp;</p>
<p>Apple 类是水果类的一种，因此它实现了水果接口所声明的所有方法。另外，由于苹果是多年生植物，因此多出一个treeAge 性质，描述苹果树的树龄。下面是这个苹果类的源代码。</p>
<p>&nbsp;</p>
<p>代码清单2：类Apple 的源代码</p>
<p>public class Apple</p>
<p>&nbsp;&nbsp;&nbsp; implements Fruit {</p>
<p>private int treeAge;</p>
<p>//生长</p>
<p>public void grow() {</p>
<p>&nbsp;&nbsp;&nbsp; log("Apple is growing...");</p>
<p>}</p>
<p>&nbsp;</p>
<p>// 收获</p>
<p>public void harvest() {</p>
<p>&nbsp;&nbsp;&nbsp; log("Apple has been harvested.");</p>
<p>}</p>
<p>&nbsp;</p>
<p>//种植</p>
<p>public void plant() {</p>
<p>&nbsp;&nbsp;&nbsp; log("Apple has been planted.");</p>
<p>}</p>
<p>&nbsp;</p>
<p>// 辅助方法</p>
<p>public static void log(String msg) {</p>
<p>&nbsp;&nbsp;&nbsp; System.out.println(msg);</p>
<p>}</p>
<p>&nbsp;</p>
<p>//树龄的取值方法</p>
<p>public int getTreeAge() {</p>
<p>&nbsp;&nbsp;&nbsp; return treeAge;</p>
<p>}</p>
<p>&nbsp;</p>
<p>// 树龄的赋值方法</p>
<p>public void setTreeAge(int treeAge) {</p>
<p>&nbsp;&nbsp;&nbsp; this.treeAge = treeAge;</p>
<p>}</p>
<p>}</p>
<p>同样，Grape 类是水果类的一种，也实现了Fruit 接口所声明的所有的方法。但由于葡萄分有籽和无籽两种，因此，比通常的水果多出一个seedless 性质，如下图所示。</p>
<p><br />
葡萄类的源代码如下所示。可以看出，Grape 类同样实现了水果接口，从而是水果类型的一种子类型。</p>
<p>&nbsp;</p>
<p>代码清单3：类Grape 的源代码</p>
<p>public class Grape</p>
<p>&nbsp;&nbsp;&nbsp; implements Fruit {</p>
<p>private boolean seedless;</p>
<p>//生长</p>
<p>public void grow() {</p>
<p>&nbsp;&nbsp;&nbsp; log("Grape is growing...");</p>
<p>}</p>
<p>&nbsp;</p>
<p>//收获</p>
<p>public void harvest() {</p>
<p>&nbsp;&nbsp;&nbsp; log("Grape has been harvested.");</p>
<p>}</p>
<p>&nbsp;</p>
<p>//种植</p>
<p>public void plant() {</p>
<p>&nbsp;&nbsp;&nbsp; log("Grape has been planted.");</p>
<p>}</p>
<p>&nbsp;</p>
<p>//辅助方法</p>
<p>public static void log(String msg) {</p>
<p>&nbsp;&nbsp;&nbsp; System.out.println(msg);</p>
<p>}</p>
<p>&nbsp;</p>
<p>// 有无籽的取值方法</p>
<p>public boolean getSeedless() {</p>
<p>&nbsp;&nbsp;&nbsp; return seedless;</p>
<p>}</p>
<p>&nbsp;</p>
<p>//有无籽的赋值方法</p>
<p>public void setSeedless(boolean seedless) {</p>
<p>&nbsp;&nbsp;&nbsp; this.seedless = seedless;</p>
<p>}</p>
<p>}</p>
<p>下图所示是Strawberry 类的类图。</p>
<p><br />
Strawberry 类实现了Fruit 接口，因此，也是水果类型的子类型，其源代码如下所示。</p>
<p>&nbsp;</p>
<p>代码清单4：类Strawberry 的源代码</p>
<p>public class Strawberry</p>
<p>&nbsp;&nbsp;&nbsp; implements Fruit {</p>
<p>//生长</p>
<p>public void grow() {</p>
<p>&nbsp;&nbsp;&nbsp; log("Strawberry is growing...");</p>
<p>}</p>
<p>&nbsp;</p>
<p>//收获</p>
<p>public void harvest() {</p>
<p>&nbsp;&nbsp;&nbsp; log("Strawberry has been harvested.");</p>
<p>}</p>
<p>&nbsp;</p>
<p>//种植</p>
<p>public void plant() {</p>
<p>&nbsp;&nbsp;&nbsp; log("Strawberry has been planted.");</p>
<p>}</p>
<p>&nbsp;</p>
<p>//辅助方法</p>
<p>public static void log(String msg) {</p>
<p>&nbsp;&nbsp;&nbsp; System.out.println(msg);</p>
<p>}</p>
<p>}</p>
<p>农场的园丁也是系统的一部分，自然要由一个合适的类来代表。这个类就FruitGardener 类，其结构由下面的类图描述。</p>
<p><br />
FruitGardener 类会根据客户端的要求，创建出不同的水果对象，比如苹果（Apple），葡萄（Grape）或草莓（Strawberry）的实例。而如果接到不合法的要求，FruitGardener 类会抛出BadFruitException 异常，如下图所示。</p>
<p><br />
园丁类的源代码如下所示。</p>
<p>&nbsp;</p>
<p>代码清单5：FruitGardener 类的源代码</p>
<p>public class FruitGardener {</p>
<p>//静态工厂方法</p>
<p>public static Fruit factory(String which) throws BadFruitException {</p>
<p>&nbsp;&nbsp;&nbsp; if (which.equalsIgnoreCase("apple")) {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return new Apple();</p>
<p>&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; else if (which.equalsIgnoreCase("strawberry")) {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return new Strawberry();</p>
<p>&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; else if (which.equalsIgnoreCase("grape")) {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return new Grape();</p>
<p>&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; else {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new BadFruitException("Bad fruit request");</p>
<p>&nbsp;&nbsp;&nbsp; }</p>
<p>}</p>
<p>}</p>
<p>&nbsp;</p>
<p>可以看出，园丁类提供了一个静态工厂方法。在客户端的调用下，这个方法创建客户端所需要的水果对象。如果客户端的请求是系统所不支持的，工厂方法就会抛出一个BadFruitException 异常。这个异常类的源代码如下所示。</p>
<p>&nbsp;</p>
<p>代码清单6：BadFruitException 类的源代码</p>
<p>&nbsp;</p>
<p>public class BadFruitException</p>
<p>&nbsp;&nbsp;&nbsp; extends Exception {</p>
<p>public BadFruitException(String msg) {</p>
<p>&nbsp;&nbsp;&nbsp; super(msg);</p>
<p>}</p>
<p>}</p>
<p>&nbsp;</p>
<p>在使用时，客户端只需调用FruitGardener 的静态方法factory()即可。请见下面的示意性客户端源代码。</p>
<p>&nbsp;</p>
<p>代码清单7：实现种植即Main()的实现</p>
<p>public class PlantFruit {</p>
<p>public PlantFruit() {</p>
<p>}</p>
<p>&nbsp;</p>
<p>public static void main(String[] args) {</p>
<p>&nbsp;&nbsp;&nbsp; PlantFruit plantfruit = new PlantFruit();</p>
<p>&nbsp;&nbsp;&nbsp; try {</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //种植葡萄</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FruitGardener.factory("grape").plant();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FruitGardener.factory("grape").grow();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FruitGardener.factory("grape").harvest();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("==================================");</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //种植苹果</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FruitGardener.factory("apple").plant();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FruitGardener.factory("apple").grow();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FruitGardener.factory("apple").harvest();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("==================================");</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //种植草莓</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FruitGardener.factory("strawberry").plant();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FruitGardener.factory("strawberry").grow();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FruitGardener.factory("strawberry").harvest();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("==================================");</p>
<p>&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; catch (BadFruitException e) {</p>
<p>&nbsp;&nbsp;&nbsp; }</p>
<p>}</p>
<p>}</p>
<p>到此为止，我们的简单程序已经设计完成，我们可以通过创建FruitGardener对象来完成水果的种植，无论你要种什么，只需调用对象中的factory()方法。输出结果如下：</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>三．简单工厂模式的定义</p>
<p>&nbsp;</p>
<p>简单工厂模式是类的创建模式，又叫做静态工厂方法（Static Factory Method）模式。简单工厂模式是由一个工厂对象决定创建出那一种产品类的实例。</p>
<p>&nbsp;</p>
<p>四．简单工厂模式的结构</p>
<p>&nbsp;</p>
<p>简单工厂模式是类的创建模式，这个模式的一般性结构如下图所示。</p>
<p><br />
角色与结构</p>
<p>简单工厂模式就是由一个工厂类可以根据传入的参量决定创建出哪一种产品类的实例。下图所示为以一个示意性的实现为例说明简单工厂模式的结构。</p>
<p><br />
从上图可以看出，简单工厂模式涉及到工厂角色、抽象产品角色以及具体产品角色等</p>
<p>三个角色：</p>
<p>（1）工厂类（Creator）角色：担任这个角色的是工厂方法模式的核心，含有与应用紧</p>
<p>密相关的商业逻辑。工厂类在客户端的直接调用下创建产品对象，它往往由一个</p>
<p>具体Java 类实现。</p>
<p>（2）抽象产品（Product）角色：担任这个角色的类是工厂方法模式所创建的对象的父</p>
<p>类，或它们共同拥有的接口。抽象产品角色可以用一个Java 接口或者Java 抽象类</p>
<p>实现。</p>
<p>（3）具体产品（Concrete Product）角色：工厂方法模式所创建的任何对象都是这个角</p>
<p>色的实例，具体产品角色由一个具体Java 类实现。</p>
<p>&nbsp;</p>
<p>工厂类的示意性源代码如下所示。可以看出，这个工厂方法创建了一个新的具体产品的实例并返还给调用者。</p>
<p>&nbsp;</p>
<p>代码清单8：Creator 类的源代码</p>
<p>public class Creator</p>
<p>{</p>
<p>//静态工厂方法</p>
<p>public static Product factory()</p>
<p>{</p>
<p>return new ConcreteProduct();</p>
<p>}</p>
<p>}</p>
<p>抽象产品角色的主要目的是给所有的具体产品类提供一个共同的类型，在最简单的情况下，可以简化为一个标识接口。所谓标识接口，就是没有声明任何方法的空接口。</p>
<p>&nbsp;</p>
<p>代码清单9：抽象角色Product 接口的源代码</p>
<p>public interface Product</p>
<p>{</p>
<p>}</p>
<p>&nbsp;</p>
<p>具体产品类的示意性源代码如下。</p>
<p>&nbsp;</p>
<p>代码清单10：具体产品角色ConcreteProduct 类的源代码</p>
<p>public class ConcreteProduct implements Product</p>
<p>{</p>
<p>public ConcreteProduct(){}</p>
<p>}</p>
<p>&nbsp;</p>
<p>虽然在这个简单的示意性实现里面只给出了一个具体产品类，但是在实际应用中一般都会遇到多个具体产品类的情况。</p>
<p>&nbsp;</p>
<p>五．简单工厂模式的实现</p>
<p>&nbsp;</p>
<p>1．多层次的产品结构</p>
<p>在真实的系统中，产品可以形成复杂的等级结构，比如下图所示的树状结构上就有多个抽象产品类和具体产品类。</p>
<p>&nbsp;</p>
<p>这个时候，简单工厂模式采取的是以不变应万变的策略，一律使用同一个工厂类。如下图所示。</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>图中从Factory 类到各个Product 类的虚线代表创建（依赖）关系；从Client 到其他类的联线是一般依赖关系。这样做的好处是设计简单，产品类的等级结构不会反映到工厂类中来，从而产品类的等级结构的变化也就不会影响到工厂类。但是这样做的缺点是，增加新的产品必将导致工厂类的修改。</p>
<p>&nbsp;</p>
<p>2． 使用Java 接口或者Java 抽象类</p>
<p>如果模式所产生的具体产品类彼此之间没有共同的商业逻辑，那么抽象产品角色可以由一个Java 接口扮演；相反，如果这些具体产品类彼此之间确有共同的商业逻辑，那么这些公有的逻辑就应当移到抽象角色里面，这就意味着抽象角色应当由一个抽象类扮演。在一个类型的等级结构里面，共同的代码应当尽量向上移动，以达到共享的目的，如下图所示。</p>
<p>&nbsp;</p>
<p>六．模式的优点和缺点</p>
<p>&nbsp;</p>
<p>1． 模式的优点</p>
<p>模式的核心是工厂类。这个类含有必要的判断逻辑，可以决定在什么时候创建哪一个产品类的实例。而客户端则可以免除直接创建产品对象的责任，而仅仅负责&#8220;消费&#8221;产品。简单工厂模式通过这种做法实现了对责任的分割。</p>
<p>2． 模式的缺点</p>
<p>正如同在本章前面所讨论的，当产品类有复杂的多层次等级结构时，工厂类只有它自</p>
<p>己。以不变应万变，就是模式的缺点。这个工厂类集中了所有的产品创建逻辑，形成一个无所不知的全能类，有人把这种类叫做上帝类（God Class）。如果这个全能类代表的是农场的一个具体园丁的话，那么这个园丁就需要对所有的产品负责，成了农场的关键人物，他什么时候不能正常工作了，整个农场都要受到影响。将这么多的逻辑集中放在一个类里面的另外一个缺点是，当产品类有不同的接口种类时，工厂类需要判断在什么时候创建某种产品。这种对时机的判断和对哪一种具体产品的判断逻辑混合在一起，使得系统在将来进行功能扩展时较为困难。这一缺点在工厂方法模式中得到克服。</p>
<p>由于简单工厂模式使用静态方法作为工厂方法，而静态方法无法由子类继承，因此，工厂角色无法形成基于继承的等级结构。这一缺点会在工厂方法模式中得到克服。</p>
<p>&nbsp;</p>
<p>七．个人体会&nbsp;&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; 设计模式实际上是良好的OO思想的一种提炼。每一种设计模式后面都体现了一种良好的OO思路，这些思路对于解决软件中常见的&#8220;change&#8221;问题有很大的适应性，而每种模式又有自己独特的解决思路，带有一定的通用性。而组合各种模式又可以解决许多常见问题。不可否认的是，还存在一些未经总结的设计模式。实际上，你自己也可以总结一些模式出来。无论怎样，设计模式仍然是面向对象，它不是新东西，也没有必要言必称设计模式—似乎不懂设计模式就落伍了，但给OO的开发者提供一个言简意赅的沟通桥梁。</p>
<p>设计模式告诉了我们什么是好的OO思想，思考如何更好的应用OO的思想—虽然还是那几个耳熟能详的术语：封装、继承、组合、多态。</p>
<p>设计模式首先是对传统的OO使用方法的矫正：如针对接口编程而不是实现；优先使用组合，而不是继承。其次是在原来理解上的突破：封装是对变化而言的，不仅仅是属性和方法的集合。类不仅是现实事物的抽象，同时它还具有责任。更有创新：依赖式注入。</p>
<p>模式不是万能的，也并不总能完美地解决问题，因此每种模式都包括了影响的信息。在应用模式之前，我们必须先分析问题的情境，并评估模式的影响，再决定是否采用模式，采用哪一种模式。也就是说，理解、分析模式，和实现模式一样重要</p>
<p>八．建议</p>
<p>&nbsp;&nbsp; (1)使用更加通俗易懂的语言解释设计模式，并用完整的代码实例辅以说明。代码的演示时间应延长点，好让学生看清，看懂代码。</p>
<p>&nbsp;&nbsp;&nbsp; (2)在学生需要的时候给学生补充一点java知识，有些同学专注于其他语言,对于java也不太懂，听起课来一头雾水，这时候来点知识补充还是必要的。</p>
<img src ="http://www.blogjava.net/J2EEHOME/aggbug/242701.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/J2EEHOME/" target="_blank">J2EE Home工作室</a> 2008-11-26 08:11 <a href="http://www.blogjava.net/J2EEHOME/articles/242701.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>浅谈DAO工厂设计模式</title><link>http://www.blogjava.net/J2EEHOME/articles/242699.html</link><dc:creator>J2EE Home工作室</dc:creator><author>J2EE Home工作室</author><pubDate>Wed, 26 Nov 2008 00:01:00 GMT</pubDate><guid>http://www.blogjava.net/J2EEHOME/articles/242699.html</guid><wfw:comment>http://www.blogjava.net/J2EEHOME/comments/242699.html</wfw:comment><comments>http://www.blogjava.net/J2EEHOME/articles/242699.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/J2EEHOME/comments/commentRss/242699.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/J2EEHOME/services/trackbacks/242699.html</trackback:ping><description><![CDATA[随着软件分层设计的流行及广泛的应用，对于DAO的设计模式大家已经不再陌生了，DAO层已经在软件系统的开发中成为必不可少的一层，将后台的数据层和前台的VO进行分离。前段时间也针对于DAO的设计介绍过一个基于Hibernate的泛型DAO的设计。 <br />
csdn blog：http://blog.csdn.net/yongtree/archive/2008/03/12/2172071.aspx <br />
javaeye blog：http://yongtree.javaeye.com/blog/170449 <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 通过DAO的设计的确可以让我们的软件系统已经将数据层和表现层进行了简单的分离，让我们系统各层次的功能更加的清晰。所以我们开始洋洋得意了，DAO的引入让系统的耦合性更加的松散，表现层再也不需要关心后台数据操作的变化了。于是我们开始高枕无忧了，我们肆无忌惮的在表现层通过调用DAO来实现我们的系统了。事实真的如此吗？那我们就举个例子来看看我们的系统是否真的具有解偶的能力了。 <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 现在我们有个员工管理系统，在该系统中，Person.java表示员工这个对象，它对应着数据库中的person表。还有用于操作Person对象的DAO接口—PersonDAO.java，还有一个PersonDAO的实现类PersonDAOImpl.java。在PersonDAOImpl.java中我们实现了操作Person对象的所有的方法。我们很自豪的说，看我们已经把操作封装在PersonDAO中了，现在我们可以在表现层（jsp，或者VO操作类中）使用PersonDAO personDAO=new PersonDAOImpl()来调用DAO操作我们的数据对象了。当我们陶醉于自己写的优美的代码的时候，项目经理来通知了，由于使用Hibernate的效率偏低，客户开始不满了，还是让我们重新用JDBC再重写一遍吧。于是所有DAO的Hibernate实现开始全部转换成JDBC实现。但是项目经理建议不要破坏现有的Hibernate实现，以后可以通过技术研究来提升Hibernate的访问效率。于是我们开始写了又写了一套JDBC的实现—PersonDAOJDBCImpl.java，现在问题出来了，表现层大量的使用了PersonDAO personDAO=new PersonDAOImpl()，全部改成new PersonDAOJDBCImpl()谈何容易，我们是不是开始欲哭无泪了。 <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 怎么解决类似的问题呢？于是我们开始引进工厂模式。我们建立一个类DaoFactory.java对DAO进行统一管理。 <br />
DaoFactory.java: <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public class DaoFactory{ <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static PersonDAO getPersonDAOInstance() <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return new PersonDAOImpl() ; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //得到其他的DAO实例 <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8230;&#8230; <br />
} <br />
表现层通过PersonDAO personDAO=DaoFactory.get getPersonDAOInstance();来实例化DAO实例。这样问题就解决了，DAO改变了，我们只需要在DAO工厂类中修改一下代码：return new PersonDAOJDBCImpl() ;那我们的应用就快速切换到JDBC实现了。可见利用工厂模式，我们的系统又进一步的解耦，表现层真的无需再关系DAO层的变化了，一切交给DAO工厂来解决。 <br />
使用过Spring这样框架的开发人员都知道，Spring通过利用IoC来实现类之间的解耦。其实在DAO工厂中我们也可以简单的借鉴一下IoC的思想，更进一步解除类之间的耦合。Spring是通过配置xml文件来进行IoC的，那么我们也可以借助于xml文件来实现。比如下面的xml： <br />
&lt;?xml version="1.0"?&gt; <br />
&lt;config&gt; <br />
&nbsp;&nbsp;&nbsp; &lt;daos&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;!-- 组织机构服务接口实现类 --&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;dao id="organizationService" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; type="com.baiyyy.oa.services.organization.OrganizationServiceImpl"&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/dao&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;!-- 工作流参与者接口 --&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;dao id="participantService" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; type="com.baiyyy.workflow.services.impl.ParticipantServiceImpl"&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/dao&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;!-- 工作流定义接口 --&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;dao id="processDefinitionService" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; type="com.baiyyy.workflow.services.impl.ProcessDefinitionServiceImpl"&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/dao&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;!-- 工作流实例接口 --&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;dao id="processInstanceService" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; type="com.baiyyy.workflow.services.impl.ProcessInstanceServiceImpl"&gt; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/dao&gt; <br />
&nbsp;&nbsp;&nbsp; &lt;/daos&gt; <br />
&lt;/config&gt; <br />
这是我设计实现的工作流系统给业务系统提供的接口所配置的xml，所有的接口都配置在xml中，我们怎么使用呢？我只不过是把DAO工厂进行进一步的改进，通过ProcessInstanceService processInstanceService=DaoFactory.getDao(ProcessInstanceService.class,&#8221; processInstanceService&#8221;);从传入的参数我们可以看出，我们清楚的知道要调用的接口ProcessInstanceService，同时通过字符串&#8221; processInstanceService&#8221;，我们可以解析上面的配置文件，得到具体实现类的路径，通过反射得到该实现类的实例。具体的DAO工厂类的实现，朋友们有兴趣可以自己去实现，我就不详细介绍了。 <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 终于写完了，以上便是对DAO工厂一些浅显的理解。现在正在学习设计模式，以后会根据自己的所学所思，介绍自己对各个设计模式的理解，希望大家一块学习讨论。 <br />
<img src ="http://www.blogjava.net/J2EEHOME/aggbug/242699.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/J2EEHOME/" target="_blank">J2EE Home工作室</a> 2008-11-26 08:01 <a href="http://www.blogjava.net/J2EEHOME/articles/242699.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>