一、策略模式的定义:
定义一系列的算法,把它们一个个封装起来,并且可以使他们互相替换。本模式可以使得算法可独立与使用它的客户而变化。
策略模式的结构图
二、策略模式出现背景举例:
当我们给人支付工资的时候可以使用不同的支付方式:
1、使用人民币现金
2、使用美元现金
3、使用信用卡
4、使用微信支付
5、使用支付宝
等等,有很多种支付方式,那到底最终要选择哪一种支付方式呢,其实是不确定的,针对不同的人,需要使用不同的支付方式【比如在国外可能就需要使用到美元支付等】;另外在不同的时间、地点也可能使用不同的支付方式【比如支付宝没钱了,就可能选择微信支付等】。
如果要写一个总的支付系统类,那么我们是否通通使用if elseif…来完成呢。显然是很不好的:
1、首先该类中包含了所有的支付类型的算法,使得这个类会非常庞大。
2、违背了“开–闭原则”,当不同的支付手段需要调整的时候,总会去修改该类,非常容易产生问题。
三、策略模式的功能:
在如上的举例中,策略模式应运而生,策略模式的重心不是如何实现算法,而是如何组织、调用这些算法,从而让程序结构更加灵活,具有更好的维护性和扩展性。
四、策略模式代码示例:
1、定义任务的策略接口
/**
* 策略接口
*/
public interface TaskStrategy {
/**
* 匹配
*
* @param obj DTO
* @return
*/
public <T> ResponseUtils match(T obj);
/**
* 执行器
*
* @param obj 执行器dto
* @return
*/
public <T>ResponseUtils execute(T obj);
}
2、抽象类策略
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 抽象类策略
*/
public abstract class AbstractTaskStrategy implements TaskStrategy {
private Logger logger = LoggerFactory.getLogger(this.getClass());
}
3、定义具体的策略实现类
import java.util.HashMap;
import java.util.Map;
/**
* 策略接口实现类:执行具体业务实现,同一个业务类型,只需要重写具体业务实现类
* @Order 指定bean的执行顺序
*/
@Order(1)
@Component
public class TaskStatusStrategy extends AbstractTaskStrategy {
//执行业务匹配逻辑
@Override
public <T> ResponseUtils match(T obj) {
System.out.println("TaskStatusStrategy执行顺序");
//这里写自己的匹配逻辑,true继续执行,false就会终止执行,匹配逻辑可以设计成表
if (obj == null) {
return ResponseUtils.fail("执行器不匹配");
}
Map map = new HashMap();
map.put("张三", 1);
return ResponseUtils.success(map);
}
//执行业务具体逻辑
@Override
public <T> ResponseUtils execute(T obj) {
//执行具体的业务逻辑
return null;
}
}
import com.example.strategy.AbstractTaskStrategy;
import com.example.utils.ResponseUtils;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Order(0)
@Component
public class UpdateTaskStrategy extends AbstractTaskStrategy {
@Override
public <T> ResponseUtils match(T obj) {
System.out.println("UpdateTaskStrategy执行顺序");
return ResponseUtils.success();
}
@Override
public <T> ResponseUtils execute(T obj) {
return ResponseUtils.success();
}
}
4、枚举:
public interface AbstractBaseExceptionEnum {
String getCode();
String getMessage();
}
import java.util.HashMap;
import java.util.Map;
public enum CoreExceptionEnum implements AbstractBaseExceptionEnum {
SUCCESS("200", "成功"),
FAIL("500", "失败"),
;
private String msg;
private String code;
CoreExceptionEnum(String msg, String code) {
this.msg = msg;
this.code = code;
}
public static Map<String, CoreExceptionEnum> allMap = new HashMap<>(16);
static {
for (CoreExceptionEnum coEnum : CoreExceptionEnum.values()) {
allMap.put(coEnum.code, coEnum);
}
}
@Override
public String getCode() {
return code;
}
@Override
public String getMessage() {
return msg;
}
}
5、Rest工具类:
import com.example.enums.CoreExceptionEnum;
public class ResponseUtils<T> {
private Boolean isSucceed;
private String msg;
private String code;
private CoreExceptionEnum coreExceptionEnum;
private T data;
@Deprecated
public ResponseUtils() {
}
public Boolean getSucceed() {
return isSucceed;
}
public void setSucceed(Boolean succeed) {
isSucceed = succeed;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public CoreExceptionEnum getCoreExceptionEnum() {
return coreExceptionEnum;
}
public void setCoreExceptionEnum(CoreExceptionEnum coreExceptionEnum) {
this.coreExceptionEnum = coreExceptionEnum;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public boolean isSucceed(){
return isSucceed;
}
/**
* 成功时-返回data
*
* @param <T>
* @return
*/
public static ResponseUtils success() {
ResponseUtils responseUtils = new ResponseUtils();
responseUtils.isSucceed = true;
responseUtils.msg = "";
responseUtils.code = CoreExceptionEnum.SUCCESS.getCode();
return responseUtils;
}
/**
* 成功-返回message
*
* @param <T>
* @return
*/
public static <T> ResponseUtils<T> success(String msg) {
ResponseUtils responseUtils = new ResponseUtils();
responseUtils.isSucceed = true;
responseUtils.msg = msg;
return responseUtils;
}
/**
* 成功-返回message和code
*
* @param <T>
* @return
*/
public static <T> ResponseUtils<T> success(String msg, String code) {
ResponseUtils responseUtils = new ResponseUtils();
responseUtils.isSucceed = true;
responseUtils.msg = msg;
responseUtils.code = code;
return responseUtils;
}
/**
* 成功时-返回data
*
* @param <T>
* @return
*/
public static <T> ResponseUtils<T> success(T data) {
ResponseUtils responseUtils = new ResponseUtils();
responseUtils.isSucceed = true;
responseUtils.msg = "";
responseUtils.code = CoreExceptionEnum.SUCCESS.getCode();
responseUtils.data = data;
return responseUtils;
}
/**
* 失败
*
* @param <T>
* @return
*/
public static <T> ResponseUtils<T> fail(String msg) {
ResponseUtils responseUtils = new ResponseUtils();
responseUtils.isSucceed = false;
responseUtils.msg = msg;
return responseUtils;
}
/**
* 失败-code
*
* @param <T>
* @return
*/
public static <T> ResponseUtils<T> fail(CoreExceptionEnum code, String msg) {
ResponseUtils responseUtils = new ResponseUtils();
responseUtils.isSucceed = false;
responseUtils.code = code.getCode();
responseUtils.msg = msg;
return responseUtils;
}
}
6、策略类调用:
import com.example.strategy.TaskStrategy;
import com.example.utils.ResponseUtils;
import com.example.vo.BaseEntity;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.List;
import java.util.Map;
@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
class DesignModeApplicationTests {
@Autowired
private List<TaskStrategy> taskStrategy;
@Test
public void testStrategy() {
BaseEntity obj = new BaseEntity();
obj.setCreateBy("sss");
for (TaskStrategy executors : taskStrategy) {
String simpleName = executors.getClass().getSimpleName();
ResponseUtils match = executors.match(obj);
Map map = (Map) match.getData();
System.out.println("执行器: " + simpleName + ", 是否匹配: " + match.isSucceed() + ",不匹配信息: " + match.getMsg());
//match==teue执行
if (match.isSucceed()) {
executors.execute(obj);
}
}
}
}