这里使用登录做例子介绍如何实现登录的多种策略
上图是策略模式的基础模型。
context
Context上下文角色,也叫Context封装角色,起承上启下的作用,屏蔽高层模块对策略、算法的直接访问,封装可能存在的变化。
Strategy
策略角色,接口类,封装相同类型策略公共方法,具体策略实现算法
ConcreteStrategy
具体策略实现Strategy中的抽象方法,编写具体算法实现。
至此基本的策略模式就说完了,具体实现看下面在spring中我们如何实现这种策略模式来实现多种登录方式:
在spring中怎样实现Context 上下文角色
@Component public class LoginStrategyFactory implements InitializingBean, ApplicationContextAware { private final MapstrategyMap = new ConcurrentHashMap<>(); private ApplicationContext appContext; @Override public void afterPropertiesSet() throws Exception { // 将 Spring 容器中所有的 LoginHandler 注册到 strategyMap appContext.getBeansOfType(LoginService.class) .values().forEach(hander->strategyMap.put(hander.getLoginType(),hander)); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { appContext = applicationContext; } public LoginService getStrategy(LoginType loginType) { return strategyMap.get(loginType); } }
首先实现ApplicationContextAware,在spring容器启动成功后将spring上下文注入到策略工厂中appContext
InitializingBean接口重写afterPropertiesSet 在bean初始化的时候去初始化strategyMap,从spring上下文中提取粗所有LoginService的实现类(具体策略)
定义策略角色(Strategy)
public interface LoginService { LoginType getLoginType(); UserDTO login(String username, String password); }
具体策略实现
@Component @Slf4j public class PhoneChatLoginStrategy implements LoginService { @Override public LoginType getLoginType() { return LoginType.PHONE; } @Override public UserDTO login(String username, String password) { //TODO 未实现手机登录 log.info("手机登录成功"); return new UserDTO(); } } @Component @Slf4j public class WeChatLoginStrategy implements LoginService { @Override public LoginType getLoginType() { return LoginType.WE_CHAT; } @Override public UserDTO login(String username, String password) { //TODO 未实现微信登录 log.info("微信登录成功"); return new UserDTO(); } }
每个策略我们提供了一个枚举,这样方便我们取具体策略。
public enum LoginType { QQ, WE_CHAT, PHONE; } 我们这里写了两个登录策略,具体调用: @RestController @RequestMapping("/user") @Slf4j public class PublicUserController { @Autowired private LoginStrategyFactory loginStrategyFactory; @PostMapping("/login") public Responselogin(@RequestBody @Validated LoginParam loginParam) { log.info("用户登录:{}",loginParam.getUsername()); LoginService strategy = loginStrategyFactory.getStrategy(loginParam.getLoginType()); UserDTO login = strategy.login(loginParam.getUsername(), loginParam.getPassword()); return new Response<>(login); } }
这样我们就完成了在spring中使用策略模式完成多种登录策略。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)