如何通关设计模式之责任链模式

责任在哪?

责任链模式看名称可以理解为责任连成一条链。这也没有什么毛病,责任链模式的重点也在于“链”上,由一条链去处理相似的请求在链中决定谁来处理这个请求,并返回相应的结果。

责任链模式的核心在“链”上,链是由多个处理者组成的。

“古代妇女的枷锁”——责任链的体现

中国古代对于妇女指定了“三从四德”的道德规范。“三从”是指“未嫁从父、既嫁从夫、夫死从子”,也就是说,一位女性在结婚前要听从于父亲,结婚后要听从于丈夫,如果丈夫死了还要听从于儿子。在父系社会中,妇女只占从属地位,想在想想中国古代的妇女还是挺悲惨的。

但是这与要讲的责任链模式有什么关系呢,确实没多大关系,只是通过这来举例说明下责任链的责任传递。假设目前是中国明朝,民间有一位女儿,生来美丽,她的一生有三种状态,未婚、已婚且丈夫健在、丈夫去世。有一天,她想去逛街,如果她处于未婚状态,则需要她向她的父亲发起一个请求是否可以去,而父亲收到这个请求后需要做出相应的回复。流程如下所示:

首先,这位女性会将去“逛街”这个请求发送给她的父亲,如何她父亲可以处理则会做出相应,否则父亲将该请求传递给她的丈夫处理,如果丈夫仍不能处理则会将请求传递给儿子进行处理。

先来看看女性这个接口以及它的实现,接口中有一个请求逛街的方法以及一个int型属性,标识她目前处于未婚、已婚且丈夫健在还是丈夫去世的哪一种状态,这也决定了她的请求由父亲、丈夫还是儿子来处理。

//抽象女性接口
public interface AbstractWomen {

	//状态等级,将决定由谁来处理她的请求
    int getLevel();
	
	//女性的请求是什么
    String getRequest();

}

//女性接口实现
public class Women implements AbstractWomen{

    private int level;
    private String request;

    public Women(int level, String request) {
        this.level = level;
        this.request = request;
    }

    @Override
    public int getLevel() {
        return this.level;
    }

    @Override
    public String getRequest() {
        return this.request;
    }
}

上面定义了女性的接口,接下来如何实现处理者的接口呢,这里我们借用模板方法模式。

/**
 * @author: zhangocean
 * @Date: 2018/12/26 16:23
 * Describe:处理类接口
 */
public abstract class Handler {

	//定义三个等级状态 
	//1:未婚,由父亲相应  
	//2:已婚,丈夫健在,由丈夫相应  
	//3:丈夫去世,由儿子相应
    public final static int FATHER_LEVEL = 1;
    public final static int HUSBAND_LEVEL = 2;
    public final static int SON_LEVEL = 3;

	//处理者可处理等级
    private int level;
	
	//处理类相应内容
    private String response;
	
	//下一个处理者
    private Handler nextHandler;

    public Handler(int level) {
        this.level = level;
    }

    public void handleMessage(AbstractWomen abstractWomen){
        //责任链模式,责任传递
        if(abstractWomen.getLevel() == level){
            this.response(abstractWomen);
        } else {
            if(this.nextHandler != null){
                this.nextHandler.handleMessage(abstractWomen);
            } else {
                System.out.println("没人处理");
            }
        }
    }

    public int getLevel() {
        return level;
    }

    public void setNextHandler(Handler nextHandler) {
        this.nextHandler = nextHandler;
    }

	//处理者相应内容
    abstract void response(AbstractWomen women);
}

使用责任链模式的精华就在于责任在链上的传递,在这个接口中我们使用到了模板方法模式,在抽象类中实现了handleMessage()的方法体,即子类不需要重写该方法(该方法作为一个模板方法),在该方法中使用递归调用处理者处理事件,如果递归到链尾仍未匹配到则打印无人处理。

//父亲实现
public class Father extends Handler {

    public Father() {
        super(Handler.FATHER_LEVEL);
    }

    @Override
    void response(AbstractWomen women) {
        System.out.println("父亲处理请求:" + women.getRequest() + ",请求等级:" + women.getLevel());
    }
}

//丈夫实现
public class Husband extends Handler {

    public Husband() {
        super(Handler.HUSBAND_LEVEL);
    }

    @Override
    void response(AbstractWomen women) {
        System.out.println("丈夫处理请求:" + women.getRequest() + ",请求等级:" + women.getLevel());
    }
}

//儿子实现
public class Son extends Handler {
    public Son() {
        super(Handler.SON_LEVEL);
    }

    @Override
    void response(AbstractWomen women) {
        System.out.println("儿子处理请求:" + women.getRequest() + ",请求等级:" + women.getLevel());
    }
}

处理者实现类比较简单,只需要在各个实现类中重写处理者相应内容即可。下面进程责任链测试代码:

public class Client {
    public static void main(String[] args) {
        Father father = new Father();
        Husband husband = new Husband();
        Son son = new Son();

		//设置下一个传递的处理者
        father.setNextHandler(husband);
        husband.setNextHandler(son);

        Random random = new Random();
        List<AbstractWomen> list = new ArrayList<>();
        for(int i=0;i<5;i++){
            list.add(new Women(random.nextInt(4), "买衣服"));
        }

        for(AbstractWomen women : list){
			//调用模板方法
            father.handleMessage(women);
        }
    }
}

打印结果如下:

丈夫处理请求:买衣服,请求等级:2
没人处理
没人处理
没人处理
儿子处理请求:买衣服,请求等级:3

责任链模式剖析

代码剖析

在上述案例代码中,一共有三位处理者,父亲、丈夫和儿子,分别可以处理的时间等级为1、2、3。一共随机生成了5位女性,她们的等级状态通过随机数生成。每一位女性只需要将请求传递给链首的处理者去处理,如果链首的处理者无法处理该等级的请求,则会传递给下一个处理者,当然,这对于请求的女性来说是透明的,她们并不知道她们的请求会被哪个处理者处理。

每一位处理者需要设置他的下一个处理者,这样才能将处理者形成一条链。当检测到没有处理者能够处理请求时,需要及时的做出一定的判断。

优点

责任链模式很好的将请求以及相应分隔开,请求者可以不知道是谁处理的,处理者不用知道请求的全貌,两者解耦,提高系统灵活性。

缺点

责任链模式有非常显著的缺点。一是性能问题,责任链模式通过在链上遍历决定事件的处理者,然而如果链过长,将会导致性能降低。二是调试很不方便,特别是链比较长时,由于采用递归的方法,调试时逻辑可能比较复杂。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值