设计模式——职责链模式

chain
阅读原文请访问个人博客 BrightLoong's Blog

一. 概述

一. 概述

职责链模式(Chain of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止(我的认为并不必定非要知足这种状况,也能够是每一个对象能够处理请求的一部分,或者是下一个处理对象须要上一个处理对象首先完成一些工做,将请求沿链一步一步传递,知道请求最终处理完成,既同时兼顾请求处理和请求转发,固然这个仅仅是我的理解,可能不正确,还请谅解)。html

使用职责链模式,发起请求的客户端并不用知道是链中的哪个对象最终处理了这个请求,因此这样系统的更改能够在不影响客户端的状况下动态地从新组织和分配责任。java

职责链模式属于行为型模式。git

二. UML类图解析

职责链模式的UML类图以下:github

chain

  • Handler:处理请求的抽象类,持有一个Handler引用做为后继者,setSuccessor(Handler handler)用于设置后继者;handleRequest(Request request)是处理请求的抽象方法,Request是具体的请求,按照本身的需求定义,能够简单的基本类型,集合类,也能够是自定义的类,等待子类具体实现。
  • ConcreteHandler一、ConcreteHandler2:具体处理者类,处理客户端请求,也能够访问后继者,按照职责链模式的定义,要么处理请求,要么转发请求,不存在二者同时兼顾的行为。

三. 代码实现

用向银行贷款做为例子,申请的贷款金额不一样须要不一样等级的银行人员进行受权。bash

贷款请求类——LoanRequest

首先建立一个贷款请求,具备基本的贷款金额和贷款人信息。ide

package io.github.brightloong.design.chain;

/** * 贷款请求类 * Created by BrightLoong on 2018/5/17. */
public class LoanRequest {
    /**贷款金额*/
    private Long loanAmount;

    /**贷款人姓名*/
    private String name;

    /** * 构造函数. * @param loanAmount * @param name */
    public LoanRequest(Long loanAmount, String name) {
        this.loanAmount = loanAmount;
        this.name = name;
    }

    public Long getLoanAmount() {
        return loanAmount;
    }

    public void setLoanAmount(Long loanAmount) {
        this.loanAmount = loanAmount;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

复制代码

抽象处理接口——BankStaff

package io.github.brightloong.design.chain;

/** * 请求处理抽象类. * Created by BrightLoong on 2018/5/17. */
public abstract class BankStaff {

    /**持有的后继者的引用*/
    private BankStaff nextBankStaff;

    /**设置后继者*/
    public void setNextBankStaff(BankStaff bankStaff) {
        this.nextBankStaff = bankStaff;
    }

    /**获取后继者*/
    public BankStaff getNextBankStaff() {
        return this.nextBankStaff;
    }

    /**抽象处理方法,等待子类实现*/
    public abstract void handleLoan(LoanRequest request);
}

复制代码

银行柜员实现——BankTeller

package io.github.brightloong.design.chain;

/** * Created by BrightLoong on 2018/5/17. */
public class BankTeller extends BankStaff {
    public void handleLoan(LoanRequest request) {
        if (request.getLoanAmount() <= 20000) {
            System.out.println(request.getName() + "申请贷款:" + request.getLoanAmount() + "元," + "由银行柜员处理。" );
        } else if (getNextBankStaff() != null) {
            getNextBankStaff().handleLoan(request);
        } else {
            System.out.println("没法处理的贷款请求。");
        }
    }
}

复制代码

银行经理实现——BankManager

package io.github.brightloong.design.chain;

/** * Created by BrightLoong on 2018/5/17. */
public class BankManager extends BankStaff{
    public void handleLoan(LoanRequest request) {
        if (request.getLoanAmount() <= 100000) {
            System.out.println(request.getName() + "申请贷款:" + request.getLoanAmount() + "元," + "由银行经理处理。" );
        } else if (getNextBankStaff() != null) {
            getNextBankStaff().handleLoan(request);
        } else {
            System.out.println("没法处理的贷款请求。");
        }
    }
}

复制代码

银行行长实现——BankPresident

package io.github.brightloong.design.chain;

/** * Created by BrightLoong on 2018/5/17. */
public class BankPresident extends BankStaff {
    public void handleLoan(LoanRequest request) {
        System.out.println(request.getName() + "申请贷款:" + request.getLoanAmount() + "元," + "由银行行长处理。" );
    }
}

复制代码

客户端调用和输出

package io.github.brightloong.design.chain;

/** * Created by BrightLoong on 2018/5/17. */
public class Client {
    public static void main(String[] args) {
        //构造职责链
        BankStaff bankTeller = new BankTeller();
        BankStaff bankManager = new BankManager();
        BankStaff bankPresident = new BankPresident();
        bankTeller.setNextBankStaff(bankManager);
        bankManager.setNextBankStaff(bankPresident);

        //构造请求
        LoanRequest request = new LoanRequest(10000L, "小明");
        bankTeller.handleLoan(request);

        LoanRequest request2 = new LoanRequest(200000L, "老王");
        bankTeller.handleLoan(request2);
    }
}

复制代码

输出结果:函数

小明申请贷款:10000元,由银行柜员处理。
老王申请贷款:200000元,由银行行长处理。
复制代码

四. 总结

使用场景

  • 有多个对象能够处理同一个请求,具体哪一个对象处理该请求由运行时刻自动肯定。
  • 在不明确接收者的状况下,向多个对象中的一个处理提交一个请求。
  • 可动态指定一组对象处理请求。

优势

  • 实现了请求发送者和接收者的解耦,下降了耦合度。
  • 方便扩展,能够方便的增长请求处理类。
  • 能够动态的设置请求处理类的顺序,比较灵活。
  • 接收者和发送者都没有对方的明确信息,且链中的对象本身也并不知道链的结构。结果是职责链可简化对象的相互链接,它们仅须要保持一个指向后继者的引用。

缺点

  • 请求有可能到了链的末端都得不处处理,或者由于没有正确配置而得不处处理。
  • 若是要配置比较复杂的链会致使性能受到影响,而且难于调试,易于出错

参考:http://www.runoob.com/design-pattern/chain-of-responsibility-pattern.html性能

相关文章
相关标签/搜索