在设计模式中,Factory Method也是比较简单的一个,但应用非常广泛,EJB,RMI,COM,CORBA,Swing中都可以看到此模式的影子,它是最重要的模式之一.在很多地方我们都会看到xxxFactory这样命名的类,那么,什么是Factory Method,为什么要用这个模式,如何用Java语言来实现该模式,这就是本文想要带给大家的内容.
基本概念
FactoryMethod是一种创建性模式,它定义了一个创建对象的接口,但是却让子类来决定具体实例化哪一个类.当一个类无法预料要创建哪种类的对象或是一个类需要由子类来指定创建的对象时我们就需要用到Factory Method 模式了.简单说来,Factory Method可以根据不同的条件产生不同的实例,当然这些不同的实例通常是属于相同的类型,具有共同的父类.Factory Method把创建这些实例的具体过程封装起来了,简化了客户端的应用,也改善了程序的扩展性,使得将来可以做最小的改动就可以加入新的待创建的类. 通常我们将Factory Method作为一种标准的创建对象的方法,当发现需要更多的灵活性的时候,就开始考虑向其它创建型模式转化
我们看一个简单的例子:
原始的方式我们一般利用构造方法,去创建一个对象,但是对于构造方法而言,构造方法的名字必须与类的名字一致,这就造成了利用函数名去传递更多有意义信息的机会,比如我们有一个创建XMLconvert类
public class XMLConverter{ //创建一个缺省的 converter, Idoc Converter public XMLConverter () {}//创建一个指定的 xml parser, idoc/bapi public XMLConverter (String xmlConverterType) { }}
这个XMLConverter类有两个构造函数, 第一个构造函数创建一个缺省的XML converter.第二个构造函数可根据程序员的指定来创建一个 XML conveter.为了使用这个类,我们必须先读API文档,并且我们可能很难记住这两个构造函数各自的用途. 我们下面看看如何使用Factory解决这个问题:
public class XMLConverter () { public Converter getIdocConverter() { return new XML();}public static Converter getBapiConverter() { return new XMLConverter ("bapi");} //创建一个缺省的 converter, Idoc Converterprivate static Converter XMLConverter () {}//创建一个指定的 xml parser, idoc/bapi private XMLConverter (String xmlParserType) { }}
这个新的XMLConverter类有着两个get函数, 它们返回两个XMLConverter型的Object. 这就是典型的Factory 模式. 这两个get函数的名字清楚地告诉了我们它们各自的用途,我们不必查API文档就能明白它们的用途.请特别注意,两个构造函数都被标明为pivate.
控制在jvm中所能产生某类型Object的个数
大家知道生成一个数据库的Connection object 是一个非常影响程序速度的操作,所以"连接池'(connection pooling)是一个很常使用的技巧: 程序维持一定数量的Connection object, 以便不断的重用.这样一来就大大减少了产生和销毁Connection object所需的时间.这就要求我们能够控制最多可产生个Connection object. 下面我们看看如和用Factory 模式来解决这个问题:
import java.sql.*;import java.util.*;pulbic class ConnectionPool { private static final int NUM_OF_CONNECTION = 50; private static int counter = 0; private Vector connectionPool = new Vector(); private ConnectionPool(){}public static Connection getConnection() throws Exception{ Connection connection = null; if (connectionPool.size() < NUM_OF_CONNECTION) { connection = Class.forName("my.sql.Driver").getConnection("dbc:oracle:thin:@192.168.100.36:1521:ora9i"); connectionPool.add(connection);} else { if(conuter < NUM_OF_CONNECTION) counter++;else counter = 0; connection = (Connection)connectionPool.elementAT(counter% NUM_OF_CONNECTION );}return connection; }}
这段小程序展示了利用Factory模式保持50个Connection Object:当Connection的数量小于制定数时,我们就不断创建Connection,知道50个
Connection Object 被创建。在这之后,我们就不断的重用这些Object
下面是通过ibm developer上的一个例子来继续理解一下工厂模式
这里给出的定义:FactoryMethod是一种创建性模式,它定义了一个创建对象的接口,但是却让子类来决定具体实例化哪一个类.当一个类无法预料要创建哪种类的对象或是一个类需要由子类来指定创建的对象时我们就需要用到Factory Method 模式了.简单说来,Factory Method可以根据不同的条件产生不同的实例,当然这些不同的实例通常是属于相同的类型,具有共同的父类.Factory Method把创建这些实例的具体过程封装起来了,简化了客户端的应用,也改善了程序的扩展性,使得将来可以做最小的改动就可以加入新的待创建的类. 通常我们将Factory Method作为一种标准的创建对象的方法,当发现需要更多的灵活性的时候,就开始考虑向其它创建型模式转化
下面是工厂模式的一个类图
其中有些一些术语
1.Product需要创建的产品的抽象类
2.ConcreteProduct: Product的子类,与Product是继承的关系,代表了一系列具体的产品
3.Creator:抽象创建器的接口,生命返回Product类型对象的Factory Method
4.ConcreteCreater:具体的创建器,重写Creator中的Factory Method,返回ConcreteProduct类型的实例
图1 Factory Method的模型结构
由上面的图我们可以看到Product与Creator存在平行的关系,ConreteProduct与ConcreteCreator存在平行关系