使用背景
在开发时,一个功能需根据场景不同自主的切换
举例
状态变化
问题
对象的状态太多,选择太复杂,简化状态的判断逻辑,客户不需要知道该用什么算法
解决方案
使用状态模式-允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。
当控制一个对象状态的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类中,可以把复杂的判断逻辑简化
使用情景
1. 状态决定行为
2. 它必须在运行时根据状态改变行为。
实现结构
组成成分
1. StateManager:将state保存起来
2. BaseState:定义算法所支持的公共接口
3. UninitState等:实现了BaseState的具体算法
优点
1. 封装了 state 切换规则
2. 将State管理都放在了StateManage里,易于管理,易于增删改。State之间复杂关系被简化,被统一管理
3. 所有的状态都被提前确定!
4. 去掉了一堆复杂的切换关系,去掉了很多if-else
缺点
1. Client必须要知道state之间的关系
2. State类的数量更多
代码实现
以为战士选择武器为例
class StateManager {
public BaseState state;
StateManager() {
}
public void setState(BaseState st) {
this.state = st;
}
public void move() {
state.move();
}
}
interface BaseState {
void move();
}
class UninitState implements BaseState {
StateManager mManager;
UninitState(StateManager m) {
mManager = m;
}
public void move() {
mManager.state = new InitState(mManager);
System.out.println("name = " + this.getClass().getName());
}
}
class InitState implements BaseState {
StateManager mManager;
InitState(StateManager m) {
mManager = m;
}
public void move() {
mManager.state = new ReadyState(mManager);
System.out.println("name = " + this.getClass().getName());
}
}
class ReadyState implements BaseState {
StateManager mManager;
ReadyState(StateManager m) {
mManager = m;
}
public void move() {
mManager.state = new RunningState(mManager);
System.out.println("name = " + this.getClass().getName());
}
}
class RunningState implements BaseState {
StateManager mManager;
RunningState(StateManager m) {
mManager = m;
}
public void move() {
mManager.state = new StoppedState(mManager);
System.out.println("name = " + this.getClass().getName());
}
}
class StoppedState implements BaseState {
StateManager mManager;
StoppedState(StateManager m) {
mManager = m;
}
public void move() {
System.out.println("name = " + this.getClass().getName());
}
}
class state {
public static void main(String[] args) {
StateManager mManager = new StateManager();
mManager.setState(new UninitState(mManager));
mManager.move();
mManager.move();
mManager.move();
mManager.move();
mManager.move();
}
}
运行结果:
name = UninitState
name = InitState
name = ReadyState
name = RunningState
name = StoppedState