java设计模式-责任链模式

责任链模式概念

责任链模式为请求创建了一个接收者对象的链,每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,沿着这条链传递请求,直到有对象处理它为止。

责任链模式解决的事

客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了。

看可以用到的场景:

1、有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。

2、在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。

3、可动态指定一组对象处理请求。

简单实现一下:

package com.example.designmode.crp;

import lombok.AllArgsConstructor;
import lombok.Data;

/**
 * <h3>design-mode</h3>
 * <p>定义一个请求</p>
 *
 * @author : ZhangYuJie
 * @date : 2022-06-19 19:09
 **/
@Data
@AllArgsConstructor
public class Request {
    private String name;

    private int days;

}

package com.example.designmode.crp;

import lombok.Data;

/**
 * <h3>design-mode</h3>
 * <p>定义一个返回结果</p>
 *
 * @author : ZhangYuJie
 * @date : 2022-06-19 19:10
 **/
@Data
public class Result {
    private boolean agree;

    public Result(boolean agree) {
        this.agree = agree;
    }
}

package com.example.designmode.crp;

/**
 * <h3>design-mode</h3>
 * <p></p>
 *
 * @author : ZhangYuJie
 * @date : 2022-06-19 19:10
 **/

public interface Handler {
    /**
     * 每个处理器持有链,能取到链上的请求或者传递请求
     * @param chain
     * @return
     */
    Result deal(Chain chain);

    interface Chain {
        /**
         * 获取请求
         * @return
         */
        Request request();

        /**
         * 传递请求
         * @param request
         * @return
         */
        Result proceed(Request request);
    }
}

package com.example.designmode.crp;

import java.util.LinkedList;
import java.util.Queue;

/**
 * <h3>design-mode</h3>
 * <p>定义一个处理接口的链</p>
 *
 * @author : ZhangYuJie
 * @date : 2022-06-19 19:11
 **/

public class HandlerChain implements Handler.Chain {
    /**
     * 持有链要处理的请求
     */
    private final Request request;
    /**
     * 持有链上所有的处理器
     */
    private Queue<Handler> handlers;

    public HandlerChain(Request request) {
        this.request = request;
    }

    /**
     * <h3>design-mode</h3>
     * <p>添加处理器</p>
     * @param handler
     * @return
     */
    public HandlerChain addHandler(Handler handler) {
        if (handlers == null) {
            handlers = new LinkedList<>();
        }
        handlers.add(handler);
        return this;
    }

    /**
     * 实现接口的方法- 获取请求
     * @return
     */
    public Request request() {
        return request;
    }

    /**
     * 实现接口的方法- 处理请求
     * @param request
     * @return
     */
    public Result proceed(Request request) {
        // 取队首的处理器开始请求。如果队首的处理器处理了,直接返回结果
        // 如果队首的处理器选择传递请求,又会进这个proceed方法。取新的队首处理
        // 为什么是传递而不是直接遍历队列,如果result = null,继续;result != null,返回呢? 因为传递的方式,可以对request再次处理。A处理器可以做简单处理,再传递给B。
        Handler handler = handlers.poll();
        assert handler != null;
        return handler.deal(this);
    }
}

定义三个处理者
package com.example.designmode.crp;

/**
 * <h3>design-mode</h3>
 * <p></p>
 *
 * @author : ZhangYuJie
 * @date : 2022-06-19 19:11
 **/

public class AHandler implements Handler {
    public Result deal(Chain chain) {
        Request request = chain.request();
        // 只处理小于等于1的请求,大于1的请求被传递了
        if (request.getDays() > 1) {
            // 这里可以对request做部分处理,再传递
            return chain.proceed(request);
        }
        System.out.println("A处理了");
        return new Result(true);
    }
}


package com.example.designmode.crp;

public class BHandler implements Handler {
    public Result deal(Chain chain) {
        Request request = chain.request();
        // 只处理小于等于2的请求,大于2的请求被传递了
        if (request.getDays() > 2) {
            return chain.proceed(request);
        }
        System.out.println("B处理了");
        return new Result(true);
    }
}

package com.example.designmode.crp;

public class CHandler implements Handler {
    public Result deal(Chain chain) {
        Request request = chain.request();
        // 只处理小于等于3的请求,大于3的请求被传递了
        if (request.getDays() > 3) {
            return chain.proceed(request);
        }
        System.out.println("C处理了");
        return new Result(true);
    }
}

测试
package com.example.designmode.crp;

/**
 * <h3>design-mode</h3>
 * <p></p>
 *
 * @author : ZhangYuJie
 * @date : 2022-06-19 19:13
 **/

public class Test {
    public static void main(String[] args) {
        // new 一个链,往链上添加处理器
        Request request1 = new Request("ZYJ", 3);
        HandlerChain chains = new HandlerChain(request1)
                .addHandler(new AHandler())
                .addHandler(new BHandler())
                .addHandler(new CHandler());
        Result result1 = chains.proceed(request1);
        System.out.println("结果:" + result1.isAgree());
    }
}

输出结果

传入3:
返回:
C处理了
结果:true

传入2:
返回:
B处理了
结果:true

传入1:
返回:
A处理了
结果:true

通过这个demo发现这种模式可以在一定的场景下代替掉if else

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值