工厂模式用于创建对象,根据不同的结构形式又可分为简单工厂模式,工厂方法模式和抽象工厂模式。
简单工厂模式(Simple Factory) ,又叫静态工厂模式。
顾名思义,就是提供一个静态方法来封装对象的实例化,目的是为了隐藏实例化过程而不让客户端直接掉调用构造函数或者无法通过构造函数来实现实例化(抽象类)。示例代码如下:
class FooSimpleFactory{ public static Foo createFoo(){ return new FooImpl(); } } abstract class Foo{ } class FooImpl extends Foo{ public FooImpl(){} }
如果将工厂类和需创建对象类合二为一,会变成什么样子呢?
abstract class Foo{ public static Foo create(){ return new FooImpl(); } } class FooImpl extends Foo{ public FooImpl(){} }
是不是屏蔽了实例化的过程啊。相信读过java源码的童鞋一定发现了,DateFormat.getDateInstance()就是简单工厂模式。
让我们再把抽象类去掉,换成具体类,然后给一个私有的构造函数,是不是同样可以隐藏实例化过程呢,示例代码如下:
class Foo{ private Foo(){} public static Foo create(){ retirm mew Foo(); } }
细心的读者一定发现跟另外一个设计模式很像,对了,就是单例模式。
工厂方法模式(Factory Method) , 又叫虚拟构造子(Virtual Constructor)模式或者多态性工厂(Polymorphic Factory)模式。
实现方式是通过定义一个工厂接口,目的是为了将实例化过程推迟到之类中。示例代码如下:
interface FooFactory{ public Foo create(); } class FooFactoryImpl implements FooFactory{ public Foo create(){ return new FooImpl(); } } abstract class Foo{} class FooImpl extends Foo{ public FooImpl(){} } abstract class
java源码中,工厂方法模式的例子很多,比如Collection.iterator()方法,URL.openConnection()方法。
让我们把示例代码稍微改一下,将工厂类和需创建对象类合二为一,结果怎么样呢?
abstract Foo(){ public Foo create(){ initilize(); } public abstract Foo initialize(){} } class FooImpl extends Foo{ public FooImpl(){} public Foo initialize(){ return new FooImpl(); } }
相信细心的读者一定可以发现,这里除了是工厂方法模式之外,还有另一个设计模式,就是模板方法模式。谁说模板方法模式不可以同时是一个工厂方法模式呢?
抽象工厂模式(Abstract Factory) , 工厂方法模式用于支持一个抽象产品等级结构的对象实例化,而抽象工厂模式用于支持多个抽象产品等级结构的对象实例化。那么为什么不采用多个工厂方法模式来实现呢,理论上可行,但是却会多出来很多的工厂类结构,于是抽象工厂模式就派上用场了。我们可以把多个抽象产品等级下的产品归类,就会发现,很多产品其实是属于同一个类型,虽然他们处于不同的产品等级结构中,这时候我们没有必要增加工厂类来实例化不同的产品等级结构下的同一个类型的产品,而是直接用同一个工厂方法来创建所有的同一类型的产品。
示例代码如下:
interface Factory{ Foo createFoo(); Product createProduct(); } class FactoryImpl1 implements Factory{ Foo createFoo(){return new Foo1();} Product createProduct(){return new Product1();} } class FactoryImpl2 implements Factory{ Foo createFoo(){return new Foo2();} Product createProduct(){return new Product2();} } interface Foo{} class Foo1 implements Foo{} class Foo2 implements Foo{} interface Product{} class Product1 implements Product{} class Product2 implements Product{}
java源码中,Toolkit就是一个很著名的抽象工厂模式的例子,实现了对Windows/Mac/Unix等不同平台的支持。