一、概述
定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂模式使一个类的实例化延迟到其子类。
简单工厂模式:又叫做静态工厂方法模式,是由一个工厂对象决定创建出哪一种产品类的实例。
二、适用性
1.当一个类不知道它所必须创建的对象的类的时候。
2.当一个类希望由它的子类来指定它所创建的对象的时候。
3.当类将创建对象的职责委托给多个帮助子类中的某一个,并且希望将哪一个帮助子类是代理者这一信息局部化的时候。
三、参与者
1.Product定义工厂方法所创建的对象的接口或抽象类。
2.ProductA和ProductB实现Product接口。
3.Factory工厂类声明工厂方法,该方法返回一个Product类型的对象。 Factory也可以定义一个工厂方法的缺省实现,它返回一个缺省的Product对象。 它负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法createProduct()可以被外界直接调用,创建所需的产品对象。
4.Client客户端,调用工厂类的createProduct()方法来创建产品实例。
四、类图
五、示例
Product接口或抽象类
public abstract class Product {
protected abstract void work();
}
public interface Product {
void work();
}
TeacherWork
public class TeacherWork extends Product {
@Override
protected void work() {
System.out.println("老师审批作业!");
}
}
StudentWork
public class StudentWork extends Product {
@Override
protected void work() {
System.out.println("学生做作业!");
}
}
SimpleFactory
public class SimpleFactory {
public Product create(String type) {
Product product = null;
if (type.equals("teacher")) {
product = new TeacherWork();
} else if (type.equals("student")) {
product = new StudentWork();
}
return product;
}
}
Test
@Test
public void test(){
SimpleFactory simple = new SimpleFactory();
Product product = simple.create("student");
product.work();
}
测试结果
Connected to the target VM, address: '127.0.0.1:1742', transport: 'socket'
学生做作业!
Disconnected from the target VM, address: '127.0.0.1:1742', transport: 'socket'
六、实践
订阅调用工厂
/**
* 消息订阅
*/
private void messageSubscription(Map<String, Object> map) {
asyncEventBus.register(new FxListenerFactory());
asyncEventBus.post(map);
}
工厂
/**
* @author lyonardo
* @Description
* @createTime 2022年11月21日 15:24:00
*/
@Slf4j
@Service
public class FxListenerFactory {
private final FxProductObjListener fxProductObjListener = SpringUtil.getBean(FxProductObjListener.class);
private final FxBomObjListener fxBomObjListener = SpringUtil.getBean(FxBomObjListener.class);
......
@Subscribe
public void send(Map<String, Object> map) {
if (MapUtils.isEmpty(map)) {
log.error("可售客户没有推送消息");
return;
}
String json = String.valueOf(map.get("json"));
log.info("json::"+json);
JSONObject jsonObject = JSON.parseObject(json);
String eventType = String.valueOf(jsonObject.get("eventType"));
String apiName = String.valueOf(jsonObject.get("apiName"));
String dataId = String.valueOf(jsonObject.get("dataId"));
switch (apiName){
case DataObjectApiNameConstants.PRODUCTOBJ : fxProductObjListener.handle(eventType,dataId);break;
case DataObjectApiNameConstants.BOMOBJ : fxBomObjListener.handle(eventType,dataId);break;
......
default: throw new OsRuntimeException(FailCodeEnum.FAIL.getCode(), "没有该订阅对象");
}
}
FxProductObjListener
/**
* @author lyonardo
* @Description 纷享销客商品
* @createTime 2022年07月11日 19:59:00
*/
@Slf4j
@Service
public class FxProductObjListener extends FxBaseListenerAbstract<BaseTlkSuperEntityDO, FxProductInfoBO>{
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public void handle(String eventType, String dataId) {
...
}
@Override
protected BaseTlkSuperEntityDO getConverter(FxProductInfoBO resource) {
...
return xx;
}
}
1.工厂模式和策略模式的最大区别是,工厂模式提供方法、由工厂根据不同条件创建Bean,而策略模式由调用方创建或注入Bean。
2.简单工厂模式违背了“开闭原则”。因为每加一个实现类,都需要在工厂中添加代码。工厂方法模式可以解决此问题。