zoukankan      html  css  js  c++  java
  • 设计模式学习笔记(六:责任链模式)

    1.1概述

        使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。这就是责任链模式。

        责任链模式是使用多个对象处理用户请求的成熟模式,责任链模式的关键是将用户的请求分派给许多对象,这些对象被组织成一个责任链,即每个对象含有后继对象的引用,并要求责任链上的每个对象,如果能处理用户的请求,就做出处理,不再将用户的请求传递给责任链上的下一个对象;如果不能处理用户的请求,就必须将用户的请求传递给责任链上的下一个对象。

    1.2模式的结构

    责任链模式的结构总包括两种角色:

    (1)处理者(Handler):处理者是一个接口,负责规定具体处理者处理用户请求的方法,以及具体处理者设置后继对象的方法。

    (2)具体处理者(ConcreteHandler):具体处理者是实现处理者接口的类的实例。具体处理者通过调用处理者接口规定的方法处理用户的请求,即在接到用户的请求后,处理者将调用接口规定的方法,在执行该方法的过程中,如果发现能处理用户的请求,就处理有关数据,否则就反馈无法处理的信息给用户,然后将用户的请求传递给自己的后继对象。

    责任链模式结构的类图如下所示:

     

    1.3责任链模式的优点

    (1)责任链中的对象只和自己的后继是低耦合关系,和其他对象毫无关联,这使得编写处理者对象以及创建责任链变得非常容易。

    (2)当在处理者中分配职责时,责任链给应用程序更多的灵活性。

    (3)应用程序可以动态地增加、删除处理者或重新指派处理者的职责。

    (4)
    应用程序可以动态地增加、删除处理者或重新指派处理者的职责。

    (5)应用程序可以动态地改变处理者之间的先后顺序。

    (6)使用责任链的用户不必知道处理者的信息,用户不会知道到底是哪个对象处理了它的请求。

    1.4适合使用责任链模式的情景

    (1)有许多对象可以处理用户的请求,希望程序在运行期间自动确定处理用户的那个对象。

    (2)希望用户不必明确指定接受者的情况下,向多个接受者的一个提交请求。

    (3)程序希望动态制定可处理用户请求的对象集合。

    1.5责任链模式的使用

    以下通过一个简单的问题来描述责任链模式汇总所涉及的各个角色。

    用户提交一个个人身份证号码,想知道该人是否在北京、上海或天津居住。

    针对上述问题,使用责任链模式设计一个系统来处理用户的请求。具体如下:

    首先看一下本实例构建框架具体类和1.2模式的结构中类图的对应关系,如下图所示:

     

    (1)处理者(Handler

    本问题中,处理者(Handler)接口的名字是Handler,代码如下:

    package com.liuzhen.six_chainOfResponsibility;
    
    public interface Handler {
        public abstract void handleRequest(String number);
        public abstract void setNextHandler(Handler handler);
    }

    (2)具体处理者

    对于本问题,一共有三个负责创建具体处理者的类,分别是BeijingShanghaiTianjing,三个类的代码如下:

    Beijing.java类:

    package com.liuzhen.six_chainOfResponsibility;
    
    import java.util.ArrayList;
    
    public class Beijing implements Handler{
        private Handler handler;                //存放当前处理者后继的Handler接口变量
        private ArrayList<String> numberList;   //存放身份证号码的数组线性表
        Beijing(){
            numberList = new ArrayList<String>();
            numberList.add("123456789");        //这里使用模拟的身份证号码
            numberList.add("987654321");
            numberList.add("987212143");
            numberList.add("767734672");
        }
        public void handleRequest(String number){
            if(numberList.contains(number))
                System.out.println("该人在北京居住");
            else{
                System.out.println("该人不在北京居住");
                if(handler != null)
                    handler.handleRequest(number);   //将请求传递给下一个处理者
            }
        }
        public void setNextHandler(Handler handler){
            this.handler = handler;
        }
    }

    Shanghai.java类:

    package com.liuzhen.six_chainOfResponsibility;
    
    import java.util.ArrayList;
    
    public class Shanghai implements Handler{
        private Handler handler;                //存放当前处理者后继的Handler接口变量
        private ArrayList<String> numberList;   //存放身份证号码的数组线性表
        Shanghai(){
            numberList = new ArrayList<String>();
            numberList.add("234567891");        //这里使用模拟的身份证号码
            numberList.add("876543219");
            numberList.add("872121493");
            numberList.add("767734729");
        }
        public void handleRequest(String number){
            if(numberList.contains(number))
                System.out.println("该人在上海居住");
            else{
                System.out.println("该人不在上海居住");
                if(handler != null)
                    handler.handleRequest(number);   //将请求传递给下一个处理者
            }
        }
        public void setNextHandler(Handler handler){
            this.handler = handler;
        }
    
    }

    Tianjing.java类:

    package com.liuzhen.six_chainOfResponsibility;
    
    import java.util.ArrayList;
    
    public class Tianjing implements Handler{
        private Handler handler;                //存放当前处理者后继的Handler接口变量
        private ArrayList<String> numberList;   //存放身份证号码的数组线性表
        Tianjing(){
            numberList = new ArrayList<String>();
            numberList.add("345678912");        //这里使用模拟的身份证号码
            numberList.add("886543219");
            numberList.add("972121493");
            numberList.add("667734729");
        }
        public void handleRequest(String number){
            if(numberList.contains(number))
                System.out.println("该人在天津居住");
            else{
                System.out.println("该人不在天津居住");
                if(handler != null)
                    handler.handleRequest(number);   //将请求传递给下一个处理者
            }
        }
        public void setNextHandler(Handler handler){
            this.handler = handler;
        }
    }

    (3)具体使用

        通过SixApllication类来具体实现上述相关类和接口,来实现适配器模式的运用,其代码如下:

    package com.liuzhen.six_chainOfResponsibility;
    
    public class SixApplication {
        private Handler beijing,shanghai,tianjing;      //责任链上的对象
        public void createChain(){                      //建立责任链
            beijing = new Beijing();
            shanghai = new Shanghai();
            tianjing = new Tianjing();
            beijing.setNextHandler(shanghai);
            shanghai.setNextHandler(tianjing);
        }
        public void reponseClient(String number){      //响应用户的请求
            beijing.handleRequest(number);
        }
        public static void main(String args[]){
            SixApplication sixApplicaiton = new SixApplication();
            sixApplicaiton.createChain();
            sixApplicaiton.reponseClient("667734729");
        }
    }

    运行结果:

    该人不在北京居住
    该人不在上海居住
    该人在天津居住

    参考资料:

          1.Java设计模式/耿祥义,张跃平著.——北京:清华大学出版社,2009.5

  • 相关阅读:
    阿里云通过465端口发送邮件绕过25端口
    阿里云子账号Policy授权规则明细
    蓝鲸cmdb平台架构
    库文件缺失问题修复
    centos7.2中启动polkit服务启动失败
    Linux升级GCC
    Ubuntu18.04服务器使用netplan网络构建桥接kvm虚拟机
    常用服务部署脚本(nodejs,pyenv,go,redis,)
    anaconda安装教程(之前安装过python)
    【PHP】array_unique与array_array_flip
  • 原文地址:https://www.cnblogs.com/liuzhen1995/p/5989208.html
Copyright © 2011-2022 走看看