【Java 设计模式】行为型之状态模式

文章目录

    • [1. 定义](#1. 定义)
    • [2. 应用场景](#2. 应用场景)
    • [3. 代码实现](#3. 代码实现)
    • 结语

状态模式(State Pattern)是一种行为型设计模式,用于通过将对象的行为封装到不同的状态类中,使得对象在不同的状态下具有不同的行为。状态模式允许对象在内部状态发生改变时改变其行为,而无需修改其代码。在本文中,我们将深入研究Java中状态模式的定义、结构、使用场景以及如何在实际开发中应用。

1. 定义

状态模式是一种行为型设计模式,用于通过将对象的行为封装到不同的状态类中,使得对象在不同的状态下具有不同的行为。状态模式允许对象在内部状态发生改变时改变其行为,而无需修改其代码。状态模式通常包含三个主要角色:上下文(Context)、抽象状态(Abstract State)和具体状态(Concrete State)。

  • 上下文(Context): 定义了一个接口,用于维护一个当前状态的引用,并提供一个用于切换状态的方法
  • 抽象状态(Abstract State): 定义了一个接口,用于封装与上下文相关的一个或多个行为
  • 具体状态(Concrete State): 实现了抽象状态的接口,负责处理与状态相关的行为

2. 应用场景

状态模式通常在以下场景中使用:

  • 一个对象的行为取决于其内部状态,并且需要在运行时根据内部状态改变其行为:

    当一个对象的行为取决于其内部状态,并且需要在运行时根据内部状态改变其行为时,可以使用状态模式

  • 一个对象具有多个状态,并且状态之间存在转换关系:

    当一个对象具有多个状态,并且这些状态之间存在转换关系时,可以使用状态模式

  • 避免使用过多的条件语句来控制对象的行为:

    当需要避免使用过多的条件语句来控制对象的行为时,可以使用状态模式,将每个状态封装到一个类中,使得代码更加清晰和可维护

3. 代码实现

下面通过一个简单的例子来演示状态模式的实现。假设有一个电梯系统,电梯有开门、关门、上行、下行和停止等状态,我们可以使用状态模式来管理电梯的不同状态。

上下文 - 电梯 ElevatorContext

java 复制代码
package com.cheney.demo;

class ElevatorContext {
    private ElevatorState currentState;

    public ElevatorContext() {
        this.currentState = new StoppedState();
    }

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

    public void openDoor() {
        currentState.openDoor(this);
    }

    public void closeDoor() {
        currentState.closeDoor(this);
    }

    public void moveUp() {
        currentState.moveUp(this);
    }

    public void moveDown() {
        currentState.moveDown(this);
    }
}

抽象状态 - 电梯状态 ElevatorState

java 复制代码
package com.cheney.demo;

interface ElevatorState {
    void openDoor(ElevatorContext context);

    void closeDoor(ElevatorContext context);

    void moveUp(ElevatorContext context);

    void moveDown(ElevatorContext context);
}

具体状态 - 停止状态 StoppedState

java 复制代码
package com.cheney.demo;

class StoppedState implements ElevatorState {
    @Override
    public void openDoor(ElevatorContext context) {
        System.out.println("开门");
        context.setState(new OpenedState());
    }

    @Override
    public void closeDoor(ElevatorContext context) {
        System.out.println("门已经关上了");
    }

    @Override
    public void moveUp(ElevatorContext context) {
        System.out.println("向上移动");
        context.setState(new MovingUpState());
    }

    @Override
    public void moveDown(ElevatorContext context) {
        System.out.println("向下移动");
        context.setState(new MovingDownState());
    }
}

具体状态 - 开门状态 OpenedState

java 复制代码
package com.cheney.demo;

class OpenedState implements ElevatorState {
    @Override
    public void openDoor(ElevatorContext context) {
        System.out.println("门已经打开了");
    }

    @Override
    public void closeDoor(ElevatorContext context) {
        System.out.println("关上门");
        context.setState(new StoppedState());
    }

    @Override
    public void moveUp(ElevatorContext context) {
        System.out.println("门打开时无法向上移动");
    }

    @Override
    public void moveDown(ElevatorContext context) {
        System.out.println("门打开时无法向下移动");
    }
}

具体状态 - 上行状态 MovingUpState

java 复制代码
package com.cheney.demo;

class MovingUpState implements ElevatorState {
    @Override
    public void openDoor(ElevatorContext context) {
        System.out.println("向上移动时无法打开门");
    }

    @Override
    public void closeDoor(ElevatorContext context) {
        System.out.println("关上门");
        context.setState(new StoppedState());
    }

    @Override
    public void moveUp(ElevatorContext context) {
        System.out.println("继续向上移动");
    }

    @Override
    public void moveDown(ElevatorContext context) {
        System.out.println("改变方向向下移动");
        context.setState(new MovingDownState());
    }
}

具体状态 - 下行状态 MovingDownState

java 复制代码
package com.cheney.demo;

class MovingDownState implements ElevatorState {
    @Override
    public void openDoor(ElevatorContext context) {
        System.out.println("向下移动时无法打开门");
    }

    @Override
    public void closeDoor(ElevatorContext context) {
        System.out.println("关上门");
        context.setState(new StoppedState());
    }

    @Override
    public void moveUp(ElevatorContext context) {
        System.out.println("改变方向向上移动");
        context.setState(new MovingUpState());
    }

    @Override
    public void moveDown(ElevatorContext context) {
        System.out.println("继续向下移动。");
    }
}

客户端启动类 Main

java 复制代码
package com.cheney.demo;

public class Main {
    public static void main(String[] args) {
        // 使用状态模式管理电梯状态
        ElevatorContext elevator = new ElevatorContext();

        // 打开门
        elevator.openDoor();
        // 关上门
        elevator.closeDoor();
        // 向上移动
        elevator.moveUp();
        // 改变方向向下移动
        elevator.moveDown();
        // 向下移动时无法打开门
        elevator.openDoor();
    }
}

在上述例子中,ElevatorContext 是上下文类,维护了当前状态的引用,并提供了用于切换状态的方法。ElevatorState 是抽象状态接口,定义了与电梯状态相关的行为。StoppedStateOpenedStateMovingUpStateMovingDownState 是具体状态类,分别实现了抽象状态接口,负责处理不同状态下的行为。

在客户端中,我们使用状态模式管理电梯的状态。通过将电梯的不同状态封装到不同的状态类中,实现了电梯状态的切换,而无需修改 ElevatorContext 的代码。

结语

状态模式是一种用于通过将对象的行为封装到不同的状态类中,使得对象在不同的状态下具有不同的行为的设计模式。通过使用状态模式,可以使代码更加清晰、可维护,并降低对象之间的耦合度。在实际开发中,状态模式常被用于处理对象的状态转换、状态机等场景。通过合理使用状态模式,可以提高系统的可扩展性和灵活性。

相关推荐
坐吃山猪4 小时前
SpringBoot01-配置文件
java·开发语言
我叫汪枫4 小时前
《Java餐厅的待客之道:BIO, NIO, AIO三种服务模式的进化》
java·开发语言·nio
yaoxtao5 小时前
java.nio.file.InvalidPathException异常
java·linux·ubuntu
Swift社区6 小时前
从 JDK 1.8 切换到 JDK 21 时遇到 NoProviderFoundException 该如何解决?
java·开发语言
DKPT7 小时前
JVM中如何调优新生代和老生代?
java·jvm·笔记·学习·spring
phltxy7 小时前
JVM——Java虚拟机学习
java·jvm·学习
seabirdssss8 小时前
使用Spring Boot DevTools快速重启功能
java·spring boot·后端
喂完待续9 小时前
【序列晋升】29 Spring Cloud Task 微服务架构下的轻量级任务调度框架
java·spring·spring cloud·云原生·架构·big data·序列晋升
benben0449 小时前
ReAct模式解读
java·ai