状态模式是行为设计模式的一种。当对象根据其内部状态更改其行为时,将使用状态设计模式。
如果我们必须根据状态改变对象的行为,我们可以在对象中有一个状态变量,并使用 if-else 条件块根据状态执行不同的操作。状态模式用于通过上下文和状态实现提供一种系统的和失去耦合的方式来实现这一点。
状态设计模式的 UML 图
- 上下文:定义了一个与客户端进行交互的接口。它维护对可用于定义对象当前状态的具体状态对象的引用。
- 状态:定义用于声明每个具体状态应该做什么的接口。
- ConcreteState:为 State 中定义的方法提供实现。
状态设计模式示例
在下面的例子中,我们实现了一个移动状态场景。关于警报,移动设备可以处于不同的状态。比如震动和静音。基于此警报状态,当要完成警报时移动设备的行为会发生变化。
// Java program to demonstrate working of
// State Design Pattern
interface MobileAlertState
{
public void alert(AlertStateContext ctx);
}
class AlertStateContext
{
private MobileAlertState currentState;
public AlertStateContext()
{
currentState = new Vibration();
}
public void setState(MobileAlertState state)
{
currentState = state;
}
public void alert()
{
currentState.alert(this);
}
}
class Vibration implements MobileAlertState
{
@Override
public void alert(AlertStateContext ctx)
{
System.out.println("vibration...");
}
}
class Silent implements MobileAlertState
{
@Override
public void alert(AlertStateContext ctx)
{
System.out.println("silent...");
}
}
class StatePattern
{
public static void main(String[] args)
{
AlertStateContext stateContext = new AlertStateContext();
stateContext.alert();
stateContext.alert();
stateContext.setState(new Silent());
stateContext.alert();
stateContext.alert();
stateContext.alert();
}
}
输出:
vibration...
vibration...
silent...
silent...
silent...
状态设计模式的优点
- 使用状态模式,实现多态行为的好处是显而易见的,并且也更容易添加状态来支持额外的行为。
- 在状态设计模式中,对象的行为是其状态函数的结果,并且行为在运行时根据状态而改变。这消除了对 if/else 或 switch/case 条件逻辑的依赖。例如,在电视遥控场景中,我们也可以通过简单地编写一个类和方法来实现该行为,该类和方法将请求参数并使用 if/else 块执行操作(打开/关闭电视)。
- State 设计模式还改进了 Cohesion,因为特定于状态的行为被聚合到 ConcreteState 类中,这些类位于代码中的一个位置。
状态设计模式的缺点
- 当我们需要在运行时通过输入某个 State 基类的不同子类来改变对象的状态时,可以使用 State 设计模式。这种情况既有利也有弊,因为我们有一个明确的独立的 State 类,具有一些逻辑,另一方面,类的数量增加了。