Java设计模式之工厂模式

12年前

Java设计模式之工厂模式

工厂模式的几种形态:

首先,工厂模式是做什么的呢?

工厂模式专门负责将大量有共同接口的类实例化.工厂模式可以动态决定哪一个类实例化,而不必事先知道每次要实例化哪个类.

了解了工厂模式之后,我们可以总结一下工厂模式有哪几种形态.

1,简单工厂模式(静态工厂模式).

2,工厂方法模式(多态性工厂,虚拟构造器模式)

3,抽象工厂模式(工具箱模式)

一下逐一介绍这三种工厂模式,并讨论他们的优缺点.

简单工厂模式:

一下是简单工厂模式的简单类图.

一下我们类介绍一下简单工厂模式的结构.

首先我们应该明白一点:简单工厂模式是类的创建模式,这个模式的一般性结构如图所示.

简单工厂模式是由一个工厂类根据传入的参数决定创建哪种类型的产品的实例.一下以示意性的实现为例说明简单工厂模式的结构.

从图中可以看出:简单工厂模式涉及到的角色有:

工厂类角色(Creator):工厂类角色是简单工厂模式的核心,包含和应用紧密相连的商业逻辑.工厂类在客户端的调用下创建产品对象.他往往有一个具体的java类实现.

抽象产品角色(Product):担任这个角色的类是由工厂方法模式所创建的对象的父类.或者是他们共有的接口.抽象产品角色可以用一个java接口或者java抽象类实现.

抽象产品角色的主要目的是给所有的具体产品类提供一个共同的类型.在最简单的情况下,可以简化为一个表示接口.

既然接口和抽象类都可以实现抽象产品角色,那么用哪个更合适呢.或者说用在什么情况下用接口,在什么情况下用抽象类呢.

总结:如果模式所产生的具体产品类彼此之间没有共同的商业逻辑,那么抽象产品角色可以有一个java接口扮演,相反,如果这些具体类产品彼此之间确实有共同的商业逻辑,那么这些共有的逻辑就应该移动到抽象角色里.这就意味这抽象角色应当有一个抽象类扮演.

具体产品角色(Concrete Product):工厂方法模式所创建的任何对象都是这个角色的实例.具体产品角色有一个java类实现.

注意:

1,在一个工厂类中可以存在多个工厂方法.每个工厂类可以有一个或者多个工厂方法,分别负责创建不同类型的产品对象.再有就是如果,整个系统中仅有一个具体产品角色的话,那么就可以省略掉抽象产品角色.

2,在某些特殊的情况下,工厂角色与抽象产品角色也可以合并.典型的应用就是java.text.DateFormat.一个抽象产品类同时是子类的工厂.

3,更有甚者啊.在某些更特殊的情况下,如果抽象产品角色已经被省略,而工厂角色还可以与具体产品角色合并.换言之产品类自产自销,自己产生自己的实例.

就想上图一样.

我里个去啊!!这听起来怎么就这么熟悉呢.怎么就这么像单例模式和多例模式啊.

好了,简单工厂模式是设计模式中最简单的模式之一,但是也是最根本的设计模式之一

下面我们就来看看简单工厂模式和其他模式之间的关系.

单例模式:单例模式使用了简单工厂模式.单例类具有一个静态工厂方法提供自身的实例.一个抽象产品类同时也是子类的工厂.

但是单例模式有不仅仅是简单工厂模式的退化情形,单例模式要求单例类的构造器私有.单例类使用一个静态的属性存储自己的唯一的实例,工厂方法永远仅提供这一个实例.

多例模式:多例模式是对单例模式的推广.他们的共同之处都是禁止外界直接实例化.同时静态工厂方法向外界提供循环使用的自身的实例.不同之处是单例模式仅有一个实例,而多例模式可以有多个实例.

多例模式往往有一个聚集属性,通过这个聚集属性登记已经创建过的实例达到循环使用实例的目的.一般而言,一个典型的多例类具有某种内部状态,这个内部状态可以用来区分各个实例.而对应于每个每一个内部状态,都只有一个实例存在.

备忘录模式:单例模式和多例模式使用一个属性或者聚集属性类登记所创建的产品对象,以便可以通过查询这个属性或者聚集属性来找到并共享已经创建了的产品对象,这就是备忘录模式的应用.备忘录模式的简略类图如下.

好了,简单工厂模式的基础知识大概也就这和门些了,来总结一下简单工厂模式的优缺点吧

优点:简单工厂模式的核心是工厂类.这个类包含必要的判断逻辑.可以决定在什么时间创建类的实例.那么客户端就可以避免直接创建类的实例的责任.而仅仅负责消费产品.简单工厂模式同个这种方法实现了对责任的分割.

缺点:当产品类有复杂的错层次等级结构的时候.工厂类只有它自己,以不变应万变.显的力不从心.工厂类中聚集了所有产品的创建逻辑形成了一个无所不能的上帝类.当上帝类忽然不能工作了,那么整个系统也就不能工作了.另外,当产品类有不同的借口种类时,工厂类需要判断在什么时间创建某种产品.这种对时机的判断和对哪一种产品的普安段逻辑混合在一起.使得系统在将来惊醒功能的宽肩较为困难.

最后总结一下,简单工厂模式在java中的应用吧.

java.date.DataFormat

SAX2库中的XMLRraderFactory