工厂模式可以分为三类
1)简单工厂模式(simple factory)
2)工厂方法模式(factory method)
3)抽象工厂模式(abstract factory)'
简单工厂模式
简单工厂模式又称为静态方法工厂模式。一个模块仅需要一个工厂类,这个具体的工厂类实例处于产品类实例化的中心位置上,它决定具体的哪一个产品类要被实例化,被创建的产品实例类通常都=具有相同的父类。
下面是模式中包含的角色及其职责
1.工厂角色(creator)角色
简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类可以直接被外界所调用,创建所需的产品对象。
2.抽象(Product)角色
简单工厂模式所创建的对象的父类,它负责描述所有实例所公有的公共接口
3.具体产品(Concrete Product)角色
简单工厂模式所创建的所有实例对象
这是一个简单工厂的例子,Apple和Banana为Fruit接口的两个具体实例,我们通过FruitFactory这一实例工厂来产生Fruit的子类。
package cn.java.simplefactory;
public interface Fruit {
public void get();
}
这是Fruit接口类。
package cn.java.simplefactory;
public class Apple implements Fruit {
@Override
public void get() {
// TODO Auto-generated method stub
System.out.println("采集苹果");
}
}
package cn.java.simplefactory;
public class Banana implements Fruit {
@Override
public void get() {
// TODO Auto-generated method stub
System.out.println("采集香蕉");
}
}
上面两个是具体的子类。
package cn.java.simplefactory;
public class FruitFactory {
public static Fruit getFruit(String type){
if(type.equalsIgnoreCase("Apple")){
return new Apple();
}else if(type.equalsIgnoreCase("Banana")){
return new Banana();
}
throw new RuntimeException("获取水果错误");
}
}
这是工厂实例类。
优点:
由于工厂实例类是这个的关键所在,它里面包含创建具体的产品实例的判断逻辑,根据外界给定的信息从而创建对应的产品实例,用户无需关心创建具体实例的过程与细节,主需要面向工厂类即可,有利于整个软件体系结构的优化。
缺点:
随着具体的产品实例的增加,我们势必要对工厂实例的内部逻辑进行修改,这样就会破坏封装这一特性。
工厂方法模式
工厂方法模式同样属于类的创建型模式,又被称为多态工厂模式。工厂方法模式的定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例延迟到其子类。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口。这样进一步的抽象化的好处是使得工厂方法模式可以在不修改具体工厂角色的情况下引进新产品。
1.抽象工厂(Creator)角色
工厂方法模式的核心,任何工厂类都要实现这个接口
2.具体工厂角色(Concrete Creator)角色
具体工厂类是抽象工厂的一个实现,负责实例化产品对象
3.抽象(Product)角色
工厂方法模式所创建的所有对象的父类,它负责描述所有实例公有的公共接口。
4.具体产品(Concrete Product)角色
工厂方法模式所创建的具体实例对象
package cn.java.factorymethod;
public abstract class Product {
//产品类的公共方法
public void method1(){
//业务逻辑处理
}
//抽象方法,留待具体的子类实现
public abstract void method2();
}
具体的产品类可以有多个,窦继承与抽象产品类。
package cn.java.factorymethod;
public class ConcreteProduct1 extends Product {
@Override
public void method2() {
//业务逻辑处理
}
}
package cn.java.factorymethod;
public class ConcreteProduct2 extends Product {
@Override
public void method2() {
// 业务逻辑处理
}
}
package cn.java.factorymethod;
public class ConcreteProduct2 extends Product {
@Override
public void method2() {
// 业务逻辑处理
}
}
上面的抽象工厂类负责产品对象的产生,具体的由其实现的子类工厂类来产生产品。
package cn.java.factorymethod;
public abstract class Creator {
public abstract <T extends Product> T createProduct(Class<T> clazz);
}
package cn.java.factorymethod;
public class ConcreteCreator extends Creator {
@Override
public <T extends Product> T createProduct(Class<T> clazz) {
Product product =null;
try {
return clazz.newInstance();
} catch (Exception e) {
//一场处理
}
return (T) product;
}
}
package cn.java.factorymethod;
public class Client2 {
public static void main(String[] args) {
Creator c= new ConcreteCreator();
c.createProduct(ConcreteProduct1.class);
/*
* 继续业务逻辑
*/
}
}
下面是一个具体的例子
通过抽象工厂的具体子类工厂来负责产生具体的产品,这样在添加新产品时,无需像简单工厂一样需要去实例工厂类修改判断逻辑代码,只需要按照抽象工厂类和产品接口的规范去新建实例就可以了。但是随着新增的产品类越来越多,就会出现大量的工厂实例。
上面的产品接口和具体产品的类代码跟简单工厂一样,新增了抽象工厂类和其具体的子类工厂实例。
package cn.java.factorymethod;
public abstract class AbstractFactory {
public abstract Fruit fruitCreate();
}
具体的产品的生产交给抽象工厂类的实例,这样代码结构比较清晰。
package cn.java.factorymethod;
public class AppleFactory extends AbstractFactory {
//苹果工厂实例生产苹果
@Override
public Fruit fruitCreate() {
return new Apple();
}
}
package cn.java.factorymethod;
public class Pear implements Fruit {
//梨子工厂实例生产梨子
@Override
public void get() {
System.out.println("采集梨子");
}
}
package cn.java.factorymethod;
public class Banana implements Fruit {
@Override
public void get() {
// TODO Auto-generated method stub
System.out.println("采集香蕉");
}
}
下面是一个场景类
package cn.java.factorymethod;
public class Client {
public static void main(String[] args) {
AbstractFactory factory = new PearFactory();
Fruit f = factory.fruitCreate();
f.get();
}
}
如果需要在客户端生产不同的产品,只需实例化一个新的具体工厂类即可。
工厂方法模式与简单工厂模式的比较:
简单工厂模式的核心是具体的工厂实例类,它负责所有产品的产生,但是在需要新添加产时,需要破坏封装特性去修改内部逻辑代码。工厂方法模式有叫多态性工厂模式,通过核心的抽象工厂类来实例化具体负责生产哪种产品的实例工厂,把对产品的实例化延迟到了具体子类中去,这样新增产品时,就无需对具体的工厂实例进行逻辑判断修改,是对多个简单工厂模式的综合,是简单工厂模式的一种推广。
反过来说,当系统中确定只需要一个实例工厂时,简单工厂模式是工厂方法模式的退化。工厂方法模式随着系统中产品子类的不断增加,也会随之增加大量的工厂类,所以需要具体的选择哪种工厂模式。
工厂方法有很多的变种,我们可以通过工厂方法模式获取单例。
package cn.java.dp.singlefactory;
public class Single {
private Single(){}
public void doSomething(){
System.out.println("处理业务逻辑");
}
<strong>}
</strong>
单例的工厂类
package cn.java.dp.singlefactory;
import java.lang.reflect.Constructor;
public class SingleFactory {
private static Single single = null;
static{
try {
Constructor<Single> constructor = Single.class.getDeclaredConstructor();
constructor.setAccessible(true);
single =(Single) constructor.newInstance();
} catch (Exception e) {
}
}
public static Single getSingle(){
return single;
}
}
通过反射获取构造器初始化。
延迟初始化
一个对象被消费完后,并不立即释放,工厂类保持其初始状态,等待其再次被调用。延迟初始化时工厂模式的一个扩展,通用类图如下。
一个对象被消费完后,并不立即释放,工厂类保持其初始状态,等待其再次被调用。延迟初始化时工厂模式的一个扩展,通用类图如下。
ProductFactory负责类对象的创建工作,并且通过prMap变量产生一个缓存,对需要再次使用的变量进行保存。具体代码实现如下
package cn.java.dp.lazyinitialization;
import java.util.HashMap;
import java.util.Map;
public class ProductFactory {
private static Map<String, Product> map = new HashMap();
public synchronized static Product productCreate(String type) {
Product product =null;
if (map.containsKey(type))
return map.get(type);
if (type.equals("ConcreteProduct"))
product = new ConcreteProduct();
if (type.equals("ConcreteProductA"))
product =new ConcreteProductA();
map.put(type, product);
return product;
}
}
延迟加载时可以扩展的,例如限制某一个类的最大实例化数量,可以通过判断Map中已有对象的数量来实现,例如JDBC连接数据库,都会要求设置一个MaxConnections最大连接数量,该数量就是内存中最大实例化数量。
抽象工厂模式
当我们有多个业务品种,业务分类时,工厂方法就不适合产生系列产品,这时候我们就需要抽象工厂模式,通过在抽象工厂类中添加一系列产品簇的方式来生产多种产品。抽象工厂模式是工厂方法模式的纵向扩展。
下面是模式中包含的角色和职责
1.抽象工厂(Creator)
抽象工厂模式的核心,包含对多个产品结构的声明,任何工厂类必须实现这个接口。
2.具体工厂(Concrete Creator)角色
具体工厂类是抽象工厂的一个实现,负责实例化某个产品族中的产品对象。
3.抽象角色(Product)
抽象模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口
4.具体产品(Creator Product)角色
抽象模式所创建的具体实例对象
抽象工厂中方法对应产品具体结构,具体共产对应产品族
下面是通用源码类图
抽象产品类
<pre name="code" class="html">package cn.java.gereral.abstractfactory;
public abstract class AbstractProductA {
//每个产品公有的方法
public void shareMethod(){
}
//每个产品相同方法,不同实现
public abstract void doSomething();
}
具体产品A1的实现
<pre name="code" class="html">package cn.java.gereral.abstractfactory;
public class ProductA1 extends AbstractProductA {
@Override
public void doSomething() {
// TODO Auto-generated method stub
System.out.println("A1的实现方法");
}
}
具体产品A2的实现
package cn.java.gereral.abstractfactory;
public class ProductA2 extends AbstractProductA {
@Override
public void doSomething() {
// TODO Auto-generated method stub
System.out.println("产品A2的实现方法");
}
}
产品B类似,不在赘述。
<strong>抽象工厂类</strong>
<pre name="code" class="html"><pre name="code" class="html"><pre name="code" class="html">package cn.java.gereral.abstractfactory;
public abstract class AbstractCreator {
//创建产品A家族
public abstract AbstractProductA createProductA();
public abstract AbstractProductB createProductB();
}
产品等级1的实现
package cn.java.gereral.abstractfactory;
public class Creator1 extends AbstractCreator{
//只生产产平等级为1的产品
@Override
public AbstractProductA createProductA() {
return new ProductA1();
}
@Override
public AbstractProductB createProductB() {
return new ProductB1();
}
}<strong>
</strong>
产品等级2的实现
<pre name="code" class="html">package cn.java.gereral.abstractfactory;
public class Creator extends AbstractCreator {
@Override
public AbstractProductA createProductA() {
return new ProductA2();
}
@Override
public AbstractProductB createProductB() {
return new ProductB2();
}
}<strong>
</strong>
有m个产品等级就有M个实现工厂,在每个工厂中实现同一产品族的生产。
下面是场景类
<pre name="code" class="html">package cn.java.gereral.abstractfactory;
public class Client {
public static void main(String[] args) {
AbstractCreator creator1 = new Creator();
AbstractCreator creator2 =new Creator1();
//产生A1对象
AbstractProductA a1 = creator1.createProductA();
//产生A2对象
AbstractProductA a2 = creator2.createProductA();
//产生B1对象
AbstractProductB b1= creator1.createProductB();
//产生B2对象
AbstractProductB b2 =creator2.createProductB();
/*
* 执行具体的业务逻辑
*/
}
}