一句话总结
在其位 谋其政
个人感觉这个总结不是太好 但是脑子第一反应就是这句话 就用他来解释吧
- 在其位
在其位说明是坐在这个位置上 (达到某个状态) 说明类里面有个对象是记录状态的(还是个抽象类)
位置不止一个状态也不止一个 (抽象类的子类不止一个)
当状态增加的时候 对应的实现类也增加
- 谋其政
只有我拥有某个权力后才会干相应的事 (类的行为是基于它的状态改变的)
达到某个状态才调用对应的方法 (方法可能不止一个)
这样理解可以很简单的分析出状态模式的3个角色
-
State :(规范我的行为)是一个接口,封装了状态及其行为
-
ConcreteState X:(不同状态的我) State的实现类,表示具体的状态(不同的状态重写不同的方法)
-
Context :(善变的我) 保持并切换各个状态,其持有一个State的引用。它将依赖状态的各种操作委托给不同的状态对象执行。其负责与客户端交互
UML类图

状态模式之京东物流
双十一女朋友送了个固态硬盘 自从下单以来,我看物流状态信息,心心念念着自己的固态硬盘快点到…
这个物流系统就很适合使用状态模式来开发,因为此过程存在很多不同的状态,例如接单,出库,运输,送货,收货,评价等等。而订单在每个不同的状态下的操作可能都不一样,例如在接单状态下,商家就需要通知仓库拣货,通知用户等等操作,其他状态类似
下面是实例的UML类图

第一,定义一个状态接口
此接口定义各个状态的统一操作接口
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);
}
}
第三,实现各种状态类
接单状态类,其需要实现LogisticsState接口
//接单状态
public class OrderState implements LogisticsState {
@Override
public void doAction(JdLogistics context) {
System.out.println("商家已经接单,正在处理中...");
}
}
//出库状态类
public class ProductOutState implements LogisticsState {
@Override
public void doAction(JdLogistics context) {
System.out.println("商品已经出库...");
}
}
//运输状态
public class TransportState implements LogisticsState {
@Override
public void doAction(JdLogistics context) {
System.out.println("商品正在运往河南分发中心");
}
}
依次类推,可以建立任意多个状态类
第四, 客户端使用
public class StateClient {
public static void main(String[] args) {
//状态的保持与切换者
JdLogistics jdLogistics = new JdLogistics();
/**
* 客户下单商家接单时调用相关接口把接单状态赋值
*/
//接单状态
OrderState orderState = new OrderState();
jdLogistics.setLogisticsState(orderState);
jdLogistics.doAction();
/**
* 当快递小哥扫描订单后 调用相关接口 状态赋值为出库
*/
//出库状态
ProductOutState productOutState = new ProductOutState();
jdLogistics.setLogisticsState(productOutState);
jdLogistics.doAction();
/**
* 当快递车发车后 调用接口 状态赋值为出库
*/
//运输状态
TransportState transportState = new TransportState();
jdLogistics.setLogisticsState(transportState);
jdLogistics.doAction();
}
}
输出结果:
商家已经接单,正在处理中...
商品已经出库...
商品正在运往河南分发中心
可见,我们将每个状态下要做的具体动作封装到了每个状态类中,我们只需要切换不同的状态即可。如果不使用状态模式,我们的代码中可能会出现很长的if else列表,这样就不便于扩展和修改了。
以下来之菜鸟教程
介绍
意图:允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类。
主要解决:对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为。
何时使用:代码中包含大量与对象状态有关的条件语句。
如何解决:将各种具体的状态类抽象出来。
关键代码:通常命令模式的接口中只有一个方法。而状态模式的接口中有一个或者多个方法。而且,状态模式的实现类的方法,一般返回值,或者是改变实例变量的值。也就是说,状态模式一般和对象的状态有关。实现类的方法有不同的功能,覆盖接口中的方法。状态模式和命令模式一样,也可以用于消除 if…else 等条件选择语句。
应用实例: 1、打篮球的时候运动员可以有正常状态、不正常状态和超常状态。 2、曾侯乙编钟中,‘钟是抽象接口’,'钟A’等是具体状态,'曾侯乙编钟’是具体环境(Context)。
优点: 1、封装了转换规则。 2、枚举可能的状态,在枚举状态之前需要确定状态种类。 3、将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为。 4、允许状态转换逻辑与状态对象合成一体,而不是某一个巨大的条件语句块。 5、可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数。
缺点: 1、状态模式的使用必然会增加系统类和对象的个数。 2、状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱。 3、状态模式对"开闭原则"的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态,而且修改某个状态类的行为也需修改对应类的源代码。
使用场景: 1、行为随状态改变而改变的场景。 2、条件、分支语句的代替者。
注意事项:在行为受状态约束的时候使用状态模式,而且状态不超过 5 个。
状态模式是一种行为设计模式,用于当对象的行为取决于其状态时。本文通过京东物流的例子,阐述了如何定义状态接口、物流Context类以及各种具体状态类,并讨论了状态模式的优势和适用场景,有助于减少代码中的条件语句并提高可扩展性。
1542

被折叠的 条评论
为什么被折叠?



