JAVA设计模式17:状态模式,允许对象在不同的内部状态下改变其行为

2023-10-28 09:56:53 浏览数 (1)

一、什么是状态模式

状态模式是一种行为型设计模式,它允许对象在不同的内部状态下改变其行为

状态模式通过将对象的行为封装在不同的状态对象中,使得对象根据其内部状态的改变而改变其行为,而不是通过大量的条件语句来判断。这样可以简化复杂的条件判断逻辑,并提高代码的可读性和可维护性。

在状态模式中,有

3

个核心角色。

  1. 环境(Context):环境是包含状态对象的类,它在运行时会根据内部状态来选择不同的状态对象,并将操作委托给该状态对象来处理。
  2. 抽象状态(State):抽象状态定义了一个共同接口,用于封装与环境相关的行为。
  3. 具体状态(Concrete State):具体状态实现了抽象状态接口,它具体定义了在特定状态下的行为。

状态模式的工作原理如下,请同学们认真学习。

  1. 环境对象内部维护一个当前状态对象的引用。
  2. 客户端通过调用环境对象的方法来触发相应的操作。
  3. 环境对象将操作委托给当前状态对象来处理。
  4. 当前状态对象根据自身的逻辑处理操作,并可能改变环境对象的状态。
  5. 环境对象根据当前状态的改变,选择不同的状态对象来处理后续的操作。

状态模式的优点包括以下

3

点,请同学们认真学习。

  1. 可以将复杂的条件判断逻辑封装在不同的状态对象中,使代码更加清晰和易于维护。
  2. 状态对象可以独立变化,增加新的状态或者修改现有状态不会对其他部分产生影响。
  3. 符合开闭原则,增加新的状态无需修改原有代码。

状态模式适用于以下

3

个场景,请同学们认真学习。

  1. 对象的行为取决于其内部状态,并且需要在运行时根据状态改变行为。
  2. 代码中包含大量的条件判断语句,需要通过封装来简化代码。
  3. 对象的状态可以彼此转换,并且需要根据状态转换来改变行为。

一个经典的示例是电梯控制系统,其中电梯可以处于不同的状态(如停止、上升、下降),不同状态下电梯的行为会有所不同。

通过状态模式,可以将每个状态封装在不同的状态对象中,并根据电梯的当前状态来切换状态对象,从而实现电梯的行为变化。


二、状态模式实例

以下是一个简单的 Java 状态模式的示例代码,以电梯的状态变化为例,请同学们复制到本地执行。

首先,定义一个抽象状态类 ElevatorState,其中包含了抽象方法 handle,代码如下。

代码语言:javascript复制
public abstract class ElevatorState {
    public abstract void handle();
}

然后,定义具体的状态类,如 StopStateUpStateDownState,它们继承自 ElevatorState 并实现 handle 方法,代码如下。

代码语言:javascript复制
public class StopState extends ElevatorState {
    @Override
    public void handle() {
        System.out.println("电梯停止状态");
    }
}

public class UpState extends ElevatorState {
    @Override
    public void handle() {
        System.out.println("电梯上升状态");
    }
}

public class DownState extends ElevatorState {
    @Override
    public void handle() {
        System.out.println("电梯下降状态");
    }
}

接下来,定义环境类 Elevator,其中包含一个当前状态对象 currentState,代码如下。

代码语言:javascript复制
public class Elevator {
    private ElevatorState currentState;

    public Elevator() {
        currentState = new StopState();
    }

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

    public void requestUp() {
        currentState.handle();
        setCurrentState(new UpState());
    }

    public void requestDown() {
        currentState.handle();
        setCurrentState(new DownState());
    }

    public void stop() {
        currentState.handle();
        setCurrentState(new StopState());
    }
}

最后,我们可以在客户端代码中使用状态模式,代码如下。

代码语言:javascript复制
public class Client {
    public static void main(String[] args) {
        Elevator elevator = new Elevator();
        elevator.requestUp();
        elevator.requestDown();
        elevator.stop();
    }
}

运行以上代码,输出结果如下。

代码语言:javascript复制
电梯停止状态
电梯上升状态
电梯下降状态
电梯停止状态

通过状态模式,我们可以根据电梯的状态切换不同的行为,将状态的判断和处理逻辑封装在具体的状态类中,提高了代码的可扩展性和可维护性。


三、状态模式的应用场景

状态模式在以下场景中适用于以下

3

个应用场景。

  1. 对象的行为取决于其内部状态,并且需要在运行时根据状态改变行为。状态模式能够将不同的状态和行为进行封装,解耦了对象的状态和行为之间的依赖关系。
  2. 当代码中包含大量的条件判断语句时,可以通过状态模式来简化代码。状态模式将条件判断逻辑封装在不同的状态对象中,使得代码更加清晰和易于维护。
  3. 对象的状态可以彼此转换,并且需要根据状态转换来改变行为。状态模式通过定义不同的状态对象,使得状态之间的转换变得简单和灵活。

另外还有一些常见的应用场景需要同学们了解。

  1. 电梯控制系统:电梯可以处于不同的状态(如停止、上升、下降),不同状态下电梯的行为会有所不同。通过状态模式,可以将每个状态封装在不同的对象中,并根据电梯的当前状态来切换状态对象,从而实现电梯的行为变化。
  2. 订单状态管理:订单可以处于不同的状态(如待支付、已支付、已发货、已完成),不同状态下订单的处理逻辑也会有所不同。使用状态模式,可以将每个订单状态封装为不同的状态对象,根据订单的当前状态来执行相应的操作。
  3. 游戏角色状态管理:角色在游戏中可以处于不同的状态(如正常、受伤、死亡),不同状态下角色的行为和属性也会发生变化。通过状态模式,可以将每个角色状态封装为不同的状态对象,根据角色的当前状态来执行相应的操作。

总的来说,状态模式适用于对象的行为随着内部状态的改变而改变的场景。它能够将不同状态的行为封装在不同的状态对象中,使得代码更加清晰、灵活和易于扩展。


四、状态模式面试题

一、请解释状态模式的定义和工作原理。

回答:状态模式是一种行为型设计模式。它允许对象在不同的内部状态下改变其行为。状态模式通过将对象的行为封装在不同的状态对象中,使得对象根据其内部状态的改变而改变其行为,而不通过大量的条件语句来判断。在状态模式中,有三个核心角色:环境(Context)、抽象状态(State)和具体状态(ConcreteState)。

工作原理如下:

  1. 环境对象内部维护一个当前状态对象的引用。
  2. 客户端通过调用环境对象的方法来触发相应的操作。
  3. 环境对象将操作委托给当前状态来处理。
  4. 当前状态对象根据自身的逻辑处理操作,并可能改变环境对象的状态。
  5. 环境对象根据当前状态的改变,选择不同的状态对象来处理后续的操作。

二、状态模式和策略模式有何区别?

回答:状态模式和策略模式有一些相似之处,它们都涉及到将不同的行为封装在对象中,并根据不同的情况来进行切换。但是它们的关注点略有不同:

  • 状态模式关注于对象的内部状态的变化,以及状态变化对行为的影响。它通过封装不同的状态对象来实现行为的变化。
  • 策略模式关注于算法的选择和切换,以便根据不同的情况选择不同的算法来完成任务。

总的来说,状态模式更加强调对象内部状态的改变和行为的变化,而策略模式更加强调在不同情况下选择不同的算法。

0 人点赞