说说设计模式~管道模式(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;
	}

回到目录

posted @ 2023-06-30 15:48  张占岭  阅读(270)  评论(0编辑  收藏  举报