吴志勇的博客 吴志勇的博客
  • h5

    • HTML5&CSS3
  • scss

    • css预处理语言
  • JavaScript

    • JavaScript教程
    • Ajax
    • ES6教程
    • NodeJS
    • Typescript
  • 框架

    • Jquery
    • VUE
    • React
  • Swing专题
  • java基础
  • javaweb
  • 框架
  • 数据库
  • netty
  • 设计模式
  • 微服务及架构
  • 云原生
  • maven
  • 单元测试
工具
我的
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

吴志勇

......
  • h5

    • HTML5&CSS3
  • scss

    • css预处理语言
  • JavaScript

    • JavaScript教程
    • Ajax
    • ES6教程
    • NodeJS
    • Typescript
  • 框架

    • Jquery
    • VUE
    • React
  • Swing专题
  • java基础
  • javaweb
  • 框架
  • 数据库
  • netty
  • 设计模式
  • 微服务及架构
  • 云原生
  • maven
  • 单元测试
工具
我的
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • Swing专题

  • java基础

  • javaweb

  • 框架

  • Maven
  • 单元测试
  • 动态代理
  • 数据库

  • netty

  • 设计模式

    • simple_factory
    • factory_method
    • abstract_factory
    • singleton
    • builder
    • prototype
    • adapter
    • decorator
    • facade
    • bridge
    • proxy
    • composite
    • flyweight
    • observer
    • command
    • state
    • chain_of_responsibility
      • 模式引入
        • 问题描述
        • 模式定义
        • 问题分析
      • 模式实现
        • 解决方案
        • 代码实现
        • 结构组成
      • 模式评价
        • 适用场景
        • 实际应用
        • 优点缺点
    • template_method
    • strategy
    • interpreter
    • mediator
    • visitor
    • memento
    • iterator
  • 微服务及架构

  • 云原生

  • Velocity模板引擎
  • 后端
  • 设计模式
wuzhiyong
2025-01-13

chainofresponsibility

# 职责链模式

# 模式引入

# 问题描述

加薪、请假申请等需要层层审批的场景。比如向经理提加薪申请,经理没权利然后向总监上报,总监没权限然后向总经理汇报等。

# 模式定义

职责链模式核心是解决服务中先后执行处理关系,从而降低请求发送者和接受者之间的耦合关系。类似于击鼓传花。

# 问题分析

如果将管理者创建成为一个类,那么该类会具有太多的责任,比如经理、总监以及总经理的审批和上报功能,就违背了单一职责原则。而且以后的需求可能会增加新的管理类别,比如项目经理、部门经理、人事总监等,那么就势必会修改管理者类以完成扩展,就违背了开放封闭原则。

# 模式实现

# 解决方案

将公司管理者的类别变成管理者的子类,可以通过多态性来化解分支带来的僵化。然后通过不同管理者之间建立管理关系实现请求的传递,使得请求的发送者和接收者解耦,可以让各服务模块更加清晰。处理者负责处理请求,客户只需要将请求发送到职责链,无需关心具体的处理细节。

Handler(请求类):用于定义一个处理请示的接口。

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

# 代码实现

Request 类:

public class Request {
    private String requestType;
    private String requestContent;
    private int number;

    public String getRequestType() {
        return requestType;
    }

    public void setRequestType(String requestType) {
        this.requestType = requestType;
    }

    public String getRequestContent() {
        return requestContent;
    }

    public void setRequestContent(String requestContent) {
        this.requestContent = requestContent;
    }

    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
    }
}
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

Manager 类:

public abstract class Manager {
    protected String name;
    protected Manager superior;

    protected Manager(String name) {
        this.name = name;
    }

    public void SetSuperior(Manager superior) {
        this.superior = superior;
    }

    public abstract void requestApplications(Request request);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

ConcreteManager 类:

public class GeneralManager extends Manager {
    protected GeneralManager(String name) {
        super(name);
    }

    @Override
    public void requestApplications(Request request) {
        if(request.getRequestType() == "请假"){
            System.out.println(name + ":" + request.getRequestContent() + " 数量" + request.getNumber() + " 被批准" );
        }else if(request.getRequestType() == "加薪" && request.getNumber() <= 500) {
            System.out.println(name + ":" + request.getRequestContent() + " 数量" + request.getNumber() + " 被批准" );
        }else {
            System.out.println(name + ":" + request.getRequestContent() + " 数量" + request.getNumber() + " 再说吧" );
        }
    }
}

public class MajorDemo extends Manager {
    protected MajorDemo(String name) {
        super(name);
    }

    @Override
    public void requestApplications(Request request) {
        if(request.getRequestType() == "请假" && request.getNumber() <= 5) {
            System.out.println(name + ":" + request.getRequestContent() + " 数量" + request.getNumber() + " 被批准" );
        }else {
            if(superior != null) {
                superior.requestApplications(request);
            }
        }
    }
}

public class CommonManager extends Manager {
    protected CommonManager(String name) {
        super(name);
    }

    @Override
    public void requestApplications(Request request) {
        if(request.getRequestType() == "请假" && request.getNumber() <= 2) {
            System.out.println(name + ":" + request.getRequestContent() + " 数量" + request.getNumber() + " 被批准" );
        }else {
            if(superior != null) {
                superior.requestApplications(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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

Main 方法:

public class Main {
    public static void main(String[] args) {
        CommonManager jinli = new CommonManager("金利");
        MajorDemo zongjian = new MajorDemo("宗剑");
        GeneralManager zhongjingli = new GeneralManager("钟精励");
        jinli.SetSuperior(zongjian);
        zongjian.SetSuperior(zhongjingli);

        Request request = new Request();
        request.setRequestType("请假");
        request.setRequestContent("小菜请假");
        request.setNumber(1);
        jinli.requestApplications(request);

        Request request2 = new Request();
        request2.setRequestType("请假");
        request2.setRequestContent("小菜请假");
        request2.setNumber(4);
        jinli.requestApplications(request2);

        Request request3 = new Request();
        request3.setRequestType("加薪");
        request3.setRequestContent("小菜请求加薪");
        request3.setNumber(500);
        jinli.requestApplications(request3);

        Request request4 = new Request();
        request4.setRequestType("加薪");
        request4.setRequestContent("小菜请求加薪");
        request4.setNumber(1000);
        jinli.requestApplications(request4);
    }
}
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

执行结果:

金利:小菜请假 数量1 被批准
宗剑:小菜请假 数量4 被批准
钟精励:小菜请求加薪 数量500 被批准
钟精励:小菜请求加薪 数量1000 再说吧
1
2
3
4

# 结构组成

image-20221017164911912

# 模式评价

# 适用场景

一个请求有多个对象可以处理,但每个对象的处理条件或权限不同。

# 实际应用

  • Netty 中 Pipeline 与 ChannelHandler 通过责任链来组织代码逻辑。
  • Tomcat 中 Servlet 过滤器使用了责任链模式。
  • Spring 中切面编程和安全机制都使用了责任链模式。

# 优点缺点

模式优点:

  • 能够简化对象的相互连接,接收者和发送者都没有对方的明确信息,且链中的对象也不知道链的结构。
  • 避免了请求的发送者和接受者之间的耦合关系。
  • 能够随时修改请求的结构,增强了给对象指派职责的灵活性

模式缺点:

  • 请求可能到了链的末端都得不到处理,或者因为没有正确配置得不到处理。
  • 较长的责任链可能会影响到系统的性能。
上次更新: 2025-02-06 00:56:14

← state template_method→

Copyright © 2020-2025 wuzhiyong
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式