定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
在工厂方法模式中,抽象产品类Product负责定义产品的共性,实现对事物最抽象的定义;Creator为抽象创建类,也就是抽象工厂,具体如何创建产品类是由具体的实现工厂完成的。
抽象产品类
public abstract class Product {
//产品类的公共方法
public void method1(){
//业务逻辑处理
}
//抽象方法
public abstract void method();
}
具体产品类可以有多个,都是继承自产品类。
public class ConcreteProduct1 extends Product{
@Override
public void method() {
//业务逻辑
//ToDo
}
}
public class ConcreteProduct2 extends Product{
@Override
public void method() {
//业务逻辑
//ToDo
}
}
抽象工厂类负责定义产品对象的产生。
public abstract class Creator {
/**
* 创建一个产品对象,输入参数可以自行设置
* @param c
* @param <T>
* @return
*/
public abstract <T extends Product> T createProduct(Class<T> c);
}
具体工厂类
public class ConcreteCreator extends Creator {
@Override
public <T extends Product> T createProduct(Class<T> c) {
Product product = null;
try{
product = (Product) Class.forName(c.getName()).newInstance();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return (T)product;
}
}
场景类
public class Main {
public static void main(String[] args){
Creator creator =new ConcreteCreator();
Product product = creator.createProduct(ConcreteProduct1.class);
}
}
该代码是通用代码,读者可根据实际项目进行扩展。
工厂方法模式的优点:
1)良好的封装性,代码结构清晰。
2)扩展性好。在需要增加产品类的情况下,只需要适当的修改具体的工厂类或者扩展一个工厂类,就可以拥抱变化。
3)屏蔽产品类。一个产品对象具体是哪一个产品生成是由工厂类决定的。数据库开发中就是最好的例子,如果从mysql切换到Oracle时,只需要换一下驱动名称。
4)工厂方法模式是典型的解耦框架。
工厂方法模式的扩展
1)缩小为简单工厂模式
如果一个模块只需要一个工厂类,那就没必要实例化工厂,直接使用静态方法就行了。
public class ConcreteCreator {
public static <T extends Product> T createProduct(Class<T> c) {
Product product = null;
try{
product = (Product) Class.forName(c.getName()).newInstance();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return (T)product;
}
}
该方法成为简单工厂模式,也称为静态工厂模式。
2)升级为多个工厂类
把工厂拆分,一个大工厂拆分成几个小工厂,每个产品都有对应的的创建工厂,每个创建者都独立的负责创建对应的产品对象,非常符合单一职责原则。
3)延迟初始化
一个对象被消费完毕,并不立刻释放,工厂类保持其初始状态,等待再次使用。ProductFactory负责产品类对象的创建工作,并且通过Map变量产生缓存,对需要再次被重用的对象保留。
public class ProductFactory {
private static final Map<String,Product> map = new HashMap<>();
public static synchronized Product createProduct(String type) {
Product product = null;
if(map.containsKey(type)){
product = map.get(type);
}else{
if(type.equals("product1")){
product = new Product1();
}else{
product = new Product2();
}
map.put(type,product);
}
return product;
}
}