您现在的位置是:首页 > 正文

设计模式之责任链模式

2024-02-01 05:49:13阅读 2

1. 概念

责任链设计模式是一种行为设计模式,它允许你创建一个对象链。请求从链的一端进入,并沿着链的路径依次经过各个对象,直至找到合适的处理者。每个对象都决定是否要处理该请求或将其传递给链中的下一个对象。
在这里插入图片描述

1.1 核心概念

在这里插入图片描述

  • Handler(处理者):每个处理者对象包含了处理请求的代码。处理者通常定义一个处理方法来执行请求处理,并决定是否将请求传递给下一个处理者。

  • 链(Chain):处理者按照某种方式连接在一起,构成一个处理链。请求进入链的一端,并沿着链传递直至有一个处理者处理请求或者请求到达链的末端。

  • Request(请求):请求是要被处理的对象。每个处理者检查请求并进行处理,或将其传递给下一个处理者。

1.2 工作原理

  • 当一个请求进入责任链时,它被传递给第一个处理者。
  • 处理者决定是否处理请求,如果能处理则执行相应操作,如果不能处理则将请求传递给链中的下一个处理者。
  • 这个过程会持续直到有一个处理者能够处理请求或者请求到达链的末端。

1.3 优势

  • 松散耦合:责任链模式允许你添加或修改处理者而无需修改现有代码。
  • 动态设置链:你可以动态设置处理链,在运行时指定处理者的顺序或者数量。

1.4 示例

举个例子,假设有一个报销审批系统。不同级别的员工有不同的报销限额。责任链模式可以用来构建审批流程,每个处理者代表一个管理层级,根据报销金额来决定是否批准请求。如果一个处理者无法批准请求,则将请求传递给下一个处理者,直到得到最终的审批结果。

责任链模式在很多场景下都有应用,特别是处理流程连续、需要灵活调整处理顺序的场景。

2. 举例

2.1 简单的购买审批场景

当使用责任链模式时,我们可以考虑一个简单的购买审批场景。不同级别的员工有不同的审批权限,低级别员工的审批额度小,而高级别员工有更高的审批额度。如果一个员工无法批准请求,请求将被传递给下一个更高级别的员工。

以下是一个使用Java实现责任链模式的示例:

// 定义请求类
class PurchaseRequest {
    private double amount;

    public PurchaseRequest(double amount) {
        this.amount = amount;
    }

    public double getAmount() {
        return amount;
    }
}

// 定义处理者接口
interface Approver {
    void setNext(Approver next);
    void processRequest(PurchaseRequest request);
}

// 具体处理者实现
class Manager implements Approver {
    private Approver next;
    private double approvalLimit = 1000;

    @Override
    public void setNext(Approver next) {
        this.next = next;
    }

    @Override
    public void processRequest(PurchaseRequest request) {
        if (request.getAmount() <= approvalLimit) {
            System.out.println("Manager approved the request of amount: " + request.getAmount());
        } else if (next != null) {
            next.processRequest(request);
        }
    }
}

class Director implements Approver {
    private Approver next;
    private double approvalLimit = 5000;

    @Override
    public void setNext(Approver next) {
        this.next = next;
    }

    @Override
    public void processRequest(PurchaseRequest request) {
        if (request.getAmount() <= approvalLimit) {
            System.out.println("Director approved the request of amount: " + request.getAmount());
        } else if (next != null) {
            next.processRequest(request);
        }
    }
}

class President implements Approver {
    private double approvalLimit = 10000;

    @Override
    public void setNext(Approver next) {
        // President is the final authority, doesn't need a next
    }

    @Override
    public void processRequest(PurchaseRequest request) {
        if (request.getAmount() <= approvalLimit) {
            System.out.println("President approved the request of amount: " + request.getAmount());
        } else {
            System.out.println("Request requires higher approval.");
        }
    }
}

// 使用责任链模式
public class ChainOfResponsibilityExample {
    public static void main(String[] args) {
        Approver manager = new Manager();
        Approver director = new Director();
        Approver president = new President();

        // 构建责任链
        manager.setNext(director);
        director.setNext(president);

        // 发起请求
        PurchaseRequest request1 = new PurchaseRequest(500);
        manager.processRequest(request1);

        PurchaseRequest request2 = new PurchaseRequest(2500);
        manager.processRequest(request2);

        PurchaseRequest request3 = new PurchaseRequest(15000);
        manager.processRequest(request3);
    }
}

这个例子中,我们创建了不同级别的处理者(Manager、Director、President),并设置了它们的审批额度。然后我们建立了一个责任链,通过调用 processRequest 方法来处理不同额度的购买请求。请求会从低级别的员工一直传递到更高级别的员工,直到找到能够批准请求的员工。

2.2 在线文件处理系统

我们可以想象一个在线文件处理系统。不同类型的文件需要经过不同的处理器进行处理,如图片文件、文本文件、视频文件等。每个处理器能够处理特定类型的文件,如果一个处理器无法处理该类型文件,请求将被传递给下一个处理器。

下面是一个使用责任链模式处理文件的简单示例:

// 文件处理请求
class File {
    private String fileName;
    private String fileType;

    public File(String fileName, String fileType) {
        this.fileName = fileName;
        this.fileType = fileType;
    }

    public String getFileName() {
        return fileName;
    }

    public String getFileType() {
        return fileType;
    }
}

// 文件处理器接口
interface FileHandler {
    void setNext(FileHandler next);
    void handleFile(File file);
}

// 图片文件处理器
class ImageHandler implements FileHandler {
    private FileHandler next;

    @Override
    public void setNext(FileHandler next) {
        this.next = next;
    }

    @Override
    public void handleFile(File file) {
        if (file.getFileType().equals("image")) {
            System.out.println("ImageHandler: Processing image file - " + file.getFileName());
        } else if (next != null) {
            next.handleFile(file);
        }
    }
}

// 文本文件处理器
class TextHandler implements FileHandler {
    private FileHandler next;

    @Override
    public void setNext(FileHandler next) {
        this.next = next;
    }

    @Override
    public void handleFile(File file) {
        if (file.getFileType().equals("text")) {
            System.out.println("TextHandler: Processing text file - " + file.getFileName());
        } else if (next != null) {
            next.handleFile(file);
        }
    }
}

// 视频文件处理器
class VideoHandler implements FileHandler {
    @Override
    public void setNext(FileHandler next) {
        // VideoHandler is the final handler and does not require a next handler
    }

    @Override
    public void handleFile(File file) {
        if (file.getFileType().equals("video")) {
            System.out.println("VideoHandler: Processing video file - " + file.getFileName());
        } else {
            System.out.println("No handler found for the file: " + file.getFileName());
        }
    }
}

// 使用责任链模式处理文件
public class FileHandlerExample {
    public static void main(String[] args) {
        FileHandler imageHandler = new ImageHandler();
        FileHandler textHandler = new TextHandler();
        FileHandler videoHandler = new VideoHandler();

        // 构建处理链
        imageHandler.setNext(textHandler);
        textHandler.setNext(videoHandler);

        // 发起文件处理请求
        File file1 = new File("image1.jpg", "image");
        imageHandler.handleFile(file1);

        File file2 = new File("document.txt", "text");
        imageHandler.handleFile(file2);

        File file3 = new File("video.mp4", "video");
        imageHandler.handleFile(file3);

        File file4 = new File("music.mp3", "audio");
        imageHandler.handleFile(file4);
    }
}

在这个示例中,不同类型的文件经过责任链,每个处理器(ImageHandler、TextHandler、VideoHandler)能够处理特定类型的文件。文件请求会从低级别处理器传递到更高级别处理器,直到找到能够处理该类型文件的处理器,或者请求到达责任链的末端。

2.3 简单的餐厅点餐系统

让我们考虑一个简单的餐厅点餐系统的场景。假设不同类型的菜品由不同的厨师来负责制作,而服务员负责接收顾客的点餐请求并将其传递给合适的厨师。

下面是使用责任链模式模拟餐厅点餐系统的示例:

// 餐品订单
class Order {
    private String dishName;
    private String category;

    public Order(String dishName, String category) {
        this.dishName = dishName;
        this.category = category;
    }

    public String getDishName() {
        return dishName;
    }

    public String getCategory() {
        return category;
    }
}

// 厨师接口
interface Chef {
    void setNextChef(Chef nextChef);
    void handleOrder(Order order);
}

// 中餐厨师
class ChineseChef implements Chef {
    private Chef nextChef;

    @Override
    public void setNextChef(Chef nextChef) {
        this.nextChef = nextChef;
    }

    @Override
    public void handleOrder(Order order) {
        if (order.getCategory().equalsIgnoreCase("Chinese")) {
            System.out.println("Chinese Chef is preparing " + order.getDishName());
        } else if (nextChef != null) {
            nextChef.handleOrder(order);
        }
    }
}

// 西餐厨师
class WesternChef implements Chef {
    private Chef nextChef;

    @Override
    public void setNextChef(Chef nextChef) {
        this.nextChef = nextChef;
    }

    @Override
    public void handleOrder(Order order) {
        if (order.getCategory().equalsIgnoreCase("Western")) {
            System.out.println("Western Chef is preparing " + order.getDishName());
        } else if (nextChef != null) {
            nextChef.handleOrder(order);
        }
    }
}

// 甜点厨师
class DessertChef implements Chef {
    @Override
    public void setNextChef(Chef nextChef) {
        // DessertChef is the final chef and does not require a next chef
    }

    @Override
    public void handleOrder(Order order) {
        if (order.getCategory().equalsIgnoreCase("Dessert")) {
            System.out.println("Dessert Chef is preparing " + order.getDishName());
        } else {
            System.out.println("No chef found for " + order.getDishName());
        }
    }
}

// 餐厅点餐系统使用责任链模式
public class RestaurantOrderSystem {
    public static void main(String[] args) {
        Chef chineseChef = new ChineseChef();
        Chef westernChef = new WesternChef();
        Chef dessertChef = new DessertChef();

        // 构建责任链
        chineseChef.setNextChef(westernChef);
        westernChef.setNextChef(dessertChef);

        // 发起点餐请求
        Order order1 = new Order("Kung Pao Chicken", "Chinese");
        chineseChef.handleOrder(order1);

        Order order2 = new Order("Steak", "Western");
        chineseChef.handleOrder(order2);

        Order order3 = new Order("Tiramisu", "Dessert");
        chineseChef.handleOrder(order3);

        Order order4 = new Order("Sushi", "Japanese");
        chineseChef.handleOrder(order4);
    }
}

在这个示例中,不同类型的菜品(中餐、西餐、甜点等)由不同的厨师负责。点餐请求会从低级别处理器传递到更高级别处理器,直到找到能够处理该类型的厨师,或者请求到达责任链的末端。

2.4 简单的权限验证

让我们考虑一个简单的权限验证场景,使用责任链模式来处理不同级别的权限检查。不同级别的权限检查由不同的权限处理者来执行,如果某个处理者无法处理权限请求,则请求将被传递给下一个处理者。

以下是使用责任链模式模拟权限验证的示例:

// 权限请求
class PermissionRequest {
    private String username;
    private int level;

    public PermissionRequest(String username, int level) {
        this.username = username;
        this.level = level;
    }

    public String getUsername() {
        return username;
    }

    public int getLevel() {
        return level;
    }
}

// 权限处理者接口
interface PermissionHandler {
    void setNextHandler(PermissionHandler nextHandler);
    void handleRequest(PermissionRequest request);
}

// 基础权限处理者
class BasicPermissionHandler implements PermissionHandler {
    private PermissionHandler nextHandler;

    @Override
    public void setNextHandler(PermissionHandler nextHandler) {
        this.nextHandler = nextHandler;
    }

    @Override
    public void handleRequest(PermissionRequest request) {
        if (request.getLevel() <= 10) {
            System.out.println(request.getUsername() + " has basic permission level.");
        } else if (nextHandler != null) {
            nextHandler.handleRequest(request);
        }
    }
}

// 中级权限处理者
class IntermediatePermissionHandler implements PermissionHandler {
    private PermissionHandler nextHandler;

    @Override
    public void setNextHandler(PermissionHandler nextHandler) {
        this.nextHandler = nextHandler;
    }

    @Override
    public void handleRequest(PermissionRequest request) {
        if (request.getLevel() <= 50) {
            System.out.println(request.getUsername() + " has intermediate permission level.");
        } else if (nextHandler != null) {
            nextHandler.handleRequest(request);
        }
    }
}

// 高级权限处理者
class AdvancedPermissionHandler implements PermissionHandler {
    @Override
    public void setNextHandler(PermissionHandler nextHandler) {
        // AdvancedPermissionHandler is the final handler and does not require a next handler
    }

    @Override
    public void handleRequest(PermissionRequest request) {
        if (request.getLevel() > 50) {
            System.out.println(request.getUsername() + " has advanced permission level.");
        } else {
            System.out.println("No handler found for " + request.getUsername());
        }
    }
}

// 使用责任链模式进行权限验证
public class PermissionChainExample {
    public static void main(String[] args) {
        PermissionHandler basicHandler = new BasicPermissionHandler();
        PermissionHandler intermediateHandler = new IntermediatePermissionHandler();
        PermissionHandler advancedHandler = new AdvancedPermissionHandler();

        // 构建权限处理链
        basicHandler.setNextHandler(intermediateHandler);
        intermediateHandler.setNextHandler(advancedHandler);

        // 发起权限请求
        PermissionRequest request1 = new PermissionRequest("UserA", 5);
        basicHandler.handleRequest(request1);

        PermissionRequest request2 = new PermissionRequest("UserB", 30);
        basicHandler.handleRequest(request2);

        PermissionRequest request3 = new PermissionRequest("UserC", 60);
        basicHandler.handleRequest(request3);

        PermissionRequest request4 = new PermissionRequest("UserD", 100);
        basicHandler.handleRequest(request4);
    }
}

在此示例中,不同级别的权限请求由不同级别的处理者处理。请求会从低级别处理者传递到更高级别处理者,直到找到能够处理该权限请求的处理者,或者请求到达责任链的末端。

2.5 工程师

让我们想象一个问题解决系统,根据问题的复杂程度,系统中的不同专家级别的工程师会负责处理不同级别的问题。如果一个工程师无法解决问题,请求将被传递给下一个更高级别的工程师。

以下是使用责任链模式模拟问题解决系统的示例:

// 问题请求
class Problem {
    private String description;
    private int complexity;

    public Problem(String description, int complexity) {
        this.description = description;
        this.complexity = complexity;
    }

    public String getDescription() {
        return description;
    }

    public int getComplexity() {
        return complexity;
    }
}

// 工程师接口
interface Engineer {
    void setNextEngineer(Engineer nextEngineer);
    void solveProblem(Problem problem);
}

// 初级工程师
class JuniorEngineer implements Engineer {
    private Engineer nextEngineer;

    @Override
    public void setNextEngineer(Engineer nextEngineer) {
        this.nextEngineer = nextEngineer;
    }

    @Override
    public void solveProblem(Problem problem) {
        if (problem.getComplexity() <= 5) {
            System.out.println("Junior Engineer solved problem: " + problem.getDescription());
        } else if (nextEngineer != null) {
            nextEngineer.solveProblem(problem);
        }
    }
}

// 中级工程师
class IntermediateEngineer implements Engineer {
    private Engineer nextEngineer;

    @Override
    public void setNextEngineer(Engineer nextEngineer) {
        this.nextEngineer = nextEngineer;
    }

    @Override
    public void solveProblem(Problem problem) {
        if (problem.getComplexity() <= 10) {
            System.out.println("Intermediate Engineer solved problem: " + problem.getDescription());
        } else if (nextEngineer != null) {
            nextEngineer.solveProblem(problem);
        }
    }
}

// 高级工程师
class SeniorEngineer implements Engineer {
    @Override
    public void setNextEngineer(Engineer nextEngineer) {
        // SeniorEngineer is the final engineer and does not require a next engineer
    }

    @Override
    public void solveProblem(Problem problem) {
        if (problem.getComplexity() > 10) {
            System.out.println("Senior Engineer solved problem: " + problem.getDescription());
        } else {
            System.out.println("No engineer found for problem: " + problem.getDescription());
        }
    }
}

// 使用责任链模式解决问题
public class ProblemSolvingSystem {
    public static void main(String[] args) {
        Engineer juniorEngineer = new JuniorEngineer();
        Engineer intermediateEngineer = new IntermediateEngineer();
        Engineer seniorEngineer = new SeniorEngineer();

        // 构建问题解决链
        juniorEngineer.setNextEngineer(intermediateEngineer);
        intermediateEngineer.setNextEngineer(seniorEngineer);

        // 发起问题解决请求
        Problem problem1 = new Problem("Bug fixing", 3);
        juniorEngineer.solveProblem(problem1);

        Problem problem2 = new Problem("Algorithm optimization", 8);
        juniorEngineer.solveProblem(problem2);

        Problem problem3 = new Problem("System architecture design", 15);
        juniorEngineer.solveProblem(problem3);

        Problem problem4 = new Problem("Network setup", 20);
        juniorEngineer.solveProblem(problem4);
    }
}

在此示例中,不同级别的工程师由不同级别的处理者处理。问题请求会从低级别处理者传递到更高级别处理者,直到找到能够解决该问题的工程师,或者请求到达责任链的末端。

网站文章

  • 浅谈MIL、SIL、PIL、HIL

    浅谈MIL、SIL、PIL、HIL

    MBD开过过程中,经常会接触到MIL、SIL、PIL、HIL,下文将从定义着手,将他们区别开来。 定义: MIL:Model in loop, 验证控制算法模型是否满足功能需求 SIL: Software in loop, 在PC上验证模型是否与代码功能一致 PIL:Processor in loop, 在目标处理器上验证模型是否与代码功能一致 HIL:Hardw

    2024-02-01 05:49:07
  • Python(三)微信公众号开发

    Python(三)微信公众号开发

    ps:暂未完善,先做记录。本文核心讲外网穿透及微信Token验证 阅读 基本开发流程 申请个人公众号-订阅号 微信公众平台https://mp.weixin.qq.com 自定义菜单 微信公众平台当然...

    2024-02-01 05:49:01
  • 数据结构 | 交换排序

    数据结构 | 交换排序

    交换排序(包括冒泡排序、快速排序)的C语言实现

    2024-02-01 05:48:32
  • stanford corenlp命名实体识别(基于python)

    stanford corenlp命名实体识别(基于python)

    很多童鞋在用stanford-core-nlp进行命名实体识别时遇到了各种问题,在此本人根据已有经验讲述如何成功利用stanford工具进行命名实体识别处理。 1. 环境安装 需要用到的有java_j...

    2024-02-01 05:48:27
  • Count and Say --leetcode

    Count and Say --leetcode题目如下The count-and-say sequence is the sequence of integers beginning as follows:1, 11, 21, 1211, 111221, ...1 is read off as "one 1" or 11.11 is rea

    2024-02-01 05:48:19
  • paddle-serving docker部署,dockerfile一键打镜像,一键启动容器

    一、服务端dockfile编写 节省镜像空间,此处在python的镜像基础上构建,最终镜像2.38G FROM python:3.7.4 COPY . /deploy WORKDIR /deploy ...

    2024-02-01 05:48:13
  • 2D空间求一点是否在多边形内

    2D空间求一点是否在多边形内

    转自:https://www.cnblogs.com/hont/p/6105997.html大致流程:1.随便选取多边形上任意一条边,以比较点和边的中心点做一条射线(这里用的伪射线)。2.用这条射线与...

    2024-02-01 05:47:43
  • docker化笔记二、镜像应用服务日志输出到宿主机器

    本章以日志为例进行说明,仅作抛砖引玉,实际项目不应该以这种方式去搜集日志(常用Syslog日志驱动类型,再用日志分析工具,比如ELK,进行获取搜集)。如果容器重新启动,使用docker logs看到的...

    2024-02-01 05:47:38
  • Java 限制前端重复请求

    Java 限制前端重复请求

    2024-02-01 05:47:33
  • Java:常用类解析5(正则表达式)

    正则表达式不仅仅是Java的技术,在任何一门编程语言中都会存在,是一种通用的IT技术。除了有一些由于语言不同而导致的一些语法不同,其理念和用法在任何编程语言中基本一致。正则表达式,主要用于匹配(查找 ...

    2024-02-01 05:47:00