策略模式應用場景:
在開發項目時,比如實現支付過程,調用第三方支付,在支付過程中需要做的同一件事情調用支付,無非就是在實現多個支付過程之後的代碼不一樣,所以我們這裏可以做到將同一件事情調用支付的代碼提取出來放到 接口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>