基于SpringBoot的业务策略模式多实现类注入(Map注入)

1前言
在业务处理的过程中遇见一个场景,登录分A,B,C,他们都是对应的实现都是增删改查,但是不同的类型对应不同的平台登录方式,同时对应的增删改查业务逻辑有存在差异,这个时候如果不想办法设计代码就会出现A,B,C三种类型都要写一个对应接口(XXXserver),然后分别再去实现他们(XXXserverImpl),如果后来再增加一个平台登录,我们又要去重复相关接口和实现,不仅显得代码冗余,更是不好维护和管理,所以利用设计模式---策略模式就解决了这个问题。

1策略模式的引入

1.1一个接口有多个实现

public interface LoginService {


    String passwordSalt = "test";


    /**
     * @param postAccessToken 请求体
     */
    ExecResult<String> prop(Login postAccessToken);

    /**
     * 是否支持特定业务信息的处理
     *
     * @return
     */
    Boolean isSupported(Login postAccessToken);
}

//实现一
@Slf4j
@Service
public class DingdingServiceImpl implements LoginService {



    @Override
    public ExecResult<String> prop(Login postAccessToken) {
 
      System.out.println("钉钉用户");
        return ExecResultUtil.success(JwtUtil.build());
    }

    @Override
    public Boolean isSupported(Login postAccessToken) {
        return Objects.equals(GrantTypeEnum.DINGDING.getCode(), postAccessToken.getGrantType());
    }
}

//实现二
@Service
public class PasswordLoginServiceImpl implements LoginService {


    @Autowired
    private UserAccountService userAccountService;

    @Override
    public ExecResult<String> prop(Login postAccessToken) {
      
      System.out.println("普通用户");
    return ExecResultUtil.success(JwtUtil.build());
    }

    @Override
    public Boolean isSupported(Login postAccessToken) {
        return Objects.equals(GrantTypeEnum.PASSWORD.getCode(), postAccessToken.getGrantType());
    }
}
//实现三
@Service
public class SysPasswordLoginServiceImpl implements LoginService {


    @Autowired
    private UserAccountService userAccountService;

    @Override
    public ExecResult<String> prop(Login postAccessToken) {
       
      System.out.println("系统用户");
return ExecResultUtil.success(JwtUtil.build());
    }

    @Override
    public Boolean isSupported(Login postAccessToken) {
        return Objects.equals(GrantTypeEnum.SYS_PASSWORD.getCode(), postAccessToken.getGrantType());
    }
}

1.2 枚举类

@AllArgsConstructor
public enum GrantTypeEnum {

    PASSWORD("password", "普通用户密码"),
    PHONE("phone", "普通手机验证码"),
    WE_CHAT("wechat", "普通微信"),
    DINGDING("dingding", "普通钉钉"),

    SYS_PASSWORD("sys_password", "系统用户密码"),
    SYS_PHONE("sys_phone", "系统手机验证码"),
    SYS_WE_CHAT("sys_wechat", "系统微信"),
    SYS_DINGDING("sys_dingding", "系统钉钉"),
    ;
    private String code;

    private String message;

    public String getCode() {
        return this.code;
    }

    public String getMessage() {
        return this.message;
    }}

1.3 写一个公共的类来判断获取对应的实现类

@Service
public class LoginServiceImpl {

//关键在这个,原理:当一个接口有多个实现类的时候,key为实现类名,value为实现类对象
    private Map<String, LoginService> procMap = new ConcurrentHashMap<>();

    @Autowired(required = false)//这个注入了多个实现类对象
    private List<LoginService> procList = Collections.emptyList();

    public ExecResult<String> prop(Login login) {

        LoginService proc = getProc(login);
        if (null == proc) {
            throw new RuntimeException("no grant type:" + login.getGrantType());
        }
        return proc.prop(login);
    }

    private LoginService getProc(Login grantType) {
        LoginService querier = procMap.get(grantType.getGrantType());
        if (querier != null) {
            return querier;
        }
        for (LoginService item : procList) {
            if (item.isSupported(grantType)) {
                querier = item;
                procMap.put(grantType.getGrantType(), querier);
                return querier;
            }
        }
        return null;
    }

}

1.4控制层(为了测试用,根据业务使用,不一定用在控制层哈)


    @Autowired
    private LoginServiceImpl loginService;


    @ApiOperation(value = "登录")
    @PostMapping("/login")
    public ExecResult<String> postAccessToken(@RequestBody Login login) {
        return loginService.prop(login);
    }

1.5测试

2.完结撒花 !!!

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot 中使用策略模式结合 Map 的方式,你可以按照以下步骤进行实现: 1. 首先,定义一个接口,表示策略模式的抽象策略,例如: ```java public interface Strategy { String execute(); } ``` 2. 创建具体的策略实现接口,例如: ```java @Component public class StrategyA implements Strategy { @Override public String execute() { return "执行策略A"; } } @Component public class StrategyB implements Strategy { @Override public String execute() { return "执行策略B"; } } ``` 3. 在使用策略的地方,注入策略的集合,并通过 Map 存储,将策略的名称作为键,策略对象作为值,例如: ```java @Service public class StrategyService { private final Map<String, Strategy> strategyMap; public StrategyService(List<Strategy> strategyList) { this.strategyMap = new HashMap<>(); for (Strategy strategy : strategyList) { strategyMap.put(strategy.getClass().getSimpleName(), strategy); } } public String executeStrategy(String strategyName) { Strategy strategy = strategyMap.get(strategyName); if (strategy != null) { return strategy.execute(); } return "未找到对应的策略"; } } ``` 4. 在使用策略的地方调用 `executeStrategy()` 方法,并传入对应的策略名称,例如: ```java @RestController public class StrategyController { private final StrategyService strategyService; public StrategyController(StrategyService strategyService) { this.strategyService = strategyService; } @GetMapping("/execute/{strategyName}") public String executeStrategy(@PathVariable String strategyName) { return strategyService.executeStrategy(strategyName); } } ``` 这样,当访问 `/execute/StrategyA` 接口时,会执行策略A;访问 `/execute/StrategyB` 接口时,会执行策略B。你可以根据实际需求进行调整和扩展。希望对你有帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值