详解Java设计模式之职责链模式

原文:详解Java设计模式之职责链模式_java_脚本之家

责任链模式是一种行为设计模式,使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系,文中通过代码示例给大家介绍的非常详细,需要的朋友可以参考下

Java技术迷

目录
  • 职责链模式
    • 1、职责链模式介绍
      • 1.1 职责链模式基本实现
    • 2、具体例子说明
      • 2.1 不使用职责链模式 - 加薪 / 请假
      • 2.2 职责链模式 - 加薪 / 请假
    • 3、职责链模式总结

职责链模式

1、职责链模式介绍

责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

在责任链模式中,请求通过一条链传递,每个对象都有机会处理请求。当一个对象无法处理请求时,它会将请求传递给链中的下一个对象,直到找到能够处理请求的对象为止。这种方式可以动态地组织和管理对象,使得请求发送者和接收者之间解耦,提高系统的灵活性和可扩展性。

1.1 职责链模式基本实现

职责链模式结构图:

责任链模式包含以下几个角色:

  • 抽象处理者(Handler):定义了一个处理请求的接口,通常包含一个指向下一个处理者的引用,用于构建责任链。
  • 具体处理者(ConcreteHandler):实现抽象处理者接口,具体处理请求的逻辑。如果可以处理请求,则处理请求;否则,将请求传递给下一个处理者。

Handler类,定义一个处理请示的接口:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

/**

 * @author Shier

 * CreateTime 2023/5/20 16:04

 * 处理请求的接口

 */

public abstract class Handler {

    protected Handler successor;

    /**

     * 设置继承者

     * @param successor

     */

    public void setSuccessor(Handler successor) {

        this.successor = successor;

    }

    public abstract void handleRequest(int request);

}

ConcreteHandler类,具体处理者类,处理它所负责的请求,可访问它的 后继者,如果可处理该请求,就处理之,否则就将该请求转发给它的后继 者。

ConcreteHandler1,当请求数为0~10则有权处理,否则转到下一位:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

/**

 * @author Shier

 * CreateTime 2023/5/20 16:06

 */

public class ConcreteHandler1 extends Handler {

    @Override

    public void handleRequest(int request) {

        if (request >= 0 && request < 10) {

            // 当前处理者权限 0 ~ 9

            System.out.println(this.getClass().getSimpleName() + "处理了请求" + request);

        } else if (successor != null) {

            // 转移给下一个处理者

            successor.handleRequest(request);

        }

    }

}

ConcreteHandler2,当请求数为10~20则有权处理,否则转到下一位。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

/**

 * @author Shier

 * CreateTime 2023/5/20 16:06

 */

public class ConcreteHandler2 extends Handler {

    @Override

    public void handleRequest(int request) {

        if (request >= 10 && request < 20) {

            // 当前处理者权限 10 ~ 19

            System.out.println(this.getClass().getSimpleName() + "处理了请求" + request);

        } else if (successor != null) {

            // 转移给下一个处理者

            successor.handleRequest(request);

        }

    }

}

ConcreteHandler3,当请求数为20~99则有权处理,否则转到下一位

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

/**

 * @author Shier

 * CreateTime 2023/5/20 16:06

 */

public class ConcreteHandler3 extends Handler {

    @Override

    public void handleRequest(int request) {

        if (request >= 20 && request < 100) {

            // 当前处理者权限 20 ~ 99

            System.out.println(this.getClass().getSimpleName() + "处理了请求" + request);

        } else if (successor != null) {

            // 转移给下一个处理者

            successor.handleRequest(request);

        }

    }

}

客户端代码,向链上的具体处理者对象提交请求。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

/**

 * @author Shier

 * CreateTime 2023/5/20 16:09

 */

public class ChainClient {

    public static void main(String[] args) {

        ConcreteHandler1 handler1 = new ConcreteHandler1();

        ConcreteHandler2 handler2 = new ConcreteHandler2();

        ConcreteHandler3 handler3 = new ConcreteHandler3();

        // 设置职责链上下关系

        handler1.setSuccessor(handler2);

        handler2.setSuccessor(handler3);

        // 请求

        int[] request = {15, 67, 8, 9, 46, 1, 5, 23, 41};

        // 循环给最小矗立着提交请求,不同的数额,得不同的权限处理者处理

        for (int i : request) {

            handler1.handleRequest(i);

        }

    }

}

2、具体例子说明

在公司请假或者升职加薪,需要通过经理、总监、总经理的批准,不同身份有不同的权限。当然可以直接直接找总经理给你升职加薪😎

2.1 不使用职责链模式 - 加薪 / 请假

升值加薪:经理是没有权限的,要上报给总监,总监的回复也是没有权限管,只能再上报到总经理才有处理的权限

请假:经理只能处理请假两天的申请,再多就不可以。必须要上报给上司才有权限去处理这个请求。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

// 申请类

public class Request {

    // 申请类别

    private String requestType;

    public String getRequestType(){

        return this.requestType;

    }

    public void setRequestType(String value){

        this.requestType = value;

    }

    //申请内容

    private String requestContent;

    public String getRequestContent(){

        return this.requestContent;

    }

    public void setRequestContent(String value){

        this.requestContent = value;

    }

    // 数量

    private int number;

    public int getNumber(){

        return this.number;

    }

    public void setNumber(int value){

        this.number = value;

    }

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

//管理者

public class Manager{

    protected String name;

    public Manager(String name){

        this.name = name;

    }

    public void getResult(String managerLevel,Request request){

        if (managerLevel == "经理"){

          if (request.getRequestType()=="请假" && request.getNumber()<=2)

            System.out.println(this.name+":"+request.getRequestContent()+" 数量:"+request.getNumber()+"天,被批准");

          else

            System.out.println(this.name+":"+request.getRequestContent()+" 数量:"+request.getNumber()+"天,我无权处理");

        }

        else if (managerLevel == "总监"){

          if (request.getRequestType()=="请假" && request.getNumber()<=5)

            System.out.println(this.name+":"+request.getRequestContent()+" 数量:"+request.getNumber()+"天,被批准");

          else

            System.out.println(this.name+":"+request.getRequestContent()+" 数量:"+request.getNumber()+"天,我无权处理");

        }

        else if (managerLevel == "总经理"){

          if (request.getRequestType()=="请假")

            System.out.println(this.name+":"+request.getRequestContent()+" 数量:"+request.getNumber()+"天,被批准");

          else if (request.getRequestType()=="加薪" && request.getNumber()<=5000)

            System.out.println(this.name+":"+request.getRequestContent()+" 数量:"+request.getNumber()+"元,被批准");

          else if (request.getRequestType()=="加薪" && request.getNumber()>5000)

            System.out.println(this.name+":"+request.getRequestContent()+" 数量:"+request.getNumber()+"元,再说吧");

        }

    }

}

客户端:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

public class Test {

    public static void main(String[] args) {

        Manager manager = new Manager("金利");

        Manager director = new Manager("宗剑");

        Manager generalManager = new Manager("钟精励");

        Request request = new Request();

        request.setRequestType("加薪");

        request.setRequestContent("Shier请求加薪");

        request.setNumber(10000);

        // 不同身份的人有不同的权限,进行处理结果

        manager.getResult("经理", request);

        director.getResult("总监", request);

        generalManager.getResult("总经理", request);

        Request request2 = new Request();

        request2.setRequestType("请假");

        request2.setRequestContent("Shier请假");

        request2.setNumber(3); // 权限级别

        manager.getResult("经理", request2);

        director.getResult("总监", request2);

        generalManager.getResult("总经理", request2);

    }

}

通过上面的程序,会发现一个问题管理者类,里面的方法比较长,太多的分支判断。类的责任太多,就违背了单一职责原则,同时增加新的项目时,要去修改这个方法,就违背了开发 - 封闭原则。下面就要用到职责链模式要简化这样开发业务场景 。

2.2 职责链模式 - 加薪 / 请假

将上面的程序进行重构,得到的代码结构图如下:

Request请求类:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

/**

 * @author Shier

 * 申请类

 */

public class Request {

    // 申请类别

    private String requestType;

    public String getRequestType() {

        return this.requestType;

    }

    public void setRequestType(String value) {

        this.requestType = value;

    }

    //申请内容

    private String requestContent;

    public String getRequestContent() {

        return this.requestContent;

    }

    public void setRequestContent(String value) {

        this.requestContent = value;

    }

    // 数量

    private int number;

    public int getNumber() {

        return this.number;

    }

    public void setNumber(int value) {

        this.number = value;

    }

}

抽象管理者:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

/**

 * @author Shier

 * CreateTime 2023/5/20 16:33

 * 抽象管理这类

 */

public abstract class Manager {

    protected String name;

    public Manager(String name) {

        this.name = name;

    }

    /**

     * 设置管理者上级

     */

    protected Manager superior;

    public void setSuperior(Manager superior) {

        this.superior = superior;

    }

    /**

     * 请求申请

     *

     * @param request

     */

    public abstract void requestApplications(Request request);

}

经理类就可以去继承这个'管理者'类,只需重写 '申请请求' 的方法

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

/**

 * @author Shier

 * CreateTime 2023/5/20 16:34

 * 普通经理类

 */

public class CommonManager extends Manager {

    public CommonManager(String name) {

        super(name);

    }

    @Override

    public void requestApplications(Request request) {

        if (request.getRequestType() == "请假" && request.getNumber() <= 2) {

            System.out.println(this.name + ":" + request.getRequestContent() + " 数量:" + request.getNumber() + "天,被批准");

        } else if (this.superior != null) {

            this.superior.requestApplications(request);

        }

    }

}

总监同样继承抽象管理类

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

/**

 * @author Shier

 * CreateTime 2023/5/20 16:36

 * 总监

 */

public class Director extends Manager {

    public Director(String name) {

        super(name);

    }

    @Override

    public void requestApplications(Request request) {

        if (request.getRequestType() == "请假" && request.getNumber() <= 5) {

            System.out.println(this.name + ":" + request.getRequestContent() + " 数量:" + request.getNumber() + "天,被批准");

        } else if (this.superior != null) {

            this.superior.requestApplications(request);

        }

    }

}

总经理同样继承管理者类,总经理的权限就是全部都需要处理。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

/**

 * @author Shier

 * CreateTime 2023/5/20 16:36

 * 总经理

 */

public class GeneralManager extends Manager {

    public GeneralManager(String name) {

        super(name);

    }

    @Override

    public void requestApplications(Request request) {

        if (request.getRequestType() == "请假") {

            System.out.println(this.name + ":" + request.getRequestContent() + " 数量:" + request.getNumber() + "天,被批准");

        } else if (request.getRequestType() == "加薪" && request.getNumber() <= 5000) {

            System.out.println(this.name + ":" + request.getRequestContent() + " 数量:" + request.getNumber() + "元,被批准");

        } else if (request.getRequestType() == "加薪" && request.getNumber() > 5000) {

            System.out.println(this.name + ":" + request.getRequestContent() + " 数量:" + request.getNumber() + "元,再说吧");

        }

    }

}

测试类:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

/**

 * @author Shier

 */

public class ChainClient {

    public static void main(String[] args) {

        CommonManager manager = new CommonManager("大明经理");

        Director director = new Director("大大明总监");

        GeneralManager generalManager = new GeneralManager("大大大明总经理");

        // 设置管理者之间上下级关系 经理 => 总监 => 总经理

        manager.setSuperior(director);

        director.setSuperior(generalManager);

        // 加薪 5000

        Request request = new Request();

        request.setRequestType("加薪");

        request.setRequestContent("Shier请求加薪");

        request.setNumber(5000);

        // 从自己最近的上司开始请求也就是经理

        manager.requestApplications(request);

        // 加薪10000

        Request request1 = new Request();

        request1.setRequestType("加薪");

        request1.setRequestContent("Shier请求加薪");

        request1.setNumber(10000);

        manager.requestApplications(request1);

        // 请假一天

        Request request2 = new Request();

        request2.setRequestType("请假");

        request2.setRequestContent("Shier请假");

        request2.setNumber(1);

        manager.requestApplications(request2);

        // 请假四天

        Request request3 = new Request();

        request3.setRequestType("请假");

        request3.setRequestContent("Shier请假");

        request3.setNumber(4);

        manager.requestApplications(request3);

    }

}

最后得到的结果:

由于我们把原来的一个 '管理者' 类改成了一个抽象类和三个具体类, 此时类之间的灵活性就大大增加了,如果我们需要扩展新的管理者类别,只需要增加子类就可以。比如这个例子增加一个 '集团总裁' 类,完全是没有问题的,只需要修改 '总经理类' 即可,并不影响其他类代码。

这样使用职责链模式可以更加清晰这些代码之间的关系,不像最上面的一个类里面多个判断语句,看起来都很难维护。好了,再总结一下职责链模式

3、职责链模式总结

职责链模式的好处

  • 当客户提交一个请求时,请求是沿链传递直至有一个 ConcreteHandler 对象负责处理它。
  • 降低耦合:接收者和发送者都没有对方的明确信息,且链中的对 象自己也并不知道链的结构。结果是职责链可简化对象的相互连接,它们仅 需保持一个指向其后继者的引用,而不需保持它所有的候选接受者的引用。降低了代码之间耦合度。
  • 灵活性:随时地增加或修改处理一个请求的结构。增强了给对象指派职责的灵活性。

优点:

  • 将请求发送者和接收者解耦,可以避免请求发送者与接收者之间的直接耦合,增强了代码的可维护性。
  • 可以动态地新增或修改请求处理顺序,提高了程序的灵活性和可扩展性。
  • 可以进行请求的拦截、分流等操作,方便进行统计和日志记录等处理。
  • 可以根据需要对请求的处理进行单独的测试,便于代码测试和调试。
  • 解耦发送者和接收者:职责链模式可以将发送者和接收者解耦,发送者不需要知道请求的具体处理者是谁,而处理者也不需要知道请求的发送者是谁,从而提高系统的灵活性。
  • 动态组合和扩展性:职责链模式允许动态地向链中添加或删除处理者,以适应不同的业务需求,增强了系统的可扩展性。
  • 可配置性:通过调整链中处理者的顺序,可以灵活地配置处理流程,满足不同的处理优先级或条件。

缺点:

  • 请求的保证:没有明确的处理者处理请求的保证。请求可能到达链的末尾而没有被处理,这需要在设计时进行合理的考虑。
  • 性能考虑:由于链中的请求需要依次传递给每个处理者,因此在处理大量请求时可能会影响性能。
  • 可能导致系统变得复杂:当链过长或者处理者过多时,职责链模式可能会导致系统变得复杂,难以理解和维护。

使用场景:

  • 处理复杂的请求处理流程,例如购物车结算、审批流程等复杂业务中。
  • 需要动态指定请求的处理顺序或者动态添加新的请求处理者时。
  • 处理日志记录、缓存等拦截器的场景。例如在Spring中,就应用了责任链模式来实现Interceptor拦截器。
  • 多个对象可以处理同一请求,但具体的处理者在运行时可变或不确定的情况下,可以使用职责链模式。
  • 需要动态组合处理流程或动态调整处理顺序的情况下,职责链模式可以提供灵活性和可配置性。
  • 需要在不明确请求的发送者和接收者之间建立松耦合关系的情况下,职责链模式可以解耦对象之间的关系。

以上就是详解Java设计模式之职责链模式的详细内容,更多关于Java 职责链模式的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:

  • 深入了解Java设计模式之职责链模式
  • Java设计模式之职责链模式详解
  • 深入理解Java设计模式之职责链模式
  • Java职责链模式的深入了解
  • Java设计模式中单一职责原则详解
  • Java创建型设计模式之建造者模式详解

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/163599.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

TG Pro v2.87(mac温度风扇速度控制工具)

TG Pro 是适用于 macOS 的温度和风扇速度控制工具&#xff0c;可让您监控 Mac 组件&#xff08;例如 CPU 和 GPU&#xff09;的温度和风扇速度。如果您担心 Mac 过热或想要手动调整风扇速度以降低噪音水平&#xff0c;这将特别有用。 除了温度和风扇监控&#xff0c;TG Pro 还…

基于截图页面生成前端项目

前两天&#xff0c;在群里看见一个视频&#xff0c;视频中&#xff0c;作者截图twitter首页&#xff0c;然后使用截图直接生成与截图布局非常相近的前端项目&#xff0c;效果还是比较惊艳的。 今天陪老婆回老家&#xff0c;路上clone这个项目的代码到本地&#xff0c;学习了一下…

回归预测 | Matlab实现HPO-ELM猎食者算法优化极限学习机的数据回归预测

回归预测 | Matlab实现HPO-ELM猎食者算法优化极限学习机的数据回归预测 目录 回归预测 | Matlab实现HPO-ELM猎食者算法优化极限学习机的数据回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 Matlab实现HPO-ELM猎食者算法优化极限学习机的数据回归预测&#xff08;…

Bert学习笔记(简单入门版)

目 录 一、基础架构 二、输入部分 三、预训练&#xff1a;MLMNSP 3.1 MLM&#xff1a;掩码语言模型 3.1.1 mask模型缺点 3.1.2 mask的概率问题 3.1.3 mask代码实践 3.2 NSP 四、如何微调Bert 五、如何提升BERT下游任务表现 5.1 一般做法 5.2 如何在相同领域数据中进…

037、目标检测-算法速览

之——常用算法速览 目录 之——常用算法速览 杂谈 正文 1.区域卷积神经网络 - R-CNN 2.单发多框检测SSD&#xff0c;single shot detection 3.yolo 杂谈 快速过一下目标检测的各类算法。 正文 1.区域卷积神经网络 - R-CNN region_based CNN&#xff0c;奠基性的工作。…

[C++历练之路]vector的介绍以及底层模拟实现

W...Y的主页 &#x1f60a; 代码仓库分享 &#x1f495; &#x1f354;前言&#xff1a; 我们学习了STL中的string以及其所有重要接口并进行了模拟实现&#xff0c;但是STL中包含的内容不止于此。学习了string之后继续学习STL中的vector&#xff0c;学习成本会大大降低&#…

CentOS7 安装mysql8(离线安装)postgresql14(在线安装)

注&#xff1a;linux系统为vmware虚拟机&#xff0c;和真实工作环境可能有出入&#xff0c;不过正因如此我暴露了NAT转出的IP也没什么大碍 引言 postgresql与mysql目前都是非常受人欢迎的两大数据库&#xff0c;其各有各的优势&#xff0c;初学者先使用简单一张图来说明两者区…

【算法挨揍日记】day31——673. 最长递增子序列的个数、646. 最长数对链

673. 最长递增子序列的个数 673. 最长递增子序列的个数 题目解析&#xff1a; 给定一个未排序的整数数组 nums &#xff0c; 返回最长递增子序列的个数 。 注意 这个数列必须是 严格 递增的。 解题思路&#xff1a; 算法思路&#xff1a; 1. 状态表⽰&#xff1a; 先尝试…

取数游戏2(动态规划java)

取数游戏2 题目描述 给定两个长度为n的整数列A和B&#xff0c;每次你可以从A数列的左端或右端取走一个数。假设第i次取走的数为ax&#xff0c;则第i次取走的数的价值vibi⋅ax&#xff0c;现在希望你求出∑vi的最大值。 输入格式 第一行一个数T &#xff0c;表示有T 组数据。…

【算法挨揍日记】day27——152. 乘积最大子数组、1567. 乘积为正数的最长子数组长度

152. 乘积最大子数组 152. 乘积最大子数组 题目描述&#xff1a; 给你一个整数数组 nums &#xff0c;请你找出数组中乘积最大的非空连续子数组&#xff08;该子数组中至少包含一个数字&#xff09;&#xff0c;并返回该子数组所对应的乘积。 测试用例的答案是一个 32-位 整…

【狂神说Java】Docker概述 | Docker安装 | Docker的常用命令

✅作者简介&#xff1a;CSDN内容合伙人、信息安全专业在校大学生&#x1f3c6; &#x1f525;系列专栏 &#xff1a;【狂神说Java】 &#x1f4c3;新人博主 &#xff1a;欢迎点赞收藏关注&#xff0c;会回访&#xff01; &#x1f4ac;舞台再大&#xff0c;你不上台&#xff0c…

PS学习笔记——视图调整

文章目录 图片拖动图片旋转图片缩放 视图只是我们在对图片进行操作时所看到的图片状态&#xff0c;并不会实际改变图片的属性。目的是方便我们在操作图片时有最舒服的体验 图片拖动 工具栏中有这样一个抓手工具(快捷键H)&#xff0c;选择这个抓手工具便可以在图片放大后能用鼠标…

2023年四川省安全员A证证模拟考试题库及四川省安全员A证理论考试试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2023年四川省安全员A证证模拟考试题库及四川省安全员A证理论考试试题是由安全生产模拟考试一点通提供&#xff0c;四川省安全员A证证模拟考试题库是根据四川省安全员A证最新版教材&#xff0c;四川省安全员A证大纲整理…

BGP联盟和团体属性实验

目录 一、实验拓扑 二、实验要求 三、实验步骤 1、IP地址配置 2、ospf配置 3、BGP建邻 4、宣告网段 5、配置团体属性 一、实验拓扑 二、实验要求 1、按照图示配 IP 地址&#xff0c;R2&#xff0c;R3&#xff0c;R4&#xff0c;R5分别配 Loopbacke 口地址作为OSPF的Ro…

系列六、GC垃圾回收【四大垃圾算法-标记清除算法】

一、概述 标记清除算法分为两个阶段&#xff0c;即&#xff1a;标记和清除两个阶段&#xff0c;先标记出要回收的对象&#xff0c;然后统一回收这些对象。形如&#xff1a; 老年代一般是由标记清除或者标记清除 标记压缩的混合实现。 二、原理 用通俗的话解释一下标记清除算法…

深入解析:开发抖音酒店景区小程序的技术

抖音作为社交媒体平台的佼佼者&#xff0c;其独特的风格和用户基础吸引了无数开发者的目光。在本文中&#xff0c;我们将深入解析开发抖音酒店景区小程序的关键技术&#xff0c;为开发者提供实用指南。 1.抖音风格设计 在开发酒店景区小程序时&#xff0c;首先要注重界面设计…

Leetcode—剑指Offer LCR 140.训练计划II【简单】

2023每日刷题&#xff08;三十三&#xff09; Leetcode—LCR 140.训练计划II 实现代码 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/ struct ListNode* trainingPlan(struct ListNode* head, int cnt) {str…

C/C++ 获取主机网卡MAC地址

MAC地址&#xff08;Media Access Control address&#xff09;&#xff0c;又称为物理地址或硬件地址&#xff0c;是网络适配器&#xff08;网卡&#xff09;在制造时被分配的全球唯一的48位地址。这个地址是数据链路层&#xff08;OSI模型的第二层&#xff09;的一部分&#…

《向量数据库指南》——什么是 向量数据库Milvus Cloud的Range Search?

Range Search 功能诞生于社区。 某天,一位做系统推荐的用户在社区提出了需求,希望 Milvus Cloud 能提供一个新功能,可以返回向量距离在一定范围之内的结果。而这不是个例,开发者在做相似性查询时,经常需要对结果做二次过滤。 为了帮助用户解决这一问题,Milvus Cl…

STL的介绍

STL 是 C 标准模板库&#xff08;Standard Template Library&#xff09;的缩写&#xff0c;是 C 标准库中的一个重要组成部分。STL 提供了一组通用的模板类和函数&#xff0c;用于实现常用的数据结构和算法&#xff0c;如向量&#xff08;vector&#xff09;、链表&#xff08…