本文接 Java设计模式之工厂模式(简单工厂模式)。
工厂方法模式又称虚拟构造函数模式或多态性工厂模式。 意为定义一个创建产品对象的共产接口,将实际创建性工作推迟到子类中。
定义
定义一个用于创建对象的接口,让子类决定实例化哪个类。工厂方法使一个类的实例化延迟到其子类。
角色
抽象工厂
抽象工厂角色是工厂方法的核心接口,所有创建对象的工厂类都必须实现该接口。
具体工厂
具体工厂角色实现了抽象工厂,含有与应用密切相关的逻辑,并且受到应用程序的调用来创建产品。
抽象产品
抽象产品角色负责定义产品的共性,实现对产品的最抽象定义。
具体产品
具体产品角色实现抽象产品角色所声明的接口具体工厂角色创建的每一个对象,都是某个具体产品角色的实例。
代码实现
同样还是以华为系列的手机为例。
定义抽象工厂
/**
* 类名 Factory
* 描述 抽象工厂
*
* @Author dgjava.com
* @Date 2020/5/6 14:09
* @Version 1.0
**/
public interface Factory {
/**
* 抽象工厂方法,对外暴露的工厂方法
* 根据该方法获取具体工厂再生产具体产品
* @param c
* @param
* @return
*/
T factory(Class c);
}
顶层的抽象共产接口,对外暴露。
实现具体工厂
/**
* 类名 PhoneFactory
* 描述 具体工厂-手机工厂
*
* @Author: dgjava.com
* @Date: 2020/5/1 5:41 PM
*/
@Slf4j
public class PhoneFactory implements Factory {
@Override
public T factory(Class c) {
Product product = null;
try {
product = (Product) Class.forName(c.getName()).newInstance();
} catch (Exception e) {
log.error("获取产品实例异常。", e);
}
return (T) product;
}
}
我们以华为手机为例,这里就定义一个手机工厂来具体实现我们的抽象工厂,华为系列产品不仅有手机,还有其他很多产品,手机只是其一。
定义抽象产品
/**
* 类名 Product
* 描述 抽象产品
*
* @Author dgjava.com
* @Date 2020/5/6 14:09
* @Version 1.0
**/
public interface Product {
Phone createPhone();
void doSomeThing();
}
实现具体产品
华为手机产品
/**
* 类名 HuaWeiProduct
* 描述 具体产品:生产华为手机
*
* @Author dgjava.com
* @Date 2020/5/6 14:21
* @Version 1.0
**/
@Slf4j
public class HuaWeiProduct implements Product{
@Override
public Phone createPhone() {
return new HuaWei();
}
@Override
public void doSomeThing() {
log.info("生产华为手机");
}
}
荣耀手机产品
/**
* 类名 RongYaoProduct
* 描述 具体产品:生产荣耀手机
*
* @Author dgjava.com
* @Date 2020/5/6 14:22
* @Version 1.0
**/
@Slf4j
public class RongYaoProduct implements Product {
@Override
public Phone createPhone() {
return new RongYao();
}
@Override
public void doSomeThing() {
log.info("生产荣耀手机");
}
}
测试代码
public static void main(String[] args) {
Factory factory = new PhoneFactory();
//此处product可以直接用 HuaWeiProduct 来实现
//但是这样工厂方法就失效了,我们对外暴露的只是工厂接口
Product product = factory.factory(HuaWeiProduct.class);
Phone phone = product.createPhone();
System.out.println(phone.getBrand());
product.doSomeThing();
}
输出结果
优点
良好的封装性
可扩展性
屏蔽产品类
框架解耦
应用场景
工厂犯法模式在实际项目开发过程中有很多的应用场景,很多优秀的开源框架中都能看到工厂模式的身影。当存在如下场景时,可以考虑使用工厂模式:
需要生成对象的地方,通过工厂模式统一处理;
需要灵活、可扩展的框架;
需要异构框架,兼容不同系统差异;
比如webService项目和非Java项目交互。
测试驱动的开发框架;
比如需要测试对象A,依赖关联的对象B,这个时候可以使用工厂模式生产对象B,用于和对象A解耦。