说说设计模式~管道模式(pipeline)

回到目录

说明

复合的责任链,类似于管道模式,只要符合条件,说会向下传递,不会终止

算法说明

  • 按最高优先级去使用,符合就用,不符合就走下一个策略
  • 具体链条,有点像pipeline管道模式
    • BlackHandler ip=172.17.0.11
    • RateLimitHandler header=is-black
    • WriteBlackHandler header=real-black

继承抽象类

  • AbstractHandler 抽象的责任处理者
    • 抽象方法action,需要各个子类【具体的责任处理者】自己去实现
    • final修饰的方法,封装了实现细节,子类不能重写
    • setNextHandler方法,设置下一个链条的【责任处理者】
  • HandlerFactory 责任工厂
    • 通过一个责任处理列表,返回一个责任链条
    • 责任链条可以持久化到数据库里

责任链如果没有终止条件,就类似于pipeline管道了

post body
BlackHandler
RateLimitHandler
WriteBlackHandler
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 @   张占岭  阅读(301)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
历史上的今天:
2017-06-30 docker~Dockerfile方式生成控制台和Api项目的镜像
2014-06-30 爱上MVC3系列~监视Action的运行时间,并提供超时记录机制
2011-06-30 不忘本~枚举
2011-06-30 说说底层架构之实体类的设计
点击右上角即可分享
微信分享提示