使编程更有灵活性一—责任链模式

责任链模式介绍
        责任链模式(Iterator Patern),是行为型设计模式之一。什么是“链”?我们将多个节点首尾相连所构成的模型称为链,比如生活中常见的锁链,就是由一个个圆角长方形的铁环串起来的结构。对于链式结构,每个节点都可以被拆开再连接,因此,链式结构也具有很好的灵活性。将这样一种结构应用于编程领域,将每一个节点看作是一个对象,每一个对象拥有不同的处理逻辑,将一个请求从链式的首端发出,沿着链的路径依次传递给每一个节点对象,直至有对象处理这个请求为止,我们将这样的一种模式称为责任链模式,这样的解释是不是更通俗易懂呢?我们还是看看责任链模式的标准定义。

责任链模式的定义
使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,只到有对象处理它为止。

责任链模式的使用场景
多个对象可以处理同一请求,但具体由哪个对象处理则在运行时动态决定。
在请求处理者不明确的情况下向多个对象中的一个提交一个请求。

需要动态指定一组对象处理请求。

责任链模式的UML类图

责任链模式的UML类图如图9-1所示。

根据类图我们可以得出如下一个责任链模式简化版的通用模式代码。

//抽象处理者
public abstract class Handler {
    protected Handler successor;//下一节点的处理者

    /**
     * 请求处理
     *
     * @paran condition 请求条件
     */
    public abstract void handleRequest(String condition);
}
//具体的处理者1
public class ConcreteHandler1 extends Handler {

    @Override
    public void handleRequest(String condition) {
        if (condition.equals("ConcreteHandler1")) {
            System.out.println("ConcreteHandler1 handled");
            return;
        } else {
            successor.handleRequest(condition);
        }
    }
}
//具体的处理者2
public class ConcreteHandler2 extends Handler {

    @Override
    public void handleRequest(String condition) {

        if (condition.equals("ConcreteHandler2")) {
            System.out.println("ConcreteHandler2 handled");
            return;
        } else {
            successor.handleRequest(condition);
        }
    }
}
//客户类
public class client {
    public static void main(String[] args) {
        //构造一个concreteHandler1对象
        ConcreteHandler1 handler1 = new ConcreteHandler1();
        //构造一个Concretelandler2对象
        ConcreteHandler2 handler2 = new ConcreteHandler2();
        //设置handler1的下一个节点
        handler1.successor = handler2;
        //设置handler2的下一节点
        handler2.successor = handler1;
        //处理请求
        handler1.handleRequest("ConcreteHandler2");
    }
}
角色介绍
     Handler:抽象处理者角色,声明一个请求处理的方法,并在其中保持一个对下一个处理节点Handler对象的引用。
     ConcreteHandler:具体处理者角色,对请求进行处理,如果不能处理则将该请求转发给下一个节点上的处理对象。
     上面我们说到这是一个简化版的通用模式代码,为什么这么说呢?因为对于请求来说,其形式是固定的,就是一个字符串,而判断一个节点上的对象是否能够处理该请求的标志,则是该字符串
 是否与之匹配。然而在大多数情况下,责任链中的请求和对应的处理规则是不尽相同的,在这种情况下可以将请求进行封装,同时对请求的处理规则也进行封装作为一个独立的对象,类图如

        图9-2所示。
 
首先我们来看AbstractHandler抽象处理者,其声明了处理者对象处理请求的方法和获取级别的方法,并对具体的处理转发逻辑进行了实现。
//抽象处理者
public abstract class AbstractHandler {
    protected AbstractHandler nextHandler;//下一节点上的处理者对象

    /**
     * 处理请求
     * <p>
     * <p>
     * paran request请求对象
     **/

    public final void handleRequest(AbstractRequest request) {

        //判断当前处理者对象的处理级别是否与请求者的处理级别一致
        if (getHandleLevel() == request.getRequestLevel()) {
            // 一致则由该处理对象处理
            handle(request);
        } else {
            //否则将该请求对象转发给下一个节点上的请求对象
            if (nextHandler != null) {

                nextHandler.handleRequest(request);
            } else {
                //当所有处理者对象均不能处理该请求时输出

                System.out.println("Al1 of handler can not handle the request");
            }
        }
    }

    /**
     * 获取处理者对象的处理级别
     *
     * @return处理级别
     */
    protected abstract int getHandleLevel();

    /* 每个处理者对象的具体处理方式
    * @param request请求者对象
    */
    protected abstract void handle(AbstractRequest request);
}

在这种情况下我们的责任转发逻辑由抽象处理类控制,而对于抽象请求者,其内部也声明了一个获取请求级别的方法,其与抽象处理者中返回的处理级别 保持对应,什么级别的处理逻辑就对应什么样的请求级别.
//抽象请求者
public abstract class AbstractRequest {
    private Object obj;//处理来器
    public AbstractRequest(Object obj) {
        this.obj = obj;
    }
    // 获取处理的内容对象
    public Object getContent() {
        return obj;
    }

    /**
     * 获取请求级别
     */
    public abstract int getRequestLevel();
}
其他的就不多介绍了,我们分别实现了3个请求者和3个处理者对象,逻辑很简单。
//请求者
public class Request1 extends AbstractRequest {

    public Request1(Object obj) {
        super(obj);
    }

    @Override
    public int getRequestLevel() {

        return 1;
    }
}

public class Request2 extends AbstractRequest {

    public Request2(Object obj) {

        super(obj);
    }

    @Override
    public int getRequestLevel() {
        return 2;
    }
}

public class Request3 extends AbstractRequest {

    public Request3(Object obj) {
        super(obj);
    }

    @Override
    public int getRequestLevel() {
        return 3;
    }
}
//处理者
public class Handler1 extends AbstractHandler {
    @Override
    protected int getHandleLevel() {
        return 1;
    }
    @Override
    protected void handle(AbstractRequest request) {
        System.out.println("Handle1 handle request:" + request.getRequestLevel());
    }//处理者
}

public class Handler2 extends AbstractHandler {
    @Override
    protected int getHandleLevel() {
        return 2;
    }

    @Override
    protected void handle(AbstractRequest request) {
        System.out.println("Handle2 handle request:" + request.getRequestLevel());
    }//处理者
}

public class Handler3 extends AbstractHandler {
    @Override
    protected int getHandleLevel() {
        return 3;
    }
    @Override
    protected void handle(AbstractRequest request) {
        System.out.println("Handle3 handle request:" + request.getRequestLevel());
    }
}

下面是客产类,具你的输出结果大家可以自行尝试,这里不再介绍。
//客户类
public class Client {
    public static void main(String[] args) {
        //构造3个处理者对象
        AbstractHandler handler1 = new Handler1();
        AbstractHandler handler2 = new Handler2();
        AbstractHandler handler3 = new Handler3();

        //设置当前处理者对象下一个节点的处理者对象
        handler1.nextHandler = handler2;
        handler2.nextHandler = handler3;

        //构造3个请求者对象
        AbstractRequest request1 = new Request1("Request1");
        AbstractRequest request2 = new Request2("Request2");
        AbstractRequest request3 = new Request3("Request3");

        //总是从链式的首端发起请求
        handler1.handleRequest(request1);
        handler1.handleRequest(request2);
        handler1.handleRequest(request3);
    }
}











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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值