springboot+枚举+设计模式 解决多业务场景

一,业务背景

有个别接口业务要根据每个省的情况提供定制化开发

二,开发前思考

  • 1,原业务已经逻辑够复杂了,如果再加上if else if 代码不好维护,还不美观

  • 2,因为是其他组调用这边服务,如果每次都要自己去编码,开发会很恶心,有什么好的方法呢….

  • 3,有什么能即装逼又能解决现有的问题呢(程序员的高境界,又实用又能装到逼)

三,选型

  • 提供统一的接口

  • 使用 spring bean+策略模式解决不同平台不同业务

  • 使用枚举+门面模式提供统一的处理入口

四,代码实现

  • 提供接口
public interface IFusionLoginService {

    /**
     * auth 登录相关
     * @param request
     * @param authInfo
     * @return
     */
    boolean auth(HttpServletRequest request, UserToken authInfo);

    /**
     * forgetPwd 处理
     * @param request
     * @return
     */
   default boolean forgetPwd(HttpServletRequest request) {return true;}

    /**
     *  
     * @param fusionLogin
     * @return
     */
   boolean login(FusionLoginVO fusionLogin);
}
复制代码
  • 实现类,公司代码不给出具体实现
@Slf4j
@Component(value = FusionConstant.FUSION_LOGIN + FusionConstant.GD)
public class GdFusionLoginServiceImpl implements IFusionLoginService {

   

    @Override
    public boolean auth(HttpServletRequest request, UserToken authInfo) {
         //todo
    }
    

    @Override
    public boolean forgetPwd(HttpServletRequest request) {
         //todo
        return false;
    }

    @Override
    public boolean login(FusionLoginVO fusionLogin) {
       //todo
    }
复制代码
  • 门面模式提供统一处理bean
@Slf4j
@Component
public class FusionLoginProvider {
    // 这里spring 会根据实现同一个接口注入,key 是 bean 的name
    @Autowired
    private Map<String, IFusionLoginService> fusionLoginServiceMap;

    @Autowired
    private ISysConfigService sysConfigService;

    private String getPlatformKey() {
        return FusionConstant.FUSION_LOGIN + sysConfigService.getString(FusionConstant.FUSION_PLATFORM_CONTROL);
    }

    private IFusionLoginService getFusionLogin() {
        if (CollectionUtil.isEmpty(fusionLoginServiceMap)) {
            return null;
        }
        String platformKey = getPlatformKey();
        IFusionLoginService fusionLoginService = fusionLoginServiceMap.get(platformKey);
        if (Objects.isNull(fusionLoginService)) {
            return null;
        }
        return fusionLoginService;
    }

    /**
     * @return false
     */
    public boolean isFusion() {
        IFusionLoginService fusionLoginService = getFusionLogin();
        if (Objects.isNull(fusionLoginService)) {
            // 没有就不处理
            return false;
        }
        return true;
    }
    
    //这里是核心处理逻辑,通过枚举类型进行判断来调用对应的方法
    public boolean handleLogin(FusionLoginVO fusionLogin, FusionLoginHandler handler) {
        IFusionLoginService fusionLoginService = getFusionLogin();
        if (Objects.isNull(fusionLoginService)) {
            // 没有就不处理
            return true;
        }
        
         return FusionLoginHandler.handle(handler, fusionLoginService, fusionLogin);
    }
}
复制代码
  • 枚举类,具体逻辑的处理类
public enum FusionLoginHandler {

    AUTH {
        @Override
        boolean handle(IFusionLoginService fusionLoginService, FusionLoginVO fusionLogin) {
            return fusionLoginService.auth(fusionLogin.getRequest(), fusionLogin.getAuthInfo());
        }
    },
    FORGET_PWD {
        @Override
        boolean handle(IFusionLoginService fusionLoginService, FusionLoginVO fusionLogin) {
            return fusionLoginService.forgetPwd(fusionLogin.getRequest());
        }
    },
    LOGIN {
        @Override
        boolean handle(IFusionLoginService fusionLoginService, FusionLoginVO fusionLogin) {
            return fusionLoginService.login(fusionLogin);
        }
    };

    abstract boolean handle(IFusionLoginService fusionLoginService, FusionLoginVO fusionLogin);

    public static boolean handle(FusionLoginHandler handler, IFusionLoginService fusionLoginService, FusionLoginVO fusionLogin) {
        return handler.handle(fusionLoginService, fusionLogin);
    }
}
复制代码
  • 具体的调用方式
//
fusionLoginProvider.handleLogin(new FusionLoginVO(request,authInfo), FusionLoginHandler.AUTH);
//
fusionLoginProvider.handleLogin(new FusionLoginVO(request,null),FusionLoginHandler.FORGET_PWD);
//
fusionLoginProvider.handleLogin(new FusionLoginVO(fusionDataReqDTO),FusionLoginHandler.LOGIN);
复制代码

五,总结

  • 6月份代码已经上线了,经过一个多月的生产检验,目前没出现问题

  • 如果业务要在原有的代码上修改时,我觉得一定要考虑清楚,好不好扩展,好不好维护,好不好协同开发,如果都不满足这些内容,并且业务还要根据不同场景进行不同逻辑的变化,一定要停下来好好考虑,不能拿起键盘就是撸,即使现在搞出来了,后期变业务了还是要返工.

  • 这套改造不是一蹴而就的,而是不断打磨的,不是为了技术而技术,而是要最适合.

  • 搞技术要对代码有敬畏心,不断积累不断磨练不断精进.

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享