【设计模式】行为型模式(三):责任链模式、状态模式

行为型模式(三):责任链模式、状态模式

  • [5.责任链模式(Chain of Responsibility)](#5.责任链模式(Chain of Responsibility))
    • [5.1 通俗易懂的解释](#5.1 通俗易懂的解释)
    • [5.2 具体步骤](#5.2 具体步骤)
    • [5.3 代码示例](#5.3 代码示例)
      • [5.3.1 处理者接口](#5.3.1 处理者接口)
      • [5.3.2 具体处理者](#5.3.2 具体处理者)
      • [5.3.3 测试类](#5.3.3 测试类)
      • [5.3.4 输出](#5.3.4 输出)
    • [5.4 总结](#5.4 总结)
  • 6.状态模式(State)
    • [6.1 通俗易懂的解释](#6.1 通俗易懂的解释)
    • [6.2 具体步骤](#6.2 具体步骤)
    • [6.3 代码示例](#6.3 代码示例)
      • [6.3.1 定义状态接口](#6.3.1 定义状态接口)
      • [6.3.2 具体状态](#6.3.2 具体状态)
      • [6.3.3 定义上下文类](#6.3.3 定义上下文类)
      • [6.3.4 测试类](#6.3.4 测试类)
      • [6.3.5 输出](#6.3.5 输出)
    • [6.4 总结](#6.4 总结)

5.责任链模式(Chain of Responsibility)

责任链模式Chain of Responsibility)是一种行为设计模式,它允许你将请求沿着处理者链进行传递,直到有一个处理者能够处理该请求。每个处理者都可以决定是否处理该请求,或者将请求传递给下一个处理者。这样可以将请求的处理逻辑分散到多个处理者中,而不是集中在一个地方。

5.1 通俗易懂的解释

想象一下你在一个公司里,有一个请假的流程。员工请假时,需要经过多个审批环节,比如:

  • 直接上级:首先由直接上级审批。
  • 部门经理:如果直接上级批准了,再由部门经理审批。
  • 人力资源部:如果部门经理也批准了,最后由人力资源部审批。

在这个过程中,每个审批者都有权决定是否批准请假请求,或者将请求传递给下一个审批者。如果某个审批者拒绝了请求,流程就结束了。如果所有审批者都批准了,员工的请假请求就通过了。

5.2 具体步骤

  • 创建请求:员工提交请假请求。
  • 传递请求:请求首先传递给直接上级。
  • 处理请求
    • 如果直接上级批准,请求传递给部门经理。
    • 如果部门经理批准,请求传递给人事部。
    • 如果人事部批准,请求处理完成。
    • 如果任何一个审批者拒绝,请求处理结束。

5.3 代码示例

下面是一个简单的 Java 代码示例,展示了责任链模式的实现。

5.3.1 处理者接口

java 复制代码
// 定义处理者接口
interface Handler {
    void setNext(Handler next);
    void handleRequest(String request);
}

5.3.2 具体处理者

java 复制代码
// 具体处理者类
class DirectSupervisor implements Handler {
    private Handler next;

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

    @Override
    public void handleRequest(String request) {
        if (request.equals("请假1天")) {
            System.out.println("直接上级批准了你的请假请求");
        } else if (next != null) {
            next.handleRequest(request);
        } else {
            System.out.println("没有更多审批者了");
        }
    }
}

class DepartmentManager implements Handler {
    private Handler next;

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

    @Override
    public void handleRequest(String request) {
        if (request.equals("请假3天")) {
            System.out.println("部门经理批准了你的请假请求");
        } else if (next != null) {
            next.handleRequest(request);
        } else {
            System.out.println("没有更多审批者了");
        }
    }
}

class HR implements Handler {
    private Handler next;

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

    @Override
    public void handleRequest(String request) {
        if (request.equals("请假7天")) {
            System.out.println("人力资源部批准了你的请假请求");
        } else if (next != null) {
            next.handleRequest(request);
        } else {
            System.out.println("没有更多审批者了");
        }
    }
}

5.3.3 测试类

java 复制代码
// 测试类
public class ChainOfResponsibilityExample {
    public static void main(String[] args) {
        Handler directSupervisor = new DirectSupervisor();
        Handler departmentManager = new DepartmentManager();
        Handler hr = new HR();

        // 设置责任链
        directSupervisor.setNext(departmentManager);
        departmentManager.setNext(hr);

        // 测试请求
        directSupervisor.handleRequest("请假1天");
        directSupervisor.handleRequest("请假3天");
        directSupervisor.handleRequest("请假7天");
        directSupervisor.handleRequest("请假10天");
    }
}

5.3.4 输出

plain 复制代码
直接上级批准了你的请假请求
部门经理批准了你的请假请求
人力资源部批准了你的请假请求
没有更多审批者了

5.4 总结

责任链模式通过将请求沿着处理者链传递,使得每个处理者都可以决定是否处理该请求,或者将请求传递给下一个处理者。这样可以将处理逻辑分散到多个处理者中,提高代码的灵活性和可扩展性。

6.状态模式(State)

状态模式State)是一种行为设计模式,它允许一个对象在其内部状态改变时改变其行为。简单来说,就是让对象的行为随着其状态的变化而变化。这样可以避免大量的条件判断语句,使代码更加清晰和易于维护。

6.1 通俗易懂的解释

想象一下你有一个智能灯泡,它可以有三种状态:关闭、低亮度和高亮度。每种状态下,灯泡的行为是不同的:

  • 关闭状态:灯泡是暗的,按下开关后,灯泡会变成低亮度。
  • 低亮度状态:灯泡是亮的,但亮度较低,按下开关后,灯泡会变成高亮度。
  • 高亮度状态:灯泡是亮的,亮度较高,按下开关后,灯泡会变成关闭。

在这个例子中,灯泡的行为(即按下开关后的反应)会随着其状态的变化而变化。这就是状态模式的核心思想。

6.2 具体步骤

  • 定义状态接口:定义一个状态接口,声明所有状态共有的方法。
  • 实现具体状态:为每种状态实现一个具体的状态类,每个类实现状态接口中的方法。
  • 定义上下文:定义一个上下文类,持有当前状态的引用,并提供改变状态的方法。
  • 改变状态:在上下文类中,根据当前状态调用相应的方法,并在需要时改变状态。

6.3 代码示例

下面是一个简单的 Java 代码示例,展示了状态模式的实现。

6.3.1 定义状态接口

java 复制代码
// 定义状态接口
interface LightState {
    void handleContext(LightContext context);
    String getStateName();
}

6.3.2 具体状态

java 复制代码
// 具体状态类:关闭状态
class OffState implements LightState {
    @Override
    public void handleContext(LightContext context) {
        System.out.println("灯泡从关闭状态变为低亮度状态");
        context.setState(new LowBrightnessState());
    }

    @Override
    public String getStateName() {
        return "关闭状态";
    }
}

// 具体状态类:低亮度状态
class LowBrightnessState implements LightState {
    @Override
    public void handleContext(LightContext context) {
        System.out.println("灯泡从低亮度状态变为高亮度状态");
        context.setState(new HighBrightnessState());
    }

    @Override
    public String getStateName() {
        return "低亮度状态";
    }
}

// 具体状态类:高亮度状态
class HighBrightnessState implements LightState {
    @Override
    public void handleContext(LightContext context) {
        System.out.println("灯泡从高亮度状态变为关闭状态");
        context.setState(new OffState());
    }

    @Override
    public String getStateName() {
        return "高亮度状态";
    }
}

6.3.3 定义上下文类

java 复制代码
// 定义上下文类
class LightContext {
    private LightState state;

    public LightContext() {
        this.state = new OffState(); // 初始状态为关闭
    }

    public void setState(LightState state) {
        this.state = state;
    }

    public void pressSwitch() {
        state.handleContext(this);
    }

    public String getCurrentStateName() {
        return state.getStateName();
    }
}
  • this 关键字:this 关键字在 Java 中表示当前对象的引用。在 pressSwitch 方法中,this 指的是调用 pressSwitch 方法的 LightContext 实例。
  • state.handleContext(this):这行代码调用了 state 对象的 handleContext 方法,并将 LightContext 的当前实例作为参数传递给 handleContext 方法。

6.3.4 测试类

java 复制代码
// 测试类
public class StatePatternExample {
    public static void main(String[] args) {
        LightContext light = new LightContext();

        // 模拟按下开关
        light.pressSwitch(); // 关闭 -> 低亮度
        System.out.println("当前状态: " + light.getCurrentStateName());

        light.pressSwitch(); // 低亮度 -> 高亮度
        System.out.println("当前状态: " + light.getCurrentStateName());

        light.pressSwitch(); // 高亮度 -> 关闭
        System.out.println("当前状态: " + light.getCurrentStateName());
    }
}

6.3.5 输出

plain 复制代码
灯泡从关闭状态变为低亮度状态
当前状态: 低亮度状态
灯泡从低亮度状态变为高亮度状态
当前状态: 高亮度状态
灯泡从高亮度状态变为关闭状态
当前状态: 关闭状态

6.4 总结

状态模式通过将对象的行为封装在不同的状态类中,使得对象的行为随着其状态的变化而变化。这样可以避免大量的条件判断语句,使代码更加清晰和易于维护。

相关推荐
卡尔特斯2 小时前
Android Kotlin 项目代理配置【详细步骤(可选)】
android·java·kotlin
白鲸开源2 小时前
Ubuntu 22 下 DolphinScheduler 3.x 伪集群部署实录
java·ubuntu·开源
ytadpole2 小时前
Java 25 新特性 更简洁、更高效、更现代
java·后端
纪莫3 小时前
A公司一面:类加载的过程是怎么样的? 双亲委派的优点和缺点? 产生fullGC的情况有哪些? spring的动态代理有哪些?区别是什么? 如何排查CPU使用率过高?
java·java面试⑧股
JavaGuide3 小时前
JDK 25(长期支持版) 发布,新特性解读!
java·后端
用户3721574261353 小时前
Java 轻松批量替换 Word 文档文字内容
java
白鲸开源3 小时前
教你数分钟内创建并运行一个 DolphinScheduler Workflow!
java
晨米酱4 小时前
JavaScript 中"对象即函数"设计模式
前端·设计模式
Java中文社群4 小时前
有点意思!Java8后最有用新特性排行榜!
java·后端·面试
代码匠心4 小时前
从零开始学Flink:数据源
java·大数据·后端·flink