博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
二十:职责链模式详解(类似于spring的hangler处理请求)
阅读量:5899 次
发布时间:2019-06-19

本文共 5017 字,大约阅读时间需要 16 分钟。

定义:为了避免请求的发送者和接收者之间的耦合关系,使多个接受对象都有机会处理请求。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

“看这个定义,就是将一堆可以处理请求的对象连成一条链,然后一个一个试着处理请求。这好像是可以解决麦当劳订餐的问题的,我先来看看我刚才苦B的订餐过程是什么样子的。” “首先应该有一个麦当劳的分店的类,它的主要功能是可以订餐。”

 “先来看看职责链模式的类图,这样比较好设计。”

 “类图还是比较简单的啊,有一个通用的接口,然后就是若干个具体的处理者。按照现在麦当劳的情况来说,接口里handleRequest方法其实就是order(订餐)方法了,而setSuccessor方法,则是用来设置职责链的下一个处理者。”

“对于麦当劳的问题来说,每一个分店就是具体的处理者了,主要的改动应该是抽象出来一个接口以及职责链的连接过程,而刚才发送订单的时候是拆分成方法参数传递给订餐方法的,现在最好是把订单做成一个数据类。”

package com.chain;import java.util.Map;//订单类(相当于request,其实就是封装一个请求)public class Order {    private int x;    private int y;    private Map
order; public Order(int x, int y, Map
order) { super(); this.x = x; this.y = y; this.order = order; } public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } public Map
getOrder() { return order; } public void setOrder(Map
order) { this.order = order; } }

                “下面便应该是分店接口了,它有两个方法,和类图当中的方法类似,只是名称略有改变。”

package com.chain;//分店接口(相当于Hanlder)public interface Subbranch {    void setSuccessor(Subbranch subbranch);        boolean handleOrder(Order order);    }

                “下面便是麦当劳分店的实现类了,它主要的改变是添加了一个属性(下一个分店),这应该就是链形成的基石了。”

package com.chain;import java.util.Collections;import java.util.Map;//麦当劳分店public class McSubbranch implements Subbranch{        private final static int MIN_DISTANCE = 500;//假设是500米以内送餐        private static int count;//类计数        private final int number;//分店号        private int x;//分店的横坐标,用于判断距离        private int y;//分店的纵坐标,用于判断距离        private Map
menu;//菜单 private Subbranch nextSubbranch;//下一家分店 public McSubbranch(int x, int y, Map
menu) { super(); this.x = x; this.y = y; this.menu = menu; number = ++count; } //设置下一家分店 public void setSuccessor(Subbranch subbranch) { this.nextSubbranch = subbranch; } //按照职责链处理订单 public boolean handleOrder(Order order){ //如果距离小于500米并且订单中的食物不缺货,则订单成功,否则失败 if (CommonUtils.getDistance(order.getX(), order.getY(), this.x, this.y) < MIN_DISTANCE && !CommonUtils.outOfStock(menu, order.getOrder())) { for (String name : order.getOrder().keySet()) { menu.put(name, menu.get(name) - order.getOrder().get(name)); } System.out.println("订餐成功,接受订单的分店是:" + this); return true; } if (nextSubbranch == null) { return false; } return nextSubbranch.handleOrder(order); } public Map
getMenu() { return Collections.unmodifiableMap(menu); } public Subbranch getNextSubbranch() { return nextSubbranch; } public String toString() { return "麦当劳分店第" + number + "个"; } }

               “handleOrder方法中的逻辑就是职责链的精髓了,它会试图处理请求,如果处理不了,则交给链中的下一个分店。刚才用的CommonUtils应该不用变了。下面就看下有了职责链模式之后,我的订餐方式吧。”

package com.chain;import java.util.HashMap;import java.util.Map;public class Client {    public static void main(String[] args) {        //假设初始菜单都是以下这些东西        Map
menu = new HashMap
(); menu.put("汉堡", 5); menu.put("薯条", 5); menu.put("可乐", 5); menu.put("雪碧", 5); //假设有5个分店 Subbranch mcSubbranch1 = new McSubbranch(0, 0, new HashMap
(menu)); Subbranch mcSubbranch2 = new McSubbranch(100, 120, new HashMap
(menu)); Subbranch mcSubbranch3 = new McSubbranch(-100, -120, new HashMap
(menu)); Subbranch mcSubbranch4 = new McSubbranch(1000, 20, new HashMap
(menu)); Subbranch mcSubbranch5 = new McSubbranch(-500, 0, new HashMap
(menu)); //以下设置职责链 mcSubbranch4.setSuccessor(mcSubbranch5); mcSubbranch3.setSuccessor(mcSubbranch4); mcSubbranch2.setSuccessor(mcSubbranch3); mcSubbranch1.setSuccessor(mcSubbranch2); //小左开始订餐,假设小左的坐标是900,20 Map
order = new HashMap
(); order.put("汉堡", 2); order.put("可乐", 1); order.put("薯条", 1); print(mcSubbranch1); System.out.println("------------------------------------------"); //小左开始订餐,直接找mcSubbranch1的这一家分店订餐即可 mcSubbranch1.handleOrder(new Order(900, 20, order)); System.out.println("------------------------------------------"); print(mcSubbranch1); } public static void print(Subbranch subbranch){ if (subbranch == null ) { return; } do { if (subbranch instanceof McSubbranch) { System.out.println("[" + subbranch + "]的菜单:" + ((McSubbranch) subbranch).getMenu()); } } while ((subbranch = ((McSubbranch) subbranch).getNextSubbranch()) != null); } }

                “输出结果和刚才是一样的,不过这下我订餐就好办多了,直接找第一家分店订餐就行,至于到最后谁给我送餐,我就不用管了。”

 1、客户端与具体的处理者解耦,客户端只认识一个Hanlder接口,降低了客户端(即请求发送者)与处理者的耦合度。

  2、客户端和处理者都不关心职责链的具体结构,而是交给职责链的创造者(在上述例子当中则是交给了OrderManager),也正因为如此,当在职责链中添加处理者的时候,这对客户端和处理者来说,都是透明的,二者不知道也不必要知道职责链的变化。

转载于:https://www.cnblogs.com/2019lgg/p/11101225.html

你可能感兴趣的文章
Linux安装BTCPayServer并设置比特币BTC和Lightning支付网关
查看>>
Python 的 with 语句
查看>>
mysql安装,远程连接,以及修改密码
查看>>
Mybatis查询返回Map类型数据
查看>>
java的深拷贝与浅拷贝
查看>>
程序员如何提高工作效率
查看>>
promise
查看>>
将Java应用部署到SAP云平台neo环境的两种方式
查看>>
==与equal的区别
查看>>
数据批量导入Oracle数据库
查看>>
调用lumisoft组件发邮件 不需要身份验证 不需要密码
查看>>
DW 正则
查看>>
抓屏原理
查看>>
ASP.NET Web API自身对CORS的支持: EnableCorsAttribute特性背后的故事
查看>>
UNIX网络编程读书笔记:TCP输出、UDP输出和SCTP输出
查看>>
扩展 DbUtility (1)
查看>>
iOS开发UI篇—使用picker View控件完成一个简单的选餐应用
查看>>
Apple Developer Registration and DUNS Number Not Accepted
查看>>
Hadoop学习笔记系列文章导航
查看>>
Win7 64位 php-5.5.13+Apache 2.4.9+mysql-5.6.19 配置
查看>>