设计模式之简单工厂模式

一、概述

定义一个用于创建对象的接口,让子类决定实例化哪一个类。FactoryMethod使一个类的实例化延迟到其子类。

简单工厂模式:又叫做静态工厂方法模式,是由一个工厂对象决定创建出哪一种产品类的实例。

二、适用性

1.当一个类不知道它所必须创建的对象的类的时候。

2.当一个类希望由它的子类来指定它所创建的对象的时候。

3.当类将创建对象的职责委托给多个帮助子类中的某一个,并且希望将哪一个帮助子类是代理者这一信息局部化的时候。

三、参与者

1.Product定义工厂方法所创建的对象的接口或抽象类。

2.ProductA和ProductB实现Product接口。

3.Factory工厂类声明工厂方法,该方法返回一个Product类型的对象。 Factory也可以定义一个工厂方法的缺省实现,它返回一个缺省的Product对象。 它负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法createProduct()可以被外界直接调用,创建所需的产品对象。

4.Client客户端,调用工厂类的createProduct()方法来创建产品实例。

四、类图

设计模式之简单工厂模式_第1张图片

五、示例

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 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 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{
    @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.简单工厂模式违背了“开闭原则”。因为每加一个实现类,都需要在工厂中添加代码。工厂方法模式可以解决此问题。

你可能感兴趣的:(设计模式,设计模式,工厂方法模式,java)