> 文章列表 > 状态设计模式(State Pattern)[论点:概念、相关角色、图示、示例代码、框架中的运用、适用场景]

状态设计模式(State Pattern)[论点:概念、相关角色、图示、示例代码、框架中的运用、适用场景]

状态设计模式(State Pattern)[论点:概念、相关角色、图示、示例代码、框架中的运用、适用场景]

文章目录

  • 概念
  • 组成角色
  • 相关图示
  • 代码示例
  • 框架中的应用
  • 适用场景

概念

        状态模式(State Pattern)是一种行为型设计模式,用于解决对象在不同状态下的行为问题。它允许一个对象在其内部状态改变时改变它的行为。状态模式主要包含三个部分:上下文(Context)、状态接口(State)和具体状态实现类(ConcreteState)。

组成角色

  1. 状态接口(State):定义一个接口,用于封装与上下文类的一个特定状态相关的行为。
  2. 具体状态实现类(ConcreteState):实现状态接口,定义与该状态相关的行为。
  3. 上下文(Context):维护一个 State 类型的对象实例,该实例定义当前的状态。

相关图示

状态设计模式(State Pattern)[论点:概念、相关角色、图示、示例代码、框架中的运用、适用场景]

代码示例

//状态接口
interface State {void handle(Context context);
}//具体状态实现类ConcreteStateA、ConcreteStateB
class ConcreteStateA implements State {@Overridepublic void handle(Context context) {System.out.println("当前状态是 A.");//设置下一个执行状态节点context.setState(new ConcreteStateB());}
}class ConcreteStateB implements State {@Overridepublic void handle(Context context) {System.out.println("当前状态是 B.");//设置下一个执行状态节点context.setState(new ConcreteStateA());}
}//上下文对象
class Context {//当前执行节点private State state;public Context(State state) {this.state = state;}public void setState(State state) {this.state = state;}public State getState() {return state;}//执行节点逻辑public void request() {state.handle(this);}
}public class StatePatternDemo {public static void main(String[] args) {State initialState = new ConcreteStateA();Context context = new Context(initialState);//状态节点流转 A -> B -> A			context.request(); // 输出:当前状态是 A.context.request(); // 输出:当前状态是 B.context.request(); // 输出:当前状态是 A.}
}

框架中的应用

        一个常见的使用状态设计模式的例子是Java线程的状态管理。Java的Thread类使用了状态模式来表示线程的不同状态,例如:NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING和TERMINATED。这些状态之间的转换由Thread类和相关的方法控制。

Thread.State枚举,它定义了Java线程的各种状态:

public enum State {NEW,RUNNABLE,BLOCKED,WAITING,TIMED_WAITING,TERMINATED;
}

线程状态之间的转换:

  1. NEW:当线程刚创建时,它处于NEW状态。在这个状态下,线程还没有开始执行。
  2. RUNNABLE:当调用线程的start()方法后,线程进入RUNNABLE状态。此时,线程已经开始执行或者准备执行,等待操作系统分配资源。
  3. BLOCKED:当线程试图获取一个已被其他线程锁定的对象的监视器(即进入synchronized块)时,线程进入BLOCKED状态。一旦锁被释放,线程将重新进入RUNNABLE状态。
  4. WAITING:当线程调用wait()、join()或LockSupport.park()方法时,线程进入WAITING状态。这表示线程正在等待另一个线程的通知或中断。当线程收到通知或中断时,它将重新进入RUNNABLE状态。
  5. TIMED_WAITING:当线程调用wait(long timeout)、sleep(long millis)、join(long millis)或LockSupport.parkNanos()等方法时,线程进入TIMED_WAITING状态。这表示线程正在等待另一个线程的通知、中断或超时。当线程收到通知、中断或超时时,它将重新进入RUNNABLE状态。
  6. TERMINATED:当线程执行完成或被中断时,它进入TERMINATED状态。在这个状态下,线程已经结束,不能再次启动。

状态切换图

在这里插入图片描述

适用场景

  1. 对象的行为随其状态改变而改变:当一个对象的行为因其内部状态而改变时,可以考虑使用状态模式。状态模式将对象的状态和行为分离,使得状态和行为可以独立地变化,提高了代码的灵活性和可维护性。
  2. 避免大量条件语句:状态模式可以减少因状态判断而导致的大量条件语句。通过使用状态模式,可以将状态相关的行为分散到各个状态类中,降低了代码的复杂性。
  3. 状态转换清晰:当一个对象的状态转换逻辑复杂且需要明确表示时,状态模式可以使状态转换更加清晰。状态模式将状态转换逻辑封装在状态类中,有助于理解和维护状态转换逻辑。

以下是一些使用状态设计模式的实际场景:

  1. 线程状态管理:Java线程状态管理是状态设计模式的一个典型应用。线程的状态(如新建、运行、阻塞等)由Thread.State枚举表示,状态之间的转换由Thread类及其相关方法控制。
  2. 工作流引擎:工作流引擎通常需要处理多个状态和状态之间的转换。状态模式可以帮助设计一个灵活的工作流引擎,使得状态和行为可以独立地变化。
  3. 游戏角色状态:在游戏开发中,角色可能有多种状态(如站立、行走、攻击等),并且状态之间可以相互转换。使用状态模式可以使游戏角色的状态管理更加清晰。
  4. 订单状态管理:在电商系统中,订单可能有多个状态(如待付款、待发货、已发货等),并且状态之间有一定的转换逻辑。状态模式可以帮助设计一个易于维护的订单状态管理系统。