设计模式-责任链模式
责任链模式
一个请求的处理分为多个阶段,每个阶段作为责任链的一个节点,节点各自处理自己责任范围内的请求.
场景:发起审批,包括审批理由和审批金额
首先定义一个请求
public class Request {
private String reason;
private BigDecimal amount;
public Request(String reason, BigDecimal amount) {
this.reason = reason;
this.amount = amount;
}
@Override
public String toString() {
return "Request{" +
"reason='" + reason + '\'' +
", amount=" + amount +
'}';
}
public String getReason() {
return reason;
}
public void setReason(String reason) {
this.reason = reason;
}
public BigDecimal getAmount() {
return amount;
}
public void setAmount(BigDecimal amount) {
this.amount = amount;
}
}
定义统一的处理接口
/**
* 提供一个统一的处理接口
*/
public interface Handler {
// 返回Boolean.TRUE = 成功
// 返回Boolean.FALSE = 拒绝
// 返回null = 交下一个处理
Boolean process(Request request);
}
具体的处理实现类
@Slf4j
public class BossHandler implements Handler {
@Override
public Boolean process(Request request) {
log.info("Boss handler");
if (request.getReason().equalsIgnoreCase("recruit")) {
log.info("不想招人...")
return false;
}
return true;
}
}
另一个处理节点
@Slf4j
public class ManageHandler implements Handler {
@Override
public Boolean process(Request request) {
if (request.getAmount().compareTo(BigDecimal.valueOf(1000L)) > 0) {
return null;
}
log.info("manager handler");
return !request.getReason().equalsIgnoreCase("party");
}
}
客户端调用
@Slf4j
public class Client {
public static void main(String[] args) {
List<Handler> handlers = new ArrayList<>();
handlers.add(new ManageHandler());
handlers.add(new BossHandler());
Boolean result = null;
// 外部控制责任链的逻辑,包括执行顺序,结果处理等
for (Handler handler : handlers) {
Request req = new Request("play", BigDecimal.valueOf(900));
result = handler.process(req);
if (null != result) {
log.info(req + " " + (result ? "Approved by " : "Denied by ") + handler.getClass().getSimpleName());
return;
}
}
}
}
这里的实现是由外部控制责任链的执行,包括执行顺序和结果处理逻辑等.
结合Spring的实现
定义一个任务,它的执行过程中要经过各种校验,如时效性校验,风控校验,权限校验等流程
首先,定义一个任务类
public class Task {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
定义Filter接口
public interface Filter {
boolean doFilter(Task task);
}
实现类
@Slf4j
@Component
public class AuthFilter implements Filter {
@Override
public boolean doFilter(Task task) {
log.info("权限校验");
return true;
}
}
@Slf4j
@Component
public class DurationFilter implements Filter {
@Override
public boolean doFilter(Task task) {
log.info("时效性校验");
return true;
}
}
@Slf4j
@Component
public class RiskFilter implements Filter {
@Override
public boolean doFilter(Task task) {
log.info("风控校验");
return true;
}
}
将实现类交给Spring管理
服务调用
@Service
public class ApplicationService {
@Autowired
private List<Filter> filters;
public void client() {
Task task = new Task();
task.setName("a task");
for (Filter filter : filters) {
boolean r = filter.doFilter(task);
if (!r) {
throw new RuntimeException("valid fail by " + filter.getClass().getSimpleName());
}
}
}
}
这样如果需要添加新的过滤器,只要新增接口实现类即可。如果需要定义执行顺序,可以使用@Order
注解定义类的加载顺序。