【再探】设计模式—职责链模式、命令模式及迭代器模式-1 职责链模式

时间:2024-06-01 15:47:18

需求:1) 请求能被多个处理器处理,对处理顺序有要求。2) 请求与处理器解耦,具体被哪个处理器处理未知,可动态决定其处理器。

1.1 职责链模式介绍

通过建立一条链来组织请求的处理者。请求将沿着链进行传递,请求发送者无需知道请求在何时、何处及如何被处理,实现了请求发送者与处理者的解耦。

图 职责链模式UML

public class ChainOfResponsibility {

    public static void main(String[] args) {
        RequestHandler requestHandler = generateChain();
        List<CustomRequest> requestList = generateRequest();
        for (CustomRequest request : requestList) {
            try {
                requestHandler.handle(request);
            } catch (Exception e) {
                System.err.println(e.getMessage());
            }
        }
    }

    private static RequestHandler generateChain() {
        RequestHandler handler = new SubjectHandler();
        RequestHandler usernameHandler = new UserNameHandler(handler);
        return new IpRequestHandler(usernameHandler);
    }

    private static List<CustomRequest> generateRequest() {
        List<CustomRequest> list = new ArrayList<>();
        list.add(new CustomRequest("localhost", "user"));
        list.add(new CustomRequest("172.34.43.32", "admin"));
        list.add(new CustomRequest("172.34.24.24", "user"));
        return list;
    }

    private static class CustomRequest {
        String ip;
        String username;

        public CustomRequest(String ip, String username) {
            this.ip = ip;
            this.username = username;
        }

        @Override
        public String toString() {
            return "CustomRequest{" +
                    "ip='" + ip + '\'' +
                    ", username='" + username + '\'' +
                    '}';
        }
    }

    private static abstract class RequestHandler {

        protected final RequestHandler handler;

        public RequestHandler(RequestHandler handler) {
            this.handler = handler;
        }

        abstract void handle(CustomRequest request);
    }

    private static class IpRequestHandler extends RequestHandler{

        private static final String[] BLACK_IPS = {"localhost","127.0.0.1"};

        public IpRequestHandler(RequestHandler handler) {
            super(handler);
        }

        @Override
        void handle(CustomRequest request) {
            if (request.ip == null) {
                throw new RuntimeException("请求IP 不合法");
            } else {
                for (String str : BLACK_IPS) {
                    if (request.ip.contains(str)) throw new RuntimeException("请求IP 不合法");
                }
            }
            handler.handle(request);
        }
    }

    private static class UserNameHandler extends RequestHandler {

        public UserNameHandler(RequestHandler handler) {
            super(handler);
        }

        @Override
        void handle(CustomRequest request) {
            if (request.username == null) {
                throw new RuntimeException("用户名不能为空");
            } else {
                if (request.username.contains("admin")) throw new RuntimeException("用户名不合法");
            }
            handler.handle(request);
        }
    }

    private static class SubjectHandler extends RequestHandler {

        public SubjectHandler() {
            super(null);
        }

        @Override
        void handle(CustomRequest request) {
            System.out.println("请求到达目标处理器:" + request);
        }
    }

}

纯职责链模式

要求一个具体处理者对象只能在两个行为中选择一个:要么承担全部责任,要么将责任推给下家,而且一个请求必须被某一个处理者对象所处理。

不纯职责链模式

允许一个具体处理者部分被处理好再向下传递,或者一个具体处理者处理完某请求后,后继处理者可以继续处理该请求。一个请求最终可以不被处理。

图 职责链模式的两种类型

1.2 优缺点

优点:

  1. 将请求发送者与接收者解耦,请求发送者无需知道请求会被哪个处理器处理。
  2. 当系统需要增加一个新的处理者时,无需修改原有系统代码,符合开闭原则。

缺点:

  1. 不能保证请求一定会被处理。如果职责链没有被正确配置,则请求可能得不到处理。
  2. 如果建链不当,则可能会造成循环调用。
  3. 如果职责链较长,系统性能将受到一定影响,代码调试也不方便。