设计模式(十)—责任链模式

最后更新于:2022-04-01 16:26:13

  **定义**: 使多个对象都有机会处理请求,从而避免了发送者和接收者之间的耦合关系。 将这些对象连成一条链,并沿着这条连传递该请求,直到有对象处理该请求为止。 **一个例子**: 古代女子讲究“三从四德”,当女子去做一件事情时,如果该女子未出嫁,首先要向父亲请求。 出嫁,就要像丈夫请求;夫死,就要向儿子请求。模拟这个女子发送请求的链式关系。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-06-06_5755340a4e2f1.jpg) **抽象的处理者实现三个职责:** ---|定义一个请求的处理方法handlerMessage,唯一开发的方法。 ---|定义一个编排方法setNext,设置下一个处理者。 ---|定义了具体的请求者必须实现的方法。 **处理者中完成的操作** ---|定义自身的责任等级 ---|实现抽象方法,对请求者进行封装,并作出响应。 **请求者完成的操作** ---|负责定义自身的请求等级。 ---|发出请求实体。 ~~~ public class ResponseTest { public static void main(String[] args) { //创建一个女子,发送自己的类型与请求 IWoman woman = new Woman(2,"我想出去购物.."); //创建责任链 ResponseHandler farther = new Farther(); ResponseHandler husband = new Husband(); ResponseHandler son = new Son(); //设置下一责任人。 farther.setNext(husband); husband.setNext(son); //设置责任链入口,处理内容 farther.handleMessage(woman); } } interface IWoman{ //女子发送请求。 String sendRequire(); //获取当前状态,出嫁、未嫁、夫死。 int getType(); } class Woman implements IWoman{ /** * 1、表示未嫁 * 2、出嫁 * 3、夫死 */ private int type = 0; private String request; //构造函数,设置女子的信息。 public Woman(int type,String require) { this.type = type; this.request = require; } //获得请求内容 @Override public String sendRequire() { return this.request; } //获取该女子当前的状态。 @Override public int getType() { System.out.println("-------"+this.type); return this.type; } } //责任链接口,定义一些方法,让子类去实现。 abstract class ResponseHandler{ //父亲处理等级 public static final int FARTHER_LEVEL_RESPONSE = 1; //丈夫处理等级 public static final int HUSBAND_LEVEL_RESPONSE = 2; //儿子处理等级 public static final int SON_LEVEL_RESPONSE = 3; //当前等级 private int level = 0; //设置下一个责任人是谁。 private ResponseHandler nextHandler; public ResponseHandler(int level) { this.level = level; } public void setNext(ResponseHandler handler){ this.nextHandler = handler; } public void handleMessage(IWoman woman){ System.out.println(this.level+"!!!!!!!-----!!!!!"+woman.getType()); if(this.level == woman.getType()){ //如果女子的当前等级与定义的等级相同,那么就做出回应 this.response(woman); }else{ //不满足当前等级,寻找下一个责任人 if(nextHandler != null){ //类似于 递归回调。 this.nextHandler.response(woman); }else{ //没有后继责任人,就停止回调。 System.out.println("----------找不到责任人了,你自由了...."); } } } //回应方式,具体实现由子类来实现。 protected abstract void response(IWoman woman); } /** * * @author admin * */ class Farther extends ResponseHandler{ public Farther() { super(ResponseHandler.FARTHER_LEVEL_RESPONSE); } @Override public void response(IWoman woman) { System.out.println("----------女儿向父亲请求-------"); System.out.println("------"+woman.sendRequire()); System.out.println("我是父亲,我统一你的请求..."); } } class Husband extends ResponseHandler{ public Husband() { super(ResponseHandler.HUSBAND_LEVEL_RESPONSE); } @Override public void response(IWoman woman) { System.out.println("----------妻子向丈夫请求-------"); System.out.println("------"+woman.sendRequire()); System.out.println("我是丈夫,我限制你的自由...."); } } class Son extends ResponseHandler{ public Son() { super(ResponseHandler.SON_LEVEL_RESPONSE); } @Override public void response(IWoman woman) { System.out.println("----------母亲向儿子请求-------"); System.out.println("------"+woman.sendRequire()); System.out.println("我是儿子,我一切都听你的...."); } } ~~~ **一个例子** 用户注册信息,用户分为普通用户和VIP用户。但是同时公用一个界面。 我们需要一个处理者,来区分不同的注册用户。这里可以用到责任链模式,来完成。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-06-06_5755340a70b3b.jpg) ~~~ public class ResponseEx { public static void main(String[] args) { //定义一些登录者 HashMap<String, Integer> hashMap = new HashMap<String, Integer>(); hashMap.put("lzl", 1); hashMap.put("xy", 2); hashMap.put("ht", 2); hashMap.put("hj", 2); hashMap.put("zl",1); //创建登录 Registe register = new Registe(); register.setHashMap(hashMap); //通过Handler处理登录信息,并通过责任链入口、 RegisteHandler CommonHandler = new CommonRegiste(); RegisteHandler VIPHandler = new VIPRegiste(); //设置下一个责任人.. CommonHandler.setHandler(VIPHandler); CommonHandler.HandleMessage(hashMap); } } abstract class RegisteHandler{ //VIP等级用户注册 public static final int VIP_LEVEL = 2; //普通用户注册 public static final int COMMON_LEVEL = 1; //设置hashMap存储登录信息 private HashMap<String, Integer> infoMap = new HashMap<String, Integer>(); //定义当前的等级 private int level ; //定义下一个责任链 private RegisteHandler nextHandler; //构造方法,设置责任人等级。 public RegisteHandler(int level){ this.level = level; } //处理信息 public void HandleMessage(HashMap<String, Integer> hashInfo){ //遍历hash表中的所用信息。 Set<String> set = hashInfo.keySet(); Iterator<String> it = set.iterator(); while(it.hasNext()){ String name = it.next(); //通过name获得 他的注册类型。 int type = hashInfo.get(name); if(this.level == type){ this.infoMap.clear(); this.infoMap.put(name, type); System.out.println("---------普通用户--------------"); //如果当前类型与注册类型相同,则执行方法。 this.response(infoMap); }else{ //如果没有找到责任人,继续查找 if(nextHandler != null){ this.infoMap.clear(); this.infoMap.put(name, type); System.out.println("---------VIP用户--------------"); this.nextHandler.response(infoMap); }else{ //如果找不到责任人。 System.out.println("没有您选择的注册类型,请重新注册...."); } } } } public void setHandler(RegisteHandler handler){ this.nextHandler = handler; } //定义请求的信息。 protected abstract void response(HashMap<String, Integer> hashMap); } class CommonRegiste extends RegisteHandler{ //构造函数设置普通用户的等级。 public CommonRegiste() { super(RegisteHandler.COMMON_LEVEL); } @Override protected void response(HashMap<String, Integer> hashMap) { Set<Map.Entry<String, Integer>> set = hashMap.entrySet(); Iterator<Map.Entry<String, Integer>> it = set.iterator(); while(it.hasNext()){ Map.Entry<String, Integer> map = it.next(); String name = map.getKey(); System.out.println("普通用户:"+name+"\t注册成功!"); } } } class VIPRegiste extends RegisteHandler{ //构造函数设置普通用户的等级。 public VIPRegiste() { super(RegisteHandler.VIP_LEVEL); } @Override protected void response(HashMap<String, Integer> hashMap) { Set<Map.Entry<String, Integer>> set = hashMap.entrySet(); Iterator<Map.Entry<String, Integer>> it = set.iterator(); while(it.hasNext()){ Map.Entry<String, Integer> map = it.next(); String name = map.getKey(); System.out.println("VIP用户: "+name+"\t注册成功!"); } } } class Registe{ /** * 1 表示普通用户 * 2 表示VIP用户 */ private HashMap<String, Integer> hashInfo = new HashMap<String, Integer>(); public void setHashMap(HashMap<String, Integer> hashMap){ this.hashInfo = hashMap; } public HashMap<String, Integer> getHashInfo() { return this.hashInfo; } } ~~~ 责任链式的优点: 1、请求和处理分开,请求者可以不用知道是谁处理,处理者可以不用知道请求的全貌。 2、两者解耦,提高系统的灵活性 责任链式的缺点 1、性能问题 2、调试不方便
';