设计模式(六):责任链模式

责任链设计模式是行为设计模式之一。

责任链模式用于在软件设计中实现松散耦合,其中来自客户端的请求被传递到对象链以处理它们。然后链中的对象将自己决定谁将处理请求以及是否需要将请求发送到链中的下一个对象。

JDK中的责任链模式示例

让我们看一下JDK中责任链模式的例子,然后我们将继续实现这种模式的真实例子。我们知道在try-catch块代码中我们可以有多个catch块。这里每个catch块都是处理该特定异常的处理器。

因此当try块中发生任何异常时,它会发送到第一个catch块进行处理。如果catch块无法处理它,它会将请求转发到链中的下一个对象,即下一个catch块。如果即使最后一个catch块也无法处理它,那么异常将被抛出链接到调用程序。

责任链设计模式示例

责任链模式的一个很好的例子是ATM分配机器。用户按照定义的货币账单输入要分配的金额和机器分配金额,例如50美元,20美元,10美元等。
如果用户输入的数量不是10的倍数,则会引发错误。我们将使用Chain of Responsibility模式来实现此解决方案。链将以与下图相同的顺序处理请求。

请注意,我们可以在单应用程序中轻松实现此解决方案,但随后复杂性将增加,解决方案将紧密耦合。因此,我们将创建一系列分配系统,以分配50美元,20美元和10美元的账单。

责任链设计模式 - 基类和接口

我们可以创建一个类Currency来存储分配和链实现使用的数量。
Currency.java

package com.journaldev.design.chainofresponsibility;

public class Currency {

    private int amount;

    public Currency(int amt){
        this.amount=amt;
    }

    public int getAmount(){
        return this.amount;
    }
}

基接口应该有一个方法来定义链中的下一个处理器以及处理请求的方法。我们的ATM Dispense界面如下所示。
DispenseChain.java

package com.journaldev.design.chainofresponsibility;

public interface DispenseChain {

    void setNextChain(DispenseChain nextChain);

    void dispense(Currency cur);
}

责任链模式 - 链实现

我们需要创建不同的处理器类来实现DispenseChain接口并提供分配方法的实现。由于我们正在开发我们的系统以使用三种类型的货币账单--50美元,20美元和10美元,我们将创建三个具体实施。
Dollar50Dispenser.java

package com.journaldev.design.chainofresponsibility;

public class Dollar50Dispenser implements DispenseChain {

    private DispenseChain chain;

    @Override
    public void setNextChain(DispenseChain nextChain) {
        this.chain=nextChain;
    }

    @Override
    public void dispense(Currency cur) {
        if(cur.getAmount() >= 50){
            int num = cur.getAmount()/50;
            int remainder = cur.getAmount() % 50;
            System.out.println("Dispensing "+num+" 50$ note");
            if(remainder !=0) this.chain.dispense(new Currency(remainder));
        }else{
            this.chain.dispense(cur);
        }
    }

}

Dollar20Dispenser.java

package com.journaldev.design.chainofresponsibility;

public class Dollar20Dispenser implements DispenseChain{

    private DispenseChain chain;

    @Override
    public void setNextChain(DispenseChain nextChain) {
        this.chain=nextChain;
    }

    @Override
    public void dispense(Currency cur) {
        if(cur.getAmount() >= 20){
            int num = cur.getAmount()/20;
            int remainder = cur.getAmount() % 20;
            System.out.println("Dispensing "+num+" 20$ note");
            if(remainder !=0) this.chain.dispense(new Currency(remainder));
        }else{
            this.chain.dispense(cur);
        }
    }

}

Dollar10Dispenser.java

package com.journaldev.design.chainofresponsibility;

public class Dollar10Dispenser implements DispenseChain {

    private DispenseChain chain;

    @Override
    public void setNextChain(DispenseChain nextChain) {
        this.chain=nextChain;
    }

    @Override
    public void dispense(Currency cur) {
        if(cur.getAmount() >= 10){
            int num = cur.getAmount()/10;
            int remainder = cur.getAmount() % 10;
            System.out.println("Dispensing "+num+" 10$ note");
            if(remainder !=0) this.chain.dispense(new Currency(remainder));
        }else{
            this.chain.dispense(cur);
        }
    }

}

这里要注意的重点是分配方法的实施。您会注意到每个实现都在尝试处理请求,并且根据数量,它可能会处理部分或全部部分。
如果其中一个链不能完全处理它,它会将请求发送到链中的下一个处理器以处理剩余的请求。如果处理器无法处理任何内容,它只会将相同的请求转发到下一个链。

责任链设计模式 - 创建链

这是非常重要的一步,我们应该仔细创建链,否则处理器可能根本没有得到任何请求。例如,在我们的实现中,如果我们将第一个处理器链保持为Dollar10Dispenser然后Dollar20Dispenser,那么请求将永远不会被转发到第二个处理器,并且链将变得无用。

这是我们的ATM Dispenser实现,用于处理用户请求的数量。

ATMDispenseChain.java

package com.journaldev.design.chainofresponsibility;

import java.util.Scanner;

public class ATMDispenseChain {

    private DispenseChain c1;

    public ATMDispenseChain() {
        // initialize the chain
        this.c1 = new Dollar50Dispenser();
        DispenseChain c2 = new Dollar20Dispenser();
        DispenseChain c3 = new Dollar10Dispenser();

        // set the chain of responsibility
        c1.setNextChain(c2);
        c2.setNextChain(c3);
    }

    public static void main(String[] args) {
        ATMDispenseChain atmDispenser = new ATMDispenseChain();
        while (true) {
            int amount = 0;
            System.out.println("Enter amount to dispense");
            Scanner input = new Scanner(System.in);
            amount = input.nextInt();
            if (amount % 10 != 0) {
                System.out.println("Amount should be in multiple of 10s.");
                return;
            }
            // process the request
            atmDispenser.c1.dispense(new Currency(amount));
        }

    }

}

当我们运行上面的应用程序时,我们得到如下的输出。

Enter amount to dispense
530
Dispensing 10 50$ note
Dispensing 1 20$ note
Dispensing 1 10$ note
Enter amount to dispense
100
Dispensing 2 50$ note
Enter amount to dispense
120
Dispensing 2 50$ note
Dispensing 1 20$ note
Enter amount to dispense
15
Amount should be in multiple of 10s.

责任链设计模式类图

我们的ATM分配示例的责任链设计模式实现如下图所示。

责任链设计模式重点

  • 客户端不知道链的哪个部分将处理请求,它将把请求发送到链中的第一个对象。例如,在我们的程序中,ATMDispenseChain不知道谁在处理分配输入金额的请求。
  • 链中的每个对象都有自己的实现来处理请求,全部或部分或将其发送到链中的下一个对象。
  • 链中的每个对象都应该引用链中的下一个对象来转发请求,它由java组成。
  • 仔细创建链非常重要,否则可能会出现请求永远不会转发到特定处理器或链中没有能够处理请求的对象的情况。在我的实现中,我添加了对用户输入数量的检查,以确保它被所有处理器完全处理,但是如果请求到达最后一个对象并且链中没有其他对象,我们可能不检查它并抛出异常将请求转发给。这是一个设计决定。
  • 责任链设计模式很好地实现了失去耦合,但如果大多数代码在所有实现中都很常见,那么它会带来很多实现类和维护问题的权衡。

JDK中的责任链模式示例

  • java.util.logging.Logger#log()
  • javax.servlet.Filter#doFilter()

这就是责任链设计模式的全部内容,我希望你喜欢它,并且能够清楚你对这种设计模式的理解。

翻译:journaldev

原文地址:https://www.cnblogs.com/jajian/p/9743922.html

时间: 2024-08-02 16:54:28

设计模式(六):责任链模式的相关文章

设计模式之责任链模式20170717

行为型设计模式之责任链模式: 一.含义 责任链模式的核心在"链"上,"链"是由多个处理者(对象)组成的,由这条链传递请求,直到有对象处理它为止(在链中决定谁来处理这个请求),并返回相应的结果 二.代码说明 1.主要有两个角色 1)处理者 它能够对请求做出处理(请求得到处理则直接返回,否则传到下一个处理者),设置下一个处理者(这两个操作可以抽象出来), 同时每个处理者都有一个相应的处理级别,以及具体的处理操作(父类实现请求传递,子类实现请求处理) 2)被处理者(请求者

设计模式之责任链模式--- Pattern chain-of-responsibility

模式的定义 责任链模式定义如下: Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request.Chain the receiving objects and pass the request along the chain until an object handles it. 使多个对象都有机会处理请求,从而避免请求的发送

设计模式_责任链模式

定义 Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request.Chain the receiving objects and pass the request along the chain until an object handles it.(使多个对象都有机会处理请求.从而避免了请求的发送者和接受者之间的耦合关系.

Java设计模式之责任链模式、职责链模式

本文继续介绍23种设计模式系列之职责链模式. 什么是链 1.链是一系列节点的集合. 2..链的各节点可灵活拆分再重组. 职责链模式 使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系, 将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理他为止. 角色 抽象处理者角色(Handler):定义出一个处理请求的接口.如果需要,接口可以定义 出一个方法以设定和返回对下家的引用.这个角色通常由一个Java抽象类或者Java接口实现. 具体处理者角色(ConcreteHan

C#设计模式:责任链模式

设计模式是面向对象编程的基础,是用于指导程序设计.在实际项目开发过程中,并不是一味将设计模式进行套用,也不是功能设计时大量引入设计模式.应该根据具体需求和要求应用适合的设计模式.设计模式是一个老话题了,因为最近在设计“网关API”组件(后续介绍),采用“责任链设计模式”进行设计,所以先进行回顾记录.  一.责任链模式介绍 责任链模式是指一个处理需要涉及多个过程或者角色参与处理,并基于某个约定组成一个链,每个过程或者角色拥有各自职责进行处理.责任链模式有效组织一个过程处理,同时子过程之间职责明确.

【GOF23设计模式】责任链模式

来源:http://www.bjsxt.com/ 一.[GOF23设计模式]_责任链模式.公文审批.供应链系统的采购审批.异常链.过滤器和拦截器调用过程 1 package com.test.chainOfResp; 2 /** 3 * 封装请假的基本信息 4 */ 5 public class LeaveRequest { 6 private String empName; 7 private int leaveDays; 8 private String reason; 9 10 publi

Head First设计模式之责任链模式

一.定义 避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止. 主要解决:职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了. 何时使用:在处理消息的时候以过滤很多道. 如何解决:拦截的类都实现统一接口. 二.结构 从责任链模式的定义可以发现,责任链模式涉及的对象只有处理者角色,但由于有多个处理者,它们具有共同的处理请求的

23种设计模式之责任链模式(Chain of Responsibility)

责任链模式是一种对象的行为型模式,避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止.责任链模式不保证每个请求都被接受,由于一个请求没有明确的接收者,那么就不能保证它一定会被处理. 优点: 1)降低了耦合度. 2)增加向对象指定责任的灵活性. 3)由于在一个类中产生的事件可以被发送到组成中的其它类处理器上,类的集合可以作为一个整体. 使用场景: 1)多个对象可以处理一个请求,而其处理器却是未知的. 2)想要在不指定确

五分钟一个设计模式之责任链模式

五分钟一个设计模式,用最简单的方法来描述设计模式.查看更多设计模式,请点击五分钟一个设计模式系列 http://blog.csdn.net/daguanjia11/article/category/3259443 请假流程 假设现在一个公司的请假流程如下:一天及以下由小组组长审批,一天以上三天以下由经理审批,三天以上七天以下由老板审批,七天以上直接劝退. 如果每次请假时都很长的if-else-来判断该去找谁请假,很不容易扩展,我们使用责任链模式来实现. 首先,是一个抽象的父类 public ab

入门设计模式之责任链模式

学习更多设计模式请参考:入门设计模式之汇总篇 责任链模式:很多对象由每一个对象对其下家的引用而连接起来行成的一条链. 其实责任链模式一直在我们的身边.某一天,董事长有个想法,他吩咐给了经理,经理吩咐给了组长,组长分配给了你我.这时候我们发现,我们没有下级了呀,咋办,那就干呗. 上方这个任务分配的过程就是责任链模式,一个事件会一直向下层传递,董事长并不关心是谁解决的这个问题,对他来说只要问题解决了就行. Handle:抽象处理者,可理解为抽象的员工(经理组长普通程序员等都是继承了员工) Handl