设计模式之责任链模式--- Pattern chain-of-responsibility

模式的定义

责任链模式定义如下:

Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request.Chain the receiving objects and pass the request along the chain until an object handles it.

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

类型

行为类

模式的使用场景

一个请求可以被多个处理者处理或处理者未明确指定时

UML类图

设计模式之责任链模式--- Pattern chain-of-responsibility_第1张图片

角色介绍

Handler类—–抽象处理者类,
抽象处理类实现三个职责:
一是定义一个请求处理方法handlerMessage,唯一一个对外开放的方法
二是定义一个链的编译方法setNext,设置下一个处理者
三是定义具体的处理者必须实现的方法:getHandlerLevel和echo

ConcreteHandler类—具体处理者类
实现几个具体处理者类,形成一个处理消息的链

模式的通用源码

抽象处理者—Handler:


public abstract class Handler {

    private Handler nextHandler;
    //设置下一个处理者是谁
    public void setNext(Handler nextHandler){
        this.nextHandler = nextHandler;
    }
    //获取处理request的level
    protected abstract Level getHandlerLevel();
    //每个处理者处理request的逻辑
    protected abstract Response echo(Request request);
    //每个处理者都必须对Request 做出处理
    public final Response handlerMessage(Request request){

        Response response = null;
        //判断是否自己可以处理
        if(request.getLevel().getId() == (getHandlerLevel().getId())){
            response = echo(request);
            System.out.println("response:"+response);
        }else {
    //不是自己处理的级别
            //判断是否有下一个处理者
            if(nextHandler != null){

                response = nextHandler.handlerMessage(request);
            }else {
                //Response没有处理者
                response = new Response("request do not handle");
                System.out.println("response:"+response);
            }
        }           
        return response;
    }
}

抽象处理类实现三个职责:
一是定义一个请求处理方法handlerMessage,唯一一个对外开放的方法
二是定义一个链的编译方法setNext,设置下一个处理者
三是定义具体的处理者必须实现的方法:getHandlerLevel和echo

具体处理者:

ConcreteHandler1:


public class ConcreteHandler1 extends Handler {
     

    @Override
    protected Level getHandlerLevel() {
        // TODO Auto-generated method stub
        return new Level(1);
    }

    @Override
    protected Response echo(Request request) {
        // TODO Auto-generated method stub
        System.out.println("ConcreteHandler1----echo:"+request);
        return new Response("ConcreteHandler1---echo:"+request);
    }

}

ConcreteHandler2:


public class ConcreteHandler2 extends Handler {
     

    @Override
    protected Level getHandlerLevel() {
        // TODO Auto-generated method stub
        return new Level(2);
    }

    @Override
    protected Response echo(Request request) {
        // TODO Auto-generated method stub
        System.out.println("ConcreteHandler2----echo:"+request);
        return new Response("ConcreteHandler2---echo:"+request);
    }

}

ConcreteHandler3:


public class ConcreteHandler3 extends Handler {
     

    @Override
    protected Level getHandlerLevel() {
        // TODO Auto-generated method stub
        return new Level(3);
    }

    @Override
    protected Response echo(Request request) {
        // TODO Auto-generated method stub
        System.out.println("ConcreteHandler3----echo:"+request);
        return new Response("ConcreteHandler3---echo:"+request);
    }

}

Response 类:


public class Response {
     

    protected String responseString;

    public Response(String responseString) {
        super();
        this.responseString = responseString;
    }

    public String getResponseString() {
        return responseString;
    }

    public void setResponseString(String responseString) {
        this.responseString = responseString;
    }

    @Override
    public String toString() {
        return "Response [responseString=" + responseString + "]";
    }
}

Level 类:


public class Level {
     

    protected int id;

    public Level(int id) {
        super();
        this.id = id;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return "Level [id=" + id + "]";
    }
}

Request 类:


public class Request {
     

    protected String reString;
    protected Level level;

    public Request(String reString, Level level) {
        super();
        this.reString = reString;
        this.level = level;
    }

    public Level getLevel() {
        return level;
    }

    public void setLevel(Level level) {
        this.level = level;
    }

    public String getReString() {
        return reString;
    }

    public void setReString(String reString) {
        this.reString = reString;
    }

    @Override
    public String toString() {
        return "Request [reString=" + reString + ", level=" + level + "]";
    }
}

Client:


public class Client {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Request request1 = new Request("request_001", new Level(1));
        Request request2 = new Request("request_002", new Level(2));
        Request request3 = new Request("request_003", new Level(3));
        Request request4 = new Request("request_004", new Level(4));

        Handler h1 = new ConcreteHandler1();
        Handler h2 = new ConcreteHandler2();
        Handler h3 = new ConcreteHandler3();

        h1.setNext(h2);
        h2.setNext(h3);

        Response response1 = h1.handlerMessage(request1);
        System.out.println("------------------------------------------------------------------");
        Response response2 = h1.handlerMessage(request2);
        System.out.println("------------------------------------------------------------------");
        Response response3 = h1.handlerMessage(request3);
        System.out.println("------------------------------------------------------------------");
        Response response4 = h1.handlerMessage(request4);
    }
}

输出结果

ConcreteHandler1----echo:Request [reString=request_001, level=Level [id=1]]
response:Response [responseString=ConcreteHandler1---echo:Request [reString=request_001, level=Level [id=1]]]
------------------------------------------------------------------
ConcreteHandler2----echo:Request [reString=request_002, level=Level [id=2]]
response:Response [responseString=ConcreteHandler2---echo:Request [reString=request_002, level=Level [id=2]]]
------------------------------------------------------------------
ConcreteHandler3----echo:Request [reString=request_003, level=Level [id=3]]
response:Response [responseString=ConcreteHandler3---echo:Request [reString=request_003, level=Level [id=3]]]
------------------------------------------------------------------
response:Response [responseString=request do not handle]

优点

将请求和处理分开:请求者可以不用知道是谁处理,处理者也可以不用知道请求者,两者解耦,提高了系统的灵活性。

缺点

一是性能问题:
每个请求都是从链头遍历到链尾,特别是当链比较长的时候,性能会是一个比较大的问题
二是调试不方便:
特别是当链比较长时,环节比较多,采用类似递归的方式,调试的时候逻辑可能比较复杂。

注意事项:

链中节点数量需要控制,避免出现超长链的情况,一般的做法是在Handler中设置一个最大的节点数量,在设置setNext方法中判断是否已经超过其阈值,超过则不允许该链建立,避免无意识的破坏系统的性能。

Android源码中的模式实现

参考资料

(1).设计模式之禅—第16章 责任链模式
(2)责任链模式
https://github.com/simple-android-framework/android_design_patterns_analysis/tree/master/chain-of-responsibility/AigeStudio

你可能感兴趣的:(设计模式之样例篇,设计模式之android,android,设计模式,责任链模式)