前言:使用策略者模式前需要了解其优缺点
- 优点:策略模式提供了对“开闭原则”的完美支持,避免使用多重条件转移语句,如if…else…语句、switch 语句,干掉复杂难看的if-else。
- 缺点:调用时,必须提前知道都有哪些策略模式类,才能自行决定当前场景该使用何种策略
背景:演示的demo 是以拉取短视频平台up主数据为背景,调用三方接口可能返回诸如:被限流、拉取数据失败、拉取数据次数超过每日上限等状态,而对于每种状态如果用 if else进行分支逻辑处理,一旦分支逻辑过多,代码会显得冗余且可读性较差,所以采用策略者模式进行代码优化。
1. 定义接口
/**
* 数据状态服务
*/
public interface StatusService {
// 状态处理方法
void statusHandle(int statusCode);
}
2. 各种状态实现类
- 被限流
/**
* 被限流
*/
public class CurrentLimitingStatusServiceImpl implements StatusService{
@Override
public void statusHandle(int statusCode) {
// todo::被限流的业务逻辑
System.out.println("拉取平台数据被限流,状态码:" + statusCode);
}
}
- 数据为空
/**
* 数据为空
*/
public class DataNullStatusServiceImpl implements StatusService{
@Override
public void statusHandle(int statusCode) {
// todo::拉取平台数据为空的业务逻辑
System.out.println("拉取平台数据为空,状态码:" + statusCode);
}
}
- 超过每日拉取限制次数
/**
* 超过每日拉取限制次数
*/
public class ExceedanceStatusServiceImpl implements StatusService {
@Override
public void statusHandle(int statusCode) {
// todo::超过每日最大限制次数的业务逻辑
System.out.println("拉取平台数据超过每日最大限制次数,状态码:" + statusCode);
}
}
- 拉取数据失败
/**
* 拉取数据失败
*/
public class FailedStatusServiceImpl implements StatusService{
@Override
public void statusHandle(int statusCode) {
// todo::拉取平台数据失败业务逻辑
System.out.println("拉取平台数据失败,状态码:" + statusCode);
}
}
- 拉取数据成功
/**
* 拉取数据成功
*/
public class SucceedStatusServiceImpl implements StatusService{
@Override
public void statusHandle(int statusCode) {
// todo::拉取平台数据成功的业务逻辑
System.out.println("拉取平台数据成功,状态码:" + statusCode);
}
}
3. 定义枚举
public enum StatusType {
CURRENT_LIMITING(10001, "被限流", new CurrentLimitingStatusServiceImpl()),
DATA_NULL(10002, "数据为空", new DataNullStatusServiceImpl()),
EXCEEDANCE(10003, "超过每日拉取限制次数", new ExceedanceStatusServiceImpl()),
FAILED(10004, "拉取数据失败", new FailedStatusServiceImpl()),
SUCCEED(10006, "拉取数据成功", new SucceedStatusServiceImpl());
private final int code;
private final String description;
private final StatusService statusService;
StatusType(int code, String description, StatusService statusService) {
this.code = code;
this.description = description;
this.statusService = statusService;
}
public int getCode() {
return code;
}
public String getDescription() {
return description;
}
public StatusService getStatusService() {
return statusService;
}
/**
* 获取 StatusType
*
* @param code
* @return
*/
public static StatusType fromCode(Integer code) {
return Arrays.stream(StatusType.values())
.filter(c -> c.getCode() == code).findFirst()
.orElse(null);
}
}
4. 简单测试
public class TestUse {
public static void main(String[] args) {
// todo::通过http请求调用拉取平台数据,拿到返回的状态码
// 这里就用自己造的状态码简单模拟下
int statusCode = 10001;
StatusType statusType = StatusType.fromCode(statusCode);
if (null != statusType) {
statusType.getStatusService().statusHandle(statusCode);
}
}
}
运行结果: