【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 的代码。

结语

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

相关推荐
激流丶7 分钟前
【Kafka 实战】如何解决Kafka Topic数量过多带来的性能问题?
java·大数据·kafka·topic
Themberfue11 分钟前
Java多线程详解⑤(全程干货!!!)线程安全问题 || 锁 || synchronized
java·开发语言·线程·多线程·synchronized·
让学习成为一种生活方式27 分钟前
R包下载太慢安装中止的解决策略-R语言003
java·数据库·r语言
晨曦_子画33 分钟前
编程语言之战:AI 之后的 Kotlin 与 Java
android·java·开发语言·人工智能·kotlin
南宫生1 小时前
贪心算法习题其三【力扣】【算法学习day.20】
java·数据结构·学习·算法·leetcode·贪心算法
Heavydrink1 小时前
HTTP动词与状态码
java
ktkiko111 小时前
Java中的远程方法调用——RPC详解
java·开发语言·rpc
计算机-秋大田2 小时前
基于Spring Boot的船舶监造系统的设计与实现,LW+源码+讲解
java·论文阅读·spring boot·后端·vue
神里大人2 小时前
idea、pycharm等软件的文件名红色怎么变绿色
java·pycharm·intellij-idea
小冉在学习2 小时前
day53 图论章节刷题Part05(并查集理论基础、寻找存在的路径)
java·算法·图论