策略模式应用场景:
在开发项目时,比如实现支付过程,调用第三方支付,在支付过程中需要做的同一件事情调用支付,无非就是在实现多个支付过程之后的代码不一样,所以我们这里可以做到将同一件事情调用支付的代码提取出来放到 接口A中,当我们需要调用第三方支付时,比如 支付B,我们去实现接口A,支付C,我们也去实现接口A。当我们需要调用某个支付时,只需要传递支付的BeanId即可
通过传统if代码判断的,后期的维护性非常差!
public String toPayHtml2(String payCode){
if(payCode.equals("ali_pay")){
return "调用支付宝接口...";
}
if(payCode.equals("xiaomi_pay")){
return "调用小米支付接口";
}
if(payCode.equals("yinlian_pay")){
return "调用银联支付接口...";
}
return "未找到该接口...";
}
所以采用策略模式进行算法优化 项目采用Springboot 进行开发
- 支付接口A,调用支付接口的方法(一个抽象的角色)
/**
* 支付接口A,调用支付接口的方法
*/
public interface PayStrategy {
String toPayHtml();
}
- 支付方式为 AliPay 其中实现PayStrategy 接口(具体实现的角色)
@Component
public class AliPayStrategy implements PayStrategy {
@Override
public String toPayHtml() {
return "调用AliPayStrategy。。。。";
}
}
- 支付方式为 XiaoMIPay 其中实现PayStrategy 接口(具体实现的角色)
@Component
public class XiaoMiPayStrategy implements PayStrategy {
@Override
public String toPayHtml() {
return "调用XiaoMiPayStrategy。。。";
}
}
- 进行支付实现调用,此处我将支付的渠道放到Map集合当中,省时间,其中你们可以随意放置比如:数据库,枚举都可以
@RestController
public class PayContextService {
private final static Map<String,String> map = new HashMap<String,String>();
@Autowired
private SpringUtils springUtils;
@RequestMapping("/toPayHtml")
public String toPayHtml(String code){
map.put("ali_pay","aliPayStrategy");
map.put("xiaomi_pay","xiaoMiPayStrategy");
map.put("yinlian_pay","aliPayStrategy");
if(StringUtils.isEmpty(code)){
return "渠道不能为空";
}
//获取到beanId
String beanId = map.get(code);
if(StringUtils.isEmpty(code)){
return "渠道不存在";
}
//使用工具类根据beanId获取到 String容器中的 bean
PayStrategy bean = SpringUtils.getBean(beanId, PayStrategy.class);
//具体执行策略算法
return bean.toPayHtml();
}
}
- 工具类
@Component
public class SpringUtils implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
//获取applicationContext
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
//通过name获取 Bean.
public static Object getBean(String name){
return getApplicationContext().getBean(name);
}
//通过class获取Bean.
public static <T> T getBean(Class<T> clazz){
return getApplicationContext().getBean(clazz);
}
//通过name,以及Clazz返回指定的Bean
public static <T> T getBean(String name,Class<T> clazz){
return getApplicationContext().getBean(name, clazz);
}
}
- pom.xml 文件配置
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- sprinboot web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>