说说设计模式~管道模式(pipeline)
说明
复合的责任链,类似于管道模式,只要符合条件,说会向下传递,不会终止
算法说明
- 按最高优先级去使用,符合就用,不符合就走下一个策略
- 具体链条,有点像pipeline管道模式
- BlackHandler ip=172.17.0.11
- RateLimitHandler header=is-black
- WriteBlackHandler header=real-black
继承抽象类
- AbstractHandler 抽象的责任处理者
- 抽象方法action,需要各个子类【具体的责任处理者】自己去实现
- final修饰的方法,封装了实现细节,子类不能重写
- setNextHandler方法,设置下一个链条的【责任处理者】
- HandlerFactory 责任工厂
- 通过一个责任处理列表,返回一个责任链条
- 责任链条可以持久化到数据库里
责任链如果没有终止条件,就类似于pipeline管道了
测试代码
抽象处理者
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;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【.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 说说底层架构之实体类的设计