[回到目錄](https://www.cnblogs.com/lori/p/3896484.html) # 說明 複合的責任鏈,類似於管道模式,只要符合條件,說會向下傳遞,不會終止 # 演算法說明 * 按最高優先順序去使用,符合就用,不符合就走下一個策略 * 具體鏈條,有點像pipeline管道模式 * ...
說明
複合的責任鏈,類似於管道模式,只要符合條件,說會向下傳遞,不會終止
演算法說明
- 按最高優先順序去使用,符合就用,不符合就走下一個策略
- 具體鏈條,有點像pipeline管道模式
- BlackHandler ip=172.17.0.11
- RateLimitHandler header=is-black
- WriteBlackHandler header=real-black
繼承抽象類
- AbstractHandler 抽象的責任處理者
- 抽象方法action,需要各個子類【具體的責任處理者】自己去實現
- final修飾的方法,封裝了實現細節,子類不能重寫
- setNextHandler方法,設置下一個鏈條的【責任處理者】
- HandlerFactory 責任工廠
- 通過一個責任處理列表,返回一個責任鏈條
- 責任鏈條可以持久化到資料庫里
責任鏈如果沒有終止條件,就類似於pipeline管道了
graph TD Request[post body]-->A[BlackHandler] A --> B[RateLimitHandler] B --> C[WriteBlackHandler] C --> D[EndHandler]測試代碼
抽象處理者
public abstract class AbstractHandler<T> {
private AbstractHandler nextHandler;
public final void setNextHandler(AbstractHandler nextHandler) {
this.nextHandler = nextHandler;
}
protected abstract void action(T body);
// final表示不允許子類重寫
public final void handleRequest(T body) {
action(body);
if (this.nextHandler != null)
this.nextHandler.handleRequest(body);
}
}
具體處理者
public class BlackHandler extends AbstractHandler<Request> {
private static final Logger logger = LoggerFactory.getLogger(CouponHandler.class);
@Override
public void action(Request body) {
logger.info("BlackHandler 處理");
}
}
public class RateLimitHandler extends AbstractHandler<Request> {
private static final Logger logger = LoggerFactory.getLogger(CouponHandler.class);
@Override
protected void action(Request body) {
logger.info("RateLimitHandler 處理");
}
}
public class WriteBlackHandler extends AbstractHandler<Request> {
private static final Logger logger = LoggerFactory.getLogger(CouponHandler.class);
@Override
protected void action(Request body) {
logger.info("WriteBlackHandler 處理");
}
}
public class EndHandler extends AbstractHandler<Request> {
private static final Logger logger = LoggerFactory.getLogger(CouponHandler.class);
@Override
protected void action(Request body) {
logger.info("EndHandler 處理");
}
}
處理者工廠和請求數據體
public class HandlerFactory {
public static <T extends Request> AbstractHandler<T> createHandler(List<AbstractHandler<T>> handlerModels) {
AbstractHandler<T> handler = null;
AbstractHandler<T> previousHandler = null;
for (AbstractHandler<T> currentHandler : handlerModels.stream().collect(Collectors.toList())) {
if (previousHandler != null) {
previousHandler.setNextHandler(currentHandler);
}
else {
handler = currentHandler;
}
previousHandler = currentHandler;
}
return handler;
}
}
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Request {
private String ip;
private String userId;
}
測試用例
public static void main(String[] args) {
List<AbstractHandler<Request>> abstractHandlers = Arrays.asList(new RateLimitHandler(), new BlackHandler(),
new WriteBlackHandler(),new EndHandler());
AbstractHandler<Request> abstractHandler = HandlerFactory.createHandler(abstractHandlers);
abstractHandler.handleRequest(new Request("1", "user1"));
}
如果希望將你的責任鏈處理存儲到資料庫中,那個在handleFactory里,就需要介面className了,例如下麵的代碼:
public static Handler handlerFactory() {
List<HandlerModel> handlerModels = new ArrayList<>();
handlerModels
.add(new HandlerModel("CouponHandler", "com.lind.common.pattern.chinaorder.handler.CouponHandler", 1));
handlerModels.add(
new HandlerModel("DiscountHandler", "com.lind.common.pattern.chinaorder.handler.DiscountHandler", 2));
handlerModels.add(
new HandlerModel("BigGiftHandler", "com.lind.common.pattern.chinaorder.handler.BigGiftHandler", 3));
handlerModels.add(new HandlerModel("VipHandler", "com.lind.common.pattern.chinaorder.handler.VipHandler", 4));
return createHandler(handlerModels);
}
private static Handler createHandler(List<HandlerModel> handlerModels) {
Handler handler = null;
Handler previousHandler = null;
for (HandlerModel handlerModel : handlerModels.stream().sorted().collect(Collectors.toList())) {
try {
Handler currentHandler = (Handler) Class.forName(handlerModel.getClassPath()).newInstance();
if (previousHandler != null) {
previousHandler.setNextHandler(currentHandler);
}
else {
handler = currentHandler;
}
previousHandler = currentHandler;
}
catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
return handler;
}
作者:倉儲大叔,張占嶺,
榮譽:微軟MVP
QQ:853066980
支付寶掃一掃,為大叔打賞!