巩义网站推广怎么做,做网站和优化的公司,重庆森林在线观看,手机pc端浏览器首先简单介绍策略模式
该模式定义了一系列算法#xff0c;并将每个算法封装起来#xff0c;使它们可以相互替换#xff0c;且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式#xff0c;它通过对算法进行封装#xff0c;把使用算法的责任和算法的实现分割开…首先简单介绍策略模式
该模式定义了一系列算法并将每个算法封装起来使它们可以相互替换且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式它通过对算法进行封装把使用算法的责任和算法的实现分割开来并委派给不同的对象对这些算法进行管理。
策略模式的主要角色如下
抽象策略Strategy类这是一个抽象角色通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。具体策略Concrete Strategy类实现了抽象策略定义的接口提供具体的算法实现或行为。环境Context类持有一个策略类的引用最终给客户端调用。
这时候策略模式其实就是接口定义规范扩展不同的实现类进行方法重写来完成策略模式的扩展
案例
登录接口中可能会有多种登录方式:
用户名密码登录短信验证码登录微信登录QQ登录....
此时业务层代码大量使用到了if...else在后期阅读代码的时候会非常不友好大量使用if...else性能也不高.
解决
我们采用策略模式工厂模式可以完整的实现
1整体思路
改造之后不在service中写业务逻辑让service调用工厂然后通过service传递不同的参数来获取不同的登录策略登录方式 2具体实现
抽象策略类UserGranter /*** 抽象策略类*/
public interface UserGranter{/*** 获取数据* param loginReq 传入的参数* return map值*/LoginResp login(LoginReq loginReq);
}具体的策略AccountGranter、SmsGranter、WeChatGranter
/*** 策略账号登录**/
Component
public class AccountGranter implements UserGranter{Overridepublic LoginResp login(LoginReq loginReq) {System.out.println(登录方式为账号登录 loginReq);// TODO// 执行业务操作 return new LoginResp();}
}
/*** 策略:短信登录*/
Component
public class SmsGranter implements UserGranter{Overridepublic LoginResp login(LoginReq loginReq) {System.out.println(登录方式为短信登录 loginReq);// TODO// 执行业务操作return new LoginResp();}
}
/*** 策略:微信登录*/
Component
public class WeChatGranter implements UserGranter{Overridepublic LoginResp login(LoginReq loginReq) {System.out.println(登录方式为微信登录 loginReq);// TODO// 执行业务操作return new LoginResp();}
}工程类UserLoginFactory
下方的setApplicationContext方法是由于这个类继承了ApplicationContextAware上下文对象,这个方法会被spring自动调用,变相的说这里完成了对所有策略的集合map的初始化.
/*** 操作策略的上下文环境类 工具类* 将策略整合起来 方便管理*/
Component
public class UserLoginFactory implements ApplicationContextAware {private static MapString, UserGranter granterPool new ConcurrentHashMap();Autowiredprivate LoginTypeConfig loginTypeConfig;/*** 从配置文件中读取策略信息存储到map中* {* account:accountGranter,* sms:smsGranter,* we_chat:weChatGranter* }** param applicationContext* throws BeansException* */Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {loginTypeConfig.getTypes().forEach((k, y) - {granterPool.put(k, (UserGranter) applicationContext.getBean(y));});}/*** 对外提供获取具体策略** param grantType 用户的登录方式需要跟配置文件中匹配* return 具体策略*/public UserGranter getGranter(String grantType) {UserGranter tokenGranter granterPool.get(grantType);return tokenGranter;}}在application.yml文件中新增自定义配置,这里的key是前端传入的type值,value是IOC容器中对象类的名字,在上方的getGranter方法中会通过key获取到IOC中对应的对象
login:types:account: accountGrantersms: smsGranterwe_chat: weChatGranter新增读取数据配置类
Getter
Setter
Configuration
ConfigurationProperties(prefix login)
public class LoginTypeConfig {private MapString,String types;}改造service代码
Service
public class UserService {Autowiredprivate UserLoginFactory factory;public LoginResp login(LoginReq loginReq){UserGranter granter factory.getGranter(loginReq.getType());if(granter null){LoginResp loginResp new LoginResp();loginResp.setSuccess(false);return loginResp;}LoginResp loginResp granter.login(loginReq);return loginResp;}
}可以看到我们使用了设计模式之后业务层的代码就清爽多了如果后期有新的需求改动比如加入了QQ登录我们只需要添加对应的策略就可以无需再改动业务层代码。