一、什么是责任链模式?
责任链模式中,存在多个对象,每个对象持有对下一个对象的引用而形成一条链,请求在这条链上传递,直到其中某一对象决定处理该请求。然而请求发出者并不清楚最终哪一个对象会处理该请求,所以,责任链模式可以在不影响客户端的情况下,对系统进行动态的调整和重新组织。
责任链虽然叫做链,但是事实上它的结构可能是一个单向的链表,也可能是一个单向环形链表,也有可能是一个树状结构。
责任链分纯与不纯的责任链。纯责任链中,请求最终一定会被处理;不纯的责任链中,请求可以不被链中任何对象处理。
需要明确的是,责任链模式自身并不负责创建责任链,也就是说客户端对于责任链内部的组织是毫不知情的。责任链的创建需要系统的其他组件去完成。
二、责任链模式中的成员
1. 抽象处理者,这是一个处理请求的接口,接口中有一方法,可以引用链中的下一个对象。
2. 具体事务处理者,继承至抽象处理者,接到请求后有两种选择,要么传递给链中下一对象,要么自己处理,两种选择只能选择其中一种。
三、使用责任链模式来解决一个问题
我们考虑一个场景,当朋友聚会时,我们要玩一些游戏,有一个游戏是这样的:先在所有参与者中选出一位当裁判,负责发号施令,剩下所有人内部按照1,2,3…这样的顺序给自己编号,编好顺序以后,裁判将一个内部写有数字的纸团交给第一个人,如果纸团内的数字与参与者的顺序相同,该参与者要被惩罚,否则该参与者需要将纸团交给下一个玩家。这个游戏就是典型的责任链模式的一个应用,接下来我们用代码来实现下吧!
3.1 Player抽象类,抽象处理者,内部有抽象的处理(handle)方法,以及设置下一个玩家(setNextPlayer)与将纸团传递给下一个玩家(next)的方法。
package designpatterns.chainOfResponsibility;
/**
* Created by Olive on 2017/12/4.
*/
public abstract class Player {
public abstract void handle(int i);
private Player nextPlayer;
public Player(){
nextPlayer = null;
}
protected void setNextPlayer(Player nextPlayer){
this.nextPlayer = nextPlayer;
}
// next方法调用责任链中下一个的handle方法
public void next(int index){
if(nextPlayer != null){
nextPlayer.handle(index);
} else {
System.out.println("Game Over");
}
}
}
3.2 实际参与者,一共四个玩家:PlayerA,PlayerB,PlayerC,PlayerD。重写了抽象类中的处理(handle)方法,并且在构造方法中指定下一个玩家。
package designpatterns.chainOfResponsibility;
/**
* Created by Olive on 2017/12/4.
*/
public class PlayerA extends Player {
// 设定责任链中下一个用户
public PlayerA(Player nextPlayer) {
this.setNextPlayer(nextPlayer);
}
@Override
public void handle(int i) {
if (i == 1) {
System.out.println("Player A get punishment!");
} else {
System.out.println("Non't A ! Next~");
next(i);
}
}
}
public class PlayerB extends Player{
// 设定责任链中下一个用户
public PlayerB(Player nextPlayer) {
this.setNextPlayer(nextPlayer);
}
@Override
public void handle(int i) {
if (i == 2) {
System.out.println("Player B get punishment!");
} else {
System.out.println("Non't B ! Next~");
next(i);
}
}
}
public class PlayerC extends Player{
// 设定责任链中下一个用户
public PlayerC(Player nextPlayer) {
this.setNextPlayer(nextPlayer);
}
@Override
public void handle(int i) {
if (i == 3) {
System.out.println("Player C get punishment!");
} else {
System.out.println("Non't C ! Next~");
next(i);
}
}
}
public class PlayerD extends Player{
// 设定责任链中下一个用户
public PlayerD(Player nextPlayer) {
this.setNextPlayer(nextPlayer);
}
@Override
public void handle(int i) {
if (i == 4) {
System.out.println("Player D get punishment!");
} else {
System.out.println("Non't D ! Next~");
next(i);
}
}
}
3.3 PlayGame类,开始游戏,裁判设定纸团内的数字
package designpatterns.chainOfResponsibility;
/**
* Created by Olive on 2017/12/4.
*/
public class PlayGame {
private static Player players;
public static void main(String[] args){
players = new PlayerA(new PlayerB(new PlayerC(new PlayerD(null))));
players.handle(4);
}
}
3.4 运行结果
Non't A ! Next~
Non't B ! Next~
Non't C ! Next~
Player D get punishment!
Process finished with exit code 0
四、上述例子的类图