一、什么是责任链?

「责任链模式」 是一种行为设计模式, 允许你将请求沿着处理者链进行发送。收到请求后, 每个处理者均可对请求进行处理, 或将其传递给链上的下个处理者。
设计模式--责任链模式_客户端

二、如果不用责任链模式会怎么样?

这里我举个例子说明下‘’

假设现在有一个闯关游戏,进入下一关的条件是上一关的分数要高于xx

1、 游戏一共3个关卡;
2、 进入第二关需要第一关的游戏得分大于等于80;
3、 进入第三关需要第二关的游戏得分大于等于90;

代码如下:

//第一关
public class FirstPassHandler {
public int handler(){
System.out.println("第一关-->FirstPassHandler");
return 80;
}
}

//第二关
public class SecondPassHandler {
public int handler(){
System.out.println("第二关-->SecondPassHandler");
return 90;
}
}
//第三关
public class ThirdPassHandler {
public int handler(){
System.out.println("第三关-->ThirdPassHandler,这是最后一关啦");
return 95;
}
}

//客户端
public class HandlerClient {
public static void main(String[] args) {

FirstPassHandler firstPassHandler = new FirstPassHandler();//第一关
SecondPassHandler secondPassHandler = new SecondPassHandler();//第二关
ThirdPassHandler thirdPassHandler = new ThirdPassHandler();//第三关

int firstScore = firstPassHandler.handler();
//第一关的分数大于等于80则进入第二关
if(firstScore >= 80){
int secondScore = secondPassHandler.handler();
//第二关的分数大于等于90则进入第二关
if(secondScore >= 90){
thirdPassHandler.handler();
}
}
}
}

那么如果这个游戏有100关,我们的代码很可能就会写成这个样子

if(第1关通过){
// 第2关 游戏
if(第2关通过){
// 第3关 游戏
if(第3关通过){
// 第4关 游戏
if(第4关通过){
// 第5关 游戏
if(第5关通过){
// 第6关 游戏
if(第6关通过){
//...
}
}
}
}
}
}

这种代码不仅冗余,并且当我们要将某两关进行调整时会对代码非常大的改动,这种操作的风险是很高的,因此,该写法非常糟糕

三、使用责任链改造

  • 既然每个关卡中都有下一关的 成员变量并且是不一样的,那么我们可以在关卡上抽象出一个父类或者接口,然后每个具体的关卡去继承或者实现

有了思路,我们先来简单介绍一下责任链设计模式的「基本组成」

  • 抽象处理者(Handler)角色:定义一个处理请求的接口,包含抽象处理方法和一个后继连接。
  • 具体处理者(Concrete Handler)角色:实现抽象处理者的处理方法,判断能否处理本次请求,如果可以处理请求则处理,否则将该请求转给它的后继者。
  • 客户类(Client)角色:创建处理链,并向链头的具体处理者对象提交请求,它不关心处理细节和请求的传递过程。

设计模式--责任链模式_java_02
代码如下:

public abstract class AbstractHandler {

/**
* 下一关用当前抽象类来接收
*/
protected AbstractHandler next;

public void setNext(AbstractHandler next) {
this.next = next;
}

public abstract int handler();
}

public class FirstPassHandler extends AbstractHandler{

private int play(){
return 80;
}

@Override
public int handler(){
System.out.println("第一关-->FirstPassHandler");
int score = play();
if(score >= 80){
//分数>=80 并且存在下一关才进入下一关
if(this.next != null){
return this.next.handler();
}
}
return score;
}
}

public class SecondPassHandler extends AbstractHandler{

private int play(){
return 90;
}

public int handler(){
System.out.println("第二关-->SecondPassHandler");

int score = play();
if(score >= 90){
//分数>=90 并且存在下一关才进入下一关
if(this.next != null){
return this.next.handler();
}
}

return score;
}
}

public class ThirdPassHandler extends AbstractHandler{

private int play(){
return 95;
}

public int handler(){
System.out.println("第三关-->ThirdPassHandler");
int score = play();
if(score >= 95){
//分数>=95 并且存在下一关才进入下一关
if(this.next != null){
return this.next.handler();
}
}
return score;
}
}

public class HandlerClient {
public static void main(String[] args) {

FirstPassHandler firstPassHandler = new FirstPassHandler();//第一关
SecondPassHandler secondPassHandler = new SecondPassHandler();//第二关
ThirdPassHandler thirdPassHandler = new ThirdPassHandler();//第三关

// 和上面没有更改的客户端代码相比,只有这里的set方法发生变化,其他都是一样的
firstPassHandler.setNext(secondPassHandler);//第一关的下一关是第二关
secondPassHandler.setNext(thirdPassHandler);//第二关的下一关是第三关

//说明:因为第三关是最后一关,因此没有下一关

//从第一个关卡开始
firstPassHandler.handler();

}
}