状态机模式
状态模式
- 状态模式定义:
- 使用场景
- 角色定义
- 1. State一抽象状态角色
- 2. ConcreteState一-具体状态角色
- 3. Context--环境角色
- 需求背景
- 1. 订单状态抽象类
- 2. 定义订单具体状态类并集成基类(抽象类)
- 2.1 订单创建状态
- 2.2 订单已支付状态
- 2.3 订单已发货状态
- 2.4 订单已签收状态
- 2.5 订单已确认收货状态
- 2.6 订单已取消状态
- 3. 订单上下文类
- 4. 测试案例
- 5. 案例说明
- 5.1 在测试案例中,我们首先创建了一个OrderContext对象,并在其上调用pay()方法,此时订单状态从CreatedState转换为PaidState。
- 5.2 接着依次调用了ship()、deliver()和receive()方法,订单状态分别从PaidState转换为ShippedState、ShippedState转换为DeliveredState、DeliveredState转换为ReceivedState。
- 5.3 然后尝试再次调用receive()、ship()、pay()和deliver()方法,此时订单状态已经处于ReceivedState,不能再进行状态转换了。
- 5.4 最后调用了cancel()方法,此时订单状态由ReceivedState转换为CancelledState。
状态模式定义:
当一个对象内在状态改变时允许其改变行为,这个对象看起来像改变了其类
使用场景
使用场景: 1、行为随状态改变而改变的场景。 2、条件、分支语句的代替者。
角色定义
1. State一抽象状态角色
接口或抽象类,负责对象状态定义,并且封装环境角色以实现状态切换
2. ConcreteState一-具体状态角色
每一个具体状态必须完成两个职责: 本状态的行为管理以及趋向状态处理,通俗地说,就是本状态下要做的事情,以及本状态如何过渡到其他状态。
3. Context–环境角色
定义客户端需要的接口,并且负责具体状态的切换
需求背景
针对用户购买的商品完成订单不同状态之间的流(未支付、已支付、已发货、已签收、已确认等)。
下面是一个简单的Java示例代码:
1. 订单状态抽象类
// 订单状态抽象类
abstract class OrderState {
protected OrderContext context;
public void setContext(OrderContext context) {
this.context = context;
}
public abstract void pay();
public abstract void cancel();
public abstract void ship();
public abstract void deliver();
public abstract void receive();
}
2. 定义订单具体状态类并集成基类(抽象类)
2.1 订单创建状态
// 订单创建状态
class CreatedState extends OrderState {
@Override
public void pay() {
System.out.println("订单已支付");
context.setState(new PaidState());
}
@Override
public void cancel() {
System.out.println("订单已取消");
context.setState(new CancelledState());
}
@Override
public void ship() {
System.out.println("订单尚未支付,不能发货");
}
@Override
public void deliver() {
System.out.println("订单尚未支付,不能发货");
}
@Override
public void receive() {
System.out.println("订单尚未支付,不能确认收货");
}
}
2.2 订单已支付状态
// 订单已支付状态
class PaidState extends OrderState {
@Override
public void pay() {
System.out.println("订单已支付,无需再次支付");
}
@Override
public void cancel() {
System.out.println("订单已取消");
context.setState(new CancelledState());
}
@Override
public void ship() {
System.out.println("订单已发货");
context.setState(new ShippedState());
}
@Override
public void deliver() {
System.out.println("订单尚未发货,不能确认收货");
}
@Override
public void receive() {
System.out.println("订单尚未发货,不能确认收货");
}
}
2.3 订单已发货状态
// 订单已发货状态
class ShippedState extends OrderState {
@Override
public void pay() {
System.out.println("订单已支付,无需再次支付");
}
@Override
public void cancel() {
System.out.println("订单已发货,不能取消");
}
@Override
public void ship() {
System.out.println("订单已发货,无需再次发货");
}
@Override
public void deliver() {
System.out.println("订单已签收");
context.setState(new DeliveredState());
}
@Override
public void receive() {
System.out.println("订单尚未签收,不能确认收货");
}
}
2.4 订单已签收状态
// 订单已签收状态
class DeliveredState extends OrderState {
@Override
public void pay() {
System.out.println("订单已支付,无需再次支付");
}
@Override
public void cancel() {
System.out.println("订单已签收,不能取消");
}
@Override
public void ship() {
System.out.println("订单已签收,不能再次发货");
}
@Override
public void deliver() {
System.out.println("订单已签收,不能再次确认收货");
}
@Override
public void receive() {
System.out.println("订单已确认收货");
context.setState(new ReceivedState());
}
}
2.5 订单已确认收货状态
// 订单已确认收货状态
class ReceivedState extends OrderState {
@Override
public void pay() {
System.out.println("订单已支付,无需再次支付");
}
@Override
public void cancel() {
System.out.println("订单已确认收货,不能取消");
}
@Override
public void ship() {
System.out.println("订单已确认收货,不能再次发货");
}
@Override
public void deliver() {
System.out.println("订单已确认收货,不能再次确认收货");
}
@Override
public void receive() {
System.out.println("订单已确认收货,无需再次确认");
}
}
2.6 订单已取消状态
//订单已取消
public class CancelledState extends OrderState {
@Override
public void pay() {
System.out.println("订单已取消");
}
@Override
public void cancel() {
System.out.println("订单已取消");
}
@Override
public void ship() {
System.out.println("订单已取消");
}
@Override
public void deliver() {
System.out.println("订单已取消");
}
@Override
public void receive() {
System.out.println("订单已取消");
}
}
3. 订单上下文类
// 订单上下文类
class OrderContext {
private OrderState state;
public OrderContext() {
setState(new CreatedState());
}
public void setState(OrderState state) {
this.state = state;
this.state.setContext(this);
}
public void pay() {
state.pay();
}
public void cancel() {
state.cancel();
}
public void ship() {
state.ship();
}
public void deliver() {
state.deliver();
}
public void receive() {
state.receive();
}
}
4. 测试案例
// 测试案例
public class StateTest {
public static void main(String[] args) {
OrderContext order = new OrderContext();
order.pay(); // 订单已支付
order.ship(); // 订单已发货
order.deliver(); // 订单已签收
order.receive(); // 订单已确认收货
order.receive(); // 订单已确认收货,无需再次确认
order.ship(); // 订单已确认收货,不能再次发货
order.pay(); // 订单已确认收货,无需再次支付
order.deliver(); // 订单已确认收货,不能再次确认收货
order.cancel(); // 订单已确认收货,不能取消
}
}