定义
状态模式(State Pattern)是一种行为型设计模式,它允许一个对象在其内部状态改变时改变它的行为。这个对象看起来好像修改了它的类。
以下是状态模式的主要特点和定义:
主要角色
-
Context(环境类) :
- 定义客户端所感兴趣的接口,并且保留一个具体状态类的实例,这个实例来决定当前的状态。
- 负责处理请求,将请求委托给当前的状态对象来处理。
-
State(抽象状态类) :
- 定义一个接口以封装与 Context 的一个特定状态相关的行为。
-
ConcreteState(具体状态类) :
- 每一个具体状态类都实现了抽象状态类定义的接口,负责具体的状态相关行为。
业务
假设我们正在开发一个游戏角色,这个角色有不同的状态,如正常状态、加速状态和受伤状态。每个状态下角色的行为都不同。
classDiagram
class CharacterState {
+move() : void
+attack() : void
}
class NormalState {
+move() : void
+attack() : void
}
class AcceleratedState {
+move() : void
+attack() : void
}
class InjuredState {
+move() : void
+attack() : void
}
class GameCharacter {
-CharacterState state
+GameCharacter()
+setState(CharacterState) : void
+move() : void
+attack() : void
}
CharacterState <|-- NormalState
CharacterState <|-- AcceleratedState
CharacterState <|-- InjuredState
GameCharacter "1" --> "1" CharacterState
一、定义抽象状态类(State)
interface CharacterState {
void move();
void attack();
}
二、定义具体状态类(ConcreteState)
- 正常状态:
class NormalState implements CharacterState {
@Override
public void move() {
System.out.println("Moving at normal speed.");
}
@Override
public void attack() {
System.out.println("Normal attack.");
}
}
- 加速状态:
class AcceleratedState implements CharacterState {
@Override
public void move() {
System.out.println("Moving at accelerated speed.");
}
@Override
public void attack() {
System.out.println("Powerful attack.");
}
}
- 受伤状态:
class InjuredState implements CharacterState {
@Override
public void move() {
System.out.println("Moving slowly.");
}
@Override
public void attack() {
System.out.println("Weak attack.");
}
}
三、定义环境类(Context)
class GameCharacter {
private CharacterState state;
public GameCharacter() {
state = new NormalState();
}
public void setState(CharacterState state) {
this.state = state;
}
public void move() {
state.move();
}
public void attack() {
state.attack();
}
}
四、使用状态模式
public class StatePatternExample {
public static void main(String[] args) {
GameCharacter character = new GameCharacter();
character.move();
character.attack();
character.setState(new AcceleratedState());
character.move();
character.attack();
character.setState(new InjuredState());
character.move();
character.attack();
}
}
在这个例子中,CharacterState是抽象状态类,定义了角色的行为接口。NormalState、AcceleratedState和InjuredState是具体状态类,实现了不同状态下的具体行为。GameCharacter是环境类,它持有一个当前状态对象,并将行为委托给当前状态对象来执行。通过这种方式,我们可以在运行时根据角色的状态改变其行为,实现了状态模式的设计。
总结
使用场景
-
对象的行为取决于它的状态,并且它必须在运行时根据状态改变它的行为。
- 例如,一个订单在不同的状态(如待支付、已支付、已发货、已完成等)下有不同的操作和显示。
-
一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。
- 使用状态模式可以将这些条件语句转换为状态类,使得代码更加清晰和易于维护。
优点
-
状态模式将与特定状态相关的行为局部化,使得代码更加清晰、易于理解和维护。
- 每个状态类只负责处理自己的状态相关的行为,而不是将所有的状态相关行为都集中在一个庞大的类中。
-
状态转换更加清晰。
- 通过状态类之间的切换,可以清晰地看到对象在不同状态之间的转换过程。
-
易于扩展。
- 可以方便地添加新的状态类,而不会影响现有的状态类和环境类。
缺点
-
状态模式会增加系统中类和对象的数量。
- 对于每个状态都需要创建一个具体状态类,这可能会导致系统变得复杂。
-
状态模式的结构相对复杂,对于简单的状态管理可能会引入不必要的复杂性。