允许一个对象在内部状态改变时改变它的行为。
应用场景
-
一个对象的行为取决于它的状态,并且它在运行时根据状态改变它的行为。
-
代码中包含大量与对象状态相关的判断语句。
优点:
-
将不同的状态隔离
-
把各种状态的转换逻辑,分布到State的子类中,减少相互间依赖
-
增加新的状态非常简单
状态模式与责任链模式的区别
状态模式和责任链模式都能消除 if-else 分支过多的问题。但在某些情况下,状态模式中的状态可以理解为责任,那么在这种情况下,两种模式都可以使用。
从定义来看,状态模式强调的是一个对象内在状态的改变,而责任链模式强调的是外部节点对象间的改变。
从代码实现上来看,两者最大的区别就是状态模式的各个状态对象知道自己要进入的下一个状态对象,而责任链模式并不清楚其下一个节点处理对象,因为链式组装由客户端负责。
状态模式与策略模式的区别
状态模式和策略模式的 UML 类图架构几乎完全一样,但两者的应用场景是不一样的。策略模式的多种算法行为择其一都能满足,彼此之间是独立的,用户可自行更换策略算法,而状态模式的各个状态间存在相互关系,彼此之间在一定条件下存在自动切换状态的效果,并且用户无法指定状态,只能设置初始状态。
当使用Context类切换状态时,状态类之间互相不认识,他们直接的依赖关系应该由客户端负责。
当使用具体的State类切换时,状态直接就可能互相认识,一个状态执行完就自动切换到了另一个状态去了
用Context类切换状态
买键盘,物流系统就很适合使用状态模式来开发,因为此过程存在很多不同的状态,例如接单,出库,运输,送货,收货,评价等等。而订单在每个不同的状态下的操作可能都不一样。
// 定义一个状态接口
public interface LogisticsState {
void doAction(JdLogistics context);
}
// 定义一个物流Context类
// 此类持有一个LogisticsState 的引用,负责在流程中保持并切换状态
public class JdLogistics {
private LogisticsState logisticsState;
public void setLogisticsState(LogisticsState logisticsState) {
this.logisticsState = logisticsState;
}
public LogisticsState getLogisticsState() {
return logisticsState;
}
public void doAction(){
Objects.requireNonNull(logisticsState);
logisticsState.doAction(this);
}
}
//接单状态类
public class OrderState implements LogisticsState {
@Override
public void doAction(JdLogistics context) {
System.out.println("商家已经接单,正在处理中...");
}
}
//