java23种设计模式之十:责任链模式
时间:2019-12-07
本文章向大家介绍java23种设计模式之十:责任链模式,主要包括java23种设计模式之十:责任链模式使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
最近在学习netty中发现其中用到了责任链模式,然后结合自己在写代码中遇到了大量写if...else的情况,决定学习一下责任链模式。
一.什么样的场景下会选择用责任链模式
我们在进行业务逻辑判断时,需要根据传入参数类型的不同做出不同的处理,如果在传入的参数类型相对较少的情况时,可以用if...else来做判断,这样的确是没有什么问题的,但是如果后期由于业务系统的扩展,导致参数类型会随之延伸出很多种不同的处理,这时就需要用责任链模式来抒代码重构,这样会让代码封装的更好、更简洁,阅读性更强,后期如果增加了新的处理场景,只需要增加新的类就行,不会对原代码有很大的改动。
责任链模式的使用,会让方法的调用像递归一样的调用向后传递,如果传入的参数类型符合第1个handler处理的定义,那么就由第1个handler进行处理,如果不能处理,那就交由后续的handler进行处理。
大量的写if...else是可以解决问题,但个人认为写多了,这样的if...else就像一面墙一样,在等着请求类型的不同来选择不同的方法进行处理,而责任链是一条线一样的处理模式,能处理就由当前的处理,不能处理则由后面的handler处理。
二.责任链模式的编写
1.抽象1个总的handler
2.编写3个实现类来实现handler
3.请求类
4.客户端测试类
/** * 处理机器人请求 * * @author pengbo.zhao * @data 2019年12月7日 下午1:51:17 */ public abstract class Handler { public final static String REQUEST_TYPE_ORDER = "order"; //订单处理 public final static String REQUEST_TYPE_HOT = "hot"; //热点问处理 public final static String REQUEST_TYPE_HIS = "his"; //历史记录处理 private String type; private Handler netxtHandler; public Handler(String type){ this.type = type; } public final void handlerChain(Request request){ if(request.getName().equals(this.type)){ this.handler(request); }else{ if(this.netxtHandler !=null){ this.netxtHandler.handlerChain(request);//递归的调用下一个实现handler类的这个方法 }else{ //需要根据业务做其它的处理 System.out.println("需要做其它的处理。。。。。。"); } } } public void nextHandler(Handler handler){//设置下一个处理的handler this.netxtHandler = handler; } protected abstract void handler(Request request);//实现类重写 }
import java.util.Map.Entry; /** * 订单处理 * * @author pengbo.zhao * @data 2019年12月7日 下午2:13:48 */ public class OrderHandler extends Handler{ public OrderHandler(String type) {//子类在继承父类时,虚拟机会先加载父类的属性,先将父类的加载完毕后才能让子类加载,当加载到这里时子类会将传入的参数传递给父类,让父类先加载完成,然后才能加载子类,否则父类不能完全加载 super(Handler.REQUEST_TYPE_ORDER); } @Override protected void handler(Request request) { System.err.println("OrderHandler..........."); for (Entry<String, String> entry : request.getParamterMap().entrySet()) { System.out.println("key = "+entry.getKey() +" map = "+entry.getValue()); } } }
public class HisHandler extends Handler{ public HisHandler(String type) { super(Handler.REQUEST_TYPE_HIS); } @Override protected void handler(Request request) { System.err.println("HisHandler..........."); for (Entry<String, String> entry : request.getParamterMap().entrySet()) { System.out.println("key = "+entry.getKey() +" map = "+entry.getValue()); } } }
public class HotHandler extends Handler{ public HotHandler(String type) { super(Handler.REQUEST_TYPE_HOT); } @Override protected void handler(Request request) { System.err.println("HotHandler..........."); for(Entry<String, String> entry :request.getParamterMap().entrySet()){ System.out.println("key = "+entry.getKey() +" value = "+entry.getValue()); } } }
请求类
public class Request { public Request(String name, Map<String, String> paramterMap) { this.name = name; this.paramterMap = paramterMap; } private String name; private Map<String,String> paramterMap; public String getName() { return name; } public void setName(String name) { this.name = name; } public Map<String, String> getParamterMap() { return paramterMap; } public void setParamterMap(Map<String, String> paramterMap) { this.paramterMap = paramterMap; } }
测试类
public class Test { public static void main(String[] args) { String types [] = {"order","hot","his"}; Map<String,String> paramMap = new HashMap<>(); paramMap.put("key_1", "value_1"); paramMap.put("key_2", "value_2"); Request request = new Request(types[new Random().nextInt(3)],paramMap); Handler orderHandler = new OrderHandler(Handler.REQUEST_TYPE_ORDER); Handler hotHandler = new HotHandler(Handler.REQUEST_TYPE_HOT); Handler hishandler = new HisHandler(Handler.REQUEST_TYPE_HIS); orderHandler.nextHandler(hotHandler); hotHandler.nextHandler(hishandler); orderHandler.handlerChain(request); } }
原文地址:https://www.cnblogs.com/MrRightZhao/p/12001911.html
- JavaScript实现私有属性
- 使用LRU算法缓存图片,android 3.0
- 深入理解JavaScript原型:prototype,__proto__和constructor
- Comparable 与 Comparator 浅析
- 必应首页平铺背景图片的实现方案
- 我们是如何优化HAProxy以让其支持200万个并发SSL连接的?
- 【译】《Understanding ECMAScript6》- 第八章-Module
- 【译】《Understanding ECMAScript6》- 第七章-Promise
- 自定义gradview
- Redis 起步
- JVM参数详解及OOM
- 【译】《Understanding ECMAScript6》- 第五章-Class
- 【译】《Understanding ECMAScript6》- 第三章-Object
- 【译】《Understanding ECMAScript6》- 第二章-函数
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- goland破解教程
- HTTP接口设计
- NSQ分布式消息基础入门
- 【golang】剑指offer 最大n位数
- Spark提交Jar任务警告: Initial job has not accepted any resources;
- Defer,Panic,and Recover
- Spark——底层操作RDD,基于内存处理数据的计算引擎
- Go 项目最佳实践
- 虚拟机更换JDK版本步骤(Hadoop集群)
- JavaSE重点复习
- [数据结构与算法] 树结构之二叉排序树、平衡二叉树、多路查找树
- 工作后, 你一定不能错过技术之JDK1.8的新特性
- 【Go】剑指offer:二叉树子树的判断
- css中的box-shadow属性详解
- 基于docker快速搭建多节点Hadoop集群