1. 基本概念

状态模式(State Pattern)是一种行为型设计模式,它适用于一个对象在在不同的状态下有不同的行为时,比如说电灯的开、关、闪烁是不停的状态,状态不同时,对应的行为也不同,在没有状态模式的情况下,为了添加新的状态或修改现有的状态,往往需要修改已有的代码,这违背了开闭原则,而且如果对象的状态切换逻辑和各个状态的行为都在同一个类中实现,就可能导致该类的职责过重,不符合单一职责原则。

而状态模式将每个状态的行为封装在一个具体状态类中,使得每个状态类相对独立,并将对象在不同状态下的行为进行委托,从而使得对象的状态可以在运行时动态改变,每个状态的实现也不会影响其他状态。

2. 基本结构

状态模式包括以下几个重要角色:

  • State(状态): 定义一个接口,用于封装与Context的一个特定状态相关的行为。
  • ConcreteState(具体状态): 负责处理Context在状态改变时的行为, 每一个具体状态子类实现一个与Context的一个状态相关的行为。
  • Context(上下文): 维护一个具体状态子类的实例,这个实例定义当前的状态。

3. 基本使用

  1. 定义状态接口:创建一个状态接口,该接口声明了对象可能的各种状态对应的方法。
1
2
3
4
// 状态接口
public interface State {
void handle();
}
  1. 实现具体状态类: 为对象可能的每种状态创建具体的状态类,实现状态接口中定义的方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 具体状态类1
public class ConcreteState1 implements State {
@Override
public void handle() {
// 执行在状态1下的操作
}
}

// 具体状态类2
public class ConcreteState2 implements State {
@Override
public void handle() {
// 执行在状态2下的操作
}
}
  1. 创建上下文类:该类包含对状态的引用,并在需要时调用当前状态的方法。
1
2
3
4
5
6
7
8
9
10
11
12
// 上下文类
public class Context {
private State currentState;

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

public void request() {
currentState.handle();
}
}
  1. 客户端使用:创建具体的状态对象和上下文对象,并通过上下文对象调用相应的方法。通过改变状态,可以改变上下文对象的行为
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Client {
public static void main(String[] args) {
Context context = new Context();

State state1 = new ConcreteState1();
State state2 = new ConcreteState2();

context.setState(state1);
context.request(); // 执行在状态1下的操作

context.setState(state2);
context.request(); // 执行在状态2下的操作
}
}

4. 使用场景

状态模式将每个状态的实现都封装在一个类中,每个状态类的实现相对独立,使得添加新状态或修改现有状态变得更加容易,避免了使用大量的条件语句来控制对象的行为。但是如果状态过多,会导致类的数量增加,可能会使得代码结构复杂。

总的来说,状态模式适用于有限状态机的场景,其中对象的行为在运行时可以根据内部状态的改变而改变,在游戏开发中,Unity3D 的 Animator 控制器就是一个状态机。它允许开发人员定义不同的状态(动画状态),并通过状态转换来实现角色的动画控制和行为切换。


本站由 卡卡龙 使用 Stellar 1.29.1主题创建

本站访问量 次. 本文阅读量 次.