我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Java通俗易懂系列设计模式之责任链模式

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Java通俗易懂系列设计模式之责任链模式

概述

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

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

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

责任链设计模式类图

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

责任链设计模式重点

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

JDK中的责任链模式示例

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

以上就是Java通俗易懂系列设计模式之责任链模式的详细内容,更多关于Java设计模式的资料请关注编程网其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Java通俗易懂系列设计模式之责任链模式

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Java设计模式之责任链模式的示例详解

责任链模式是将链中的每一个节点看做是一个对象,每个节点处理的请求均不相同,且内部自动维护下一个节点对象,当一个请求从链式的首段发出时,会沿着链的路径依次传递给每一个节点对象。本文将通过示例和大家详细聊聊责任链模式,需要的可以参考一下
2022-11-13

每天一个设计模式之责任链模式

作者按:《每天一个设计模式》旨在初步领会设计模式的精髓,目前采用javascript和python两种语言实现。诚然,每种设计模式都有多种实现方式,但此小册只记录最直截了当的实现方式 :)0. 项目地址责任链模式·代码《每天一个设计模式》地
2023-01-31

java设计模式中的责任链模式是什么

本篇文章为大家展示了java设计模式中的责任链模式是什么,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。一:模式说明模式定义:使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系。
2023-06-22

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录