工厂模式 + 策略模式 实现:在运行时根据具体条件动态选择不同的策略

我们通过一个具体的例子来解释这种设计思想:

        比如在线刷题场景,有单选,多选,简答,判断等题目类型。这些类型通过参数type进行区分。后端需要根据前端传来的参数来判断是哪种题型进而选择不同的处理方法。

实现:

        1.配置不同的handler:

public interface SubjectTypeHandler {
    /**
     * 拿到当前handler对应的枚举类
     */
    SubjectInfoTypeEnum getHandlerType();

    /**
     * 要进行的操作,这里举个例子add,新增题目。不同题目类型继承这个接口后有不同的实现逻辑
     */
    void add(SubjectInfoBo subjectInfoBO);
    
}

单选题handler实现举例:

/**
 * @ClassName RadioTypeHandler
 * @Description 单选题目handler
 * @Author 86153
 * @Date 2024/7/30 20:32
 * @Version 1.0
 **/
@Component
public class RadioTypeHandler implements SubjectTypeHandler{
    @Resource
    private SubjectRadioService subjectRadioService;

    @Override
    public SubjectInfoTypeEnum getHandlerType() {
        return SubjectInfoTypeEnum.RADIO;//返回单选题枚举
    }
    @Override
    public void add(SubjectInfoBo subjectInfoBO) {
        //单选题目的插入
        subjectRadioService.add();//调用单选题service的add方法
    }

}

          2.题目类型枚举类:

          3.工厂实现:


 * @ClassName SubjectTypeHandlerFactoory
 * @Description subject题目类型处理工厂
 * @Author 86153
 * @Date 2024/7/30 19:24
 * @Version 1.0
 **/
@Component
public class SubjectTypeHandlerFactoory implements InitializingBean {
    @Resource
    List<SubjectTypeHandler> subjectTypeHandlerList;//自动装配所有handler
    //工厂核心,Map<题目类型 , 对应handler>
    //SubjectInfoTypeEnum是题目类型的枚举类
    Map<SubjectInfoTypeEnum,SubjectTypeHandler> handlerMap = new HashMap<>();
  

    //外部调用接口,传进来题目类型id,就能返回对应的handler
    public SubjectTypeHandler getHandler(int subjectType) {
        SubjectInfoTypeEnum subjectInfoTypeEnum = SubjectInfoTypeEnum.getByCode(subjectType);
        return handlerMap.get(subjectInfoTypeEnum);//通过题目类型枚举拿到对应的handler
    }
    //实现InitializingBean接口,重写afterPropertiesSet方法初始化工厂
    //@Resource属性注入已经将所有handler拿到一个list了
    //getHandler拿到handler对应的枚举
    //这里遍历list,将 <不同题目类型的枚举 ,对应的handler>放进map当中
    @Override
    public void afterPropertiesSet() throws Exception {
        for (SubjectTypeHandler subjectTypeHandler : subjectTypeHandlerList) {
            handlerMap.put(subjectTypeHandler.getHandlerType(),subjectTypeHandler);
        }

    }
}

         这里再理一下工厂的实现逻辑:   首先@Resource将所有的hanler注入到工厂的list当中,然后通过InitializingBean接口进行初始化(bean生命周期:先进行依赖注入然后进行初始化),遍历list,将<接口枚举 , 接口handler>放在一个map当中。工厂对外提供getHandler方法,通过参数题目类型对应的code拿到对应的枚举,再拿到对应handler。

         4.工厂调用:

SubjectTypeHandler handler = 
 subjectTypeHandlerFactoory.getHandler(不同题目类型的code);

handler.add(subjectInfoBo);//工厂根据code拿到对应题目的handler

通过代理 + 策略:

  1. 我们可以实现动态策略选择,省略大量if-else代码
  2. 分离策略的使用与创建逻辑(工厂封装对象创建的细节,我们只需要关注使用逻辑)
  3. 可拓展性:新的策略类可以轻松地添加到系统中,只需修改工厂类,而不影响客户端代码。比如后面需要添加一个画图题,我只需要增加策略类,增加枚举即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值