`
joeytang
  • 浏览: 8057 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

《JAVA与模式》之工厂方法模式

 
阅读更多
from http://www.cnblogs.com/java-my-life/archive/2012/03/25/2416227.html

在阎宏博士的《JAVA与模式》一书中开头是这样描述工厂方法模式的:

  工厂方法模式是类的创建模式,又叫做虚拟构造子(Virtual Constructor)模式或者多态性工厂(Polymorphic Factory)模式。

  工厂方法模式的用意是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类中。

那么工厂方法模式是在什么场景下使用呢,下面就以本人的理解举例说明:

  相信很多人都做过导入导出功能,就拿导出功能来说。有这么一个需求:XX系统需要支持对数据库中的员工薪资进行导出,并且支持多种格式如:HTML、CSV、PDF等,每种格式导出的结构有所不同,比如:财务跟其他人对导出薪资的HTML格式要求可能会不一样,因为财务可能需要特定的格式方便核算或其他用途。

  如果使用简单工厂模式,则工厂类必定过于臃肿。因为简单工厂模式只有一个工厂类,它需要处理所有的创建的逻辑。假如以上需求暂时只支持3种导出的格式以及2种导出的结构,那工厂类则需要6个if else来创建6种不同的类型。如果日后需求不断增加,则后果不堪设想。

  这时候就需要工厂方法模式来处理以上需求。在工厂方法模式中,核心的工厂类不再负责所有的对象的创建,而是将具体创建的工作交给子类去做。这个核心类则摇身一变,成为了一个抽象工厂角色,仅负责给出具体工厂子类必须实现的接口,而不接触哪一个类应当被实例化这种细节。

  这种进一步抽象化的结果,使这种工厂方法模式可以用来允许系统在不修改具体工厂角色的情况下引进新的产品,这一特点无疑使得工厂方法模式具有超过简单工厂模式的优越性。下面就针对以上需求设计UML图:



  从上图可以看出,这个使用的工厂方法模式的系统涉及到以下角色:



  抽象工厂(ExportFactory)角色:担任这个角色的是工厂方法模式的核心,任何在模式中创建对象的工厂类必须实现这个接口。在实际的系统中,这个角色也常常使用抽象类实现。

  具体工厂(ExportHtmlFactory、ExportPdfFactory)角色:担任这个角色的是实现了抽象工厂接口的具体JAVA类。具体工厂角色含有与业务密切相关的逻辑,并且受到使用者的调用以创建导出类(如:ExportStandardHtmlFile)。

  抽象导出(ExportFile)角色:工厂方法模式所创建的对象的超类,也就是所有导出类的共同父类或共同拥有的接口。在实际的系统中,这个角色也常常使用抽象类实现。

  具体导出(ExportStandardHtmlFile等)角色:这个角色实现了抽象导出(ExportFile)角色所声明的接口,工厂方法模式所创建的每一个对象都是某个具体导出角色的实例。

源代码
  首先是抽象工厂角色源代码。它声明了一个工厂方法,要求所有的具体工厂角色都实现这个工厂方法。参数type表示导出的格式是哪一种结构,如:导出HTML格式有两种结构,一种是标准结构,一种是财务需要的结构。

public interface ExportFactory {
    public ExportFile factory(String type);
}
  具体工厂角色类源代码:

复制代码
public class ExportHtmlFactory implements ExportFactory{

    @Override
    public ExportFile factory(String type) {
        // TODO Auto-generated method stub
        if("standard".equals(type)){
           
            return new ExportStandardHtmlFile();
           
        }else if("financial".equals(type)){
           
            return new ExportFinancialHtmlFile();
           
        }else{
            throw new RuntimeException("没有找到对象");
        }
    }

}
复制代码
复制代码
public class ExportPdfFactory implements ExportFactory {

    @Override
    public ExportFile factory(String type) {
        // TODO Auto-generated method stub
        if("standard".equals(type)){
           
            return new ExportStandardPdfFile();
           
        }else if("financial".equals(type)){
           
            return new ExportFinancialPdfFile();
           
        }else{
            throw new RuntimeException("没有找到对象");
        }
    }

}
复制代码
  抽象导出角色类源代码:

public interface ExportFile {
    public boolean export(String data);
}
  具体导出角色类源代码,通常情况下这个类会有复杂的业务逻辑。

复制代码
public class ExportFinancialHtmlFile implements ExportFile{

    @Override
    public boolean export(String data) {
        // TODO Auto-generated method stub
        /**
         * 业务逻辑
         */
        System.out.println("导出财务版HTML文件");
        return true;
    }

}
复制代码
复制代码
public class ExportFinancialPdfFile implements ExportFile{

    @Override
    public boolean export(String data) {
        // TODO Auto-generated method stub
        /**
         * 业务逻辑
         */
        System.out.println("导出财务版PDF文件");
        return true;
    }

}
复制代码
复制代码
public class ExportStandardHtmlFile implements ExportFile{

    @Override
    public boolean export(String data) {
        // TODO Auto-generated method stub
        /**
         * 业务逻辑
         */
        System.out.println("导出标准HTML文件");
        return true;
    }

}
复制代码
复制代码
public class ExportStandardPdfFile implements ExportFile {

    @Override
    public boolean export(String data) {
        // TODO Auto-generated method stub
        /**
         * 业务逻辑
         */
        System.out.println("导出标准PDF文件");
        return true;
    }

}
复制代码
客户端角色类源代码:

复制代码
public class Test {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        String data = "";
        ExportFactory exportFactory = new ExportHtmlFactory();
        ExportFile ef = exportFactory.factory("financial");
        ef.export(data);
    }

}
复制代码
工厂方法模式的活动序列图

  客户端创建ExportHtmlFactory对象,这时客户端所持有变量的静态类型为ExportFactory,而实际类型为ExportHtmlFactory。然后客户端调用ExportHtmlFactory对象的工厂方法factory(),接着后者调用ExportFinancialHtmlFile的构造子创建出导出对象。

工厂方法模式和简单工厂模式
  工厂方法模式和简单工厂模式在结构上的不同很明显。工厂方法模式的核心是一个抽象工厂类,而简单工厂模式把核心放在一个具体类上。
  工厂方法模式退化后可以变得很像简单工厂模式。设想如果非常确定一个系统只需要一个具体工厂类,那么不妨把抽象工厂类合并到具体工厂类中去。由于只有一个具体工厂类,所以不妨将工厂方法改为静态方法,这时候就得到了简单工厂模式。

  如果系统需要加入一个新的导出类型,那么所需要的就是向系统中加入一个这个导出类以及所对应的工厂类。没有必要修改客户端,也没有必要修改抽象工厂角色或者其他已有的具体工厂角色。对于增加新的导出类型而言,这个系统完全支持“开-闭原则”。
  

完结
  一个应用系统是由多人开发的,导出的功能是你实现的,但是使用者(调用这个方法的人)可能却是其他人。这时候你应该设计的足够灵活并尽可能降低两者之间的耦合度,当你修改或增加一个新的功能时,使用者不需要修改任何地方。假如你的设计不够灵活,那么将无法面对客户多变的需求。可能一个极小的需求变更,都会使你的代码结构发生改变,并导致其他使用你所提供的接口的人都要修改他们的代码。牵一处而动全身,这就使得日后这个系统将难以维护。
分享到:
评论

相关推荐

    java设计模式之工厂模式

    java设计模式之工厂模式java设计模式之工厂模式java设计模式之工厂模式java设计模式之工厂模式java设计模式之工厂模式java设计模式之工厂模式java设计模式之工厂模式java设计模式之工厂模式java设计模式之工厂模式...

    Java 工厂模式 抽象工厂 工厂方法模式

    本文将深入探讨Java中的工厂模式,包括基本的工厂模式、抽象工厂模式以及工厂方法模式。 **工厂模式**:工厂模式的核心思想是提供一个创建对象的接口,但让实现这个接口的类来决定实例化哪一个类。这样,客户端无需...

    工厂模式:简单工厂模式、工厂方法模式、抽象工厂模式

    在给定的资源中,"设计模式交流之工厂模式-shannonxu-2014-10-24.pptx"可能是详细的PPT讲解,涵盖了这些模式的概念、结构、优缺点以及实际应用案例。而"Factory"可能是一个代码示例,展示了工厂模式的具体实现,包括...

    java设计模式之工厂方法模式

    在Java中,工厂方法模式允许我们定义一个创建对象的接口,但让实现这个接口的类决定实例化哪一个类。这样,类的实例化过程就被推迟到了子类中。 工厂方法模式的核心在于抽象工厂(Abstract Factory)和具体工厂...

    java工厂方法模式

    同时,工厂方法模式也可以避免简单工厂模式的缺点,即当有新产品要加入到系统中时,必须对工厂类进行修改,以加入必要的处理逻辑。 工厂方法模式适合在如下场合中运用: * 当无法得知必须创建的对象属于哪个类的...

    工厂模式(简单工厂,普通工厂,抽象工厂)代码java

    在软件设计模式中,工厂模式是一种非常...在实际项目中,工厂模式经常与其他设计模式(如策略模式、建造者模式等)结合使用,以解决更复杂的问题。阅读并理解这些代码有助于深入理解工厂模式及其在Java编程中的应用。

    工厂方法模式java实例demo

    在这个“工厂方法模式java实例demo”中,我们可以期待看到如何在实际代码中应用这一模式。 在刘伟老师的《设计模式》一书中,他可能通过一个具体的示例解释了工厂方法模式的概念。这个例子可能涉及创建不同类型的...

    java 设计模式 mvc模式 单例模式 代理 工厂 简单工厂

    在Java中,简单工厂模式、工厂方法模式和抽象工厂模式是三种常见的实现方式。简单工厂模式虽然简单易懂,但扩展性较差,因为它将所有产品类型硬编码在工厂类中。工厂方法模式通过定义创建对象的接口,让子类决定实例...

    JAVA设计模式之工厂方法模式

    ### JAVA设计模式之工厂方法模式 #### 一、引言 设计模式是在软件工程领域内广泛应用的一种编程思想,它能够帮助开发者解决常见的软件设计问题,提高代码的可维护性和复用性。面向对象的设计模式更是现代软件开发...

    工厂方法模式Java代码

    在Java中,工厂方法模式通常用于实现“开闭原则”,即软件实体应对扩展开放,对修改关闭,这是面向对象设计的四个基本原则之一。 总结来说,工厂方法模式提供了一种灵活的创建对象的方式,使得代码更加可扩展和易于...

    Java中工厂模式案例

    在软件设计模式中,工厂模式是一种非常...通过工厂模式,我们可以将对象的创建与对象的使用分离,使得代码结构更加清晰,同时也能更好地应对需求的变化。因此,熟练掌握工厂模式对于任何Java开发者来说都是非常重要的。

    Java设计模式之工厂方法的工厂方法实现的源码

    这个Java源码示例是关于工厂方法模式的一个具体实现,特别是工厂方法的工厂方法,即二级工厂模式。 工厂方法模式的核心思想是定义一个创建对象的接口,但让子类决定实例化哪一个类。这样的好处在于隔离了类的实例化...

    java与模式之简单工厂模式

    在Java与模式之简单工厂模式中,我们首先理解其基本概念。简单工厂模式包含三个主要角色: 1. **产品接口(Product)**:定义了产品的公共接口,所有具体产品类都需要实现这个接口。 2. **具体产品(Concrete ...

    JAVA工厂模式工厂方法模式.pdf

    JAVA工厂模式工厂方法模式.pdf

    java设计模式-工厂模式

    Java设计模式中的工厂模式是一种创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,当客户端请求创建一个产品对象时,它不会直接创建,而是调用一个工厂对象来完成创建工作。这种模式的核心在于封装了对象...

    java三种工厂模式文档+三个实例.rar

    Java工厂模式是面向对象设计模式中的一个重要概念,它提供了一种创建对象的最佳方式。在工厂模式中,我们创建对象时不直接实例化具体类,而是通过一个接口或者抽象类来间接创建。这种模式的核心在于将对象的创建过程...

    Java设计模式之工厂方法的源码

    该资源是Java设计模式之工厂方法完整工程的源码,作为博主的工厂方法模式实战之某商场一次促销活动博文的源码,需要使用者结合改博文使用,该源码直接下载后就可以运行的Java工程。该工程是基于Idea+maven+...

    Java设计模式05工厂方法模式

    与简单工厂模式相比,工厂方法模式更符合“开闭原则”,即对扩展开放,对修改关闭。 在简单工厂模式中,所有的产品创建逻辑集中在单一的工厂类中,这导致了工厂类的职责过重,耦合度高,一旦需要添加新产品,就必须...

Global site tag (gtag.js) - Google Analytics