设计模式——责任链模式

来源:互联网 发布:走淘宝联盟能用红包吗 编辑:程序博客网 时间:2024/06/05 06:18

一、什么是责任链模式?


责任链模式中,存在多个对象,每个对象持有对下一个对象的引用而形成一条链,请求在这条链上传递,直到其中某一对象决定处理该请求。然而请求发出者并不清楚最终哪一个对象会处理该请求,所以,责任链模式可以在不影响客户端的情况下,对系统进行动态的调整和重新组织。


责任链虽然叫做链,但是事实上它的结构可能是一个单向的链表,也可能是一个单向环形链表,也有可能是一个树状结构。


责任链分纯与不纯的责任链。纯责任链中,请求最终一定会被处理;不纯的责任链中,请求可以不被链中任何对象处理。


需要明确的是,责任链模式自身并不负责创建责任链,也就是说客户端对于责任链内部的组织是毫不知情的。责任链的创建需要系统的其他组件去完成。


二、责任链模式中的成员


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

四、上述例子的类图