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

概念

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

组成角色

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

相关图示

图片来自:https://refactoringguru.cn/design-patterns/state
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XRtTYCD1-1681376543697)(/Users/dasouche/Library/Application Support/typora-user-images/image-20230413112815810.png)]

代码示例

//状态接口
interface State {
    
    
    void handle(Context context);
}


//具体状态实现类ConcreteStateA、ConcreteStateB
class ConcreteStateA implements State {
    
    
    @Override
    public void handle(Context context) {
    
    
        System.out.println("当前状态是 A.");
      	//设置下一个执行状态节点
        context.setState(new ConcreteStateB());
    }
}

class ConcreteStateB implements State {
    
    
    @Override
    public 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. 订单状态管理:在电商系统中,订单可能有多个状态(如待付款、待发货、已发货等),并且状态之间有一定的转换逻辑。状态模式可以帮助设计一个易于维护的订单状态管理系统。

猜你喜欢

转载自blog.csdn.net/asd1358355022/article/details/130134932