文章目录
状态模式
介绍
状态模式它允许一个对象在其内部状态改变时改变其行为,使对象看起来似乎修改了其类。状态模式的主要目的是将对象的状态封装成不同的类,并将对象的行为委托给当前状态。
组成
- Context(环境): 维护一个对具体状态的引用,维护一个状态对象,并将与状态相关的操作委托给当前状态对象。
- State(状态): 定义一个接口或抽象类,封装了与Context的一个特定状态相关的行为。
- ConcreteState(具体状态): 实现了State接口,每个具体状态类都提供了在状态改变时处理的具体行为。
结构图
场景
假设我们有一个订单处理系统,订单在不同的状态下可以执行不同的操作,比如创建、支付、发货、完成等
版本1.0
// 不使用状态模式的订单类classOrderWithoutState{privateString state;publicOrderWithoutState(){// 初始状态为创建状态
state ="Created";}publicvoidsetState(String newState){this.state = newState;}publicvoidprocessOrder(){if("Created".equals(state)){System.out.println("Order created, waiting for payment");// 可以执行创建订单后的其他逻辑}elseif("Paid".equals(state)){System.out.println("Payment received, preparing for shipment");// 可以执行支付后的其他逻辑}elseif("Shipped".equals(state)){System.out.println("Order shipped, waiting for confirmation");// 可以执行发货后的其他逻辑}elseif("Completed".equals(state)){System.out.println("Order completed, thank you for your purchase");// 可以执行订单完成后的其他逻辑}}}
// 客户端publicclassWithoutStatePatternExample{publicstaticvoidmain(String[] args){OrderWithoutState order =newOrderWithoutState();// 创建订单
order.processOrder();// 支付订单
order.setState("Paid");
order.processOrder();// 发货
order.setState("Shipped");
order.processOrder();// 完成订单
order.setState("Completed");
order.processOrder();}}
问题
上面的实现中,订单类包含一个表示状态的字符串属性,通过条件语句判断当前订单状态,并执行相应的逻辑。这种实现方式会导致代码中出现大量的条件判断,难以维护,并且不符合开闭原则,当需要添加新的订单状态时,需要修改原有的代码。
使用状态模式版本
// 状态接口interfaceOrderState{voidprocessOrder(OrderContext context);}
// 具体状态1:创建状态classCreatedStateimplementsOrderState{@OverridepublicvoidprocessOrder(OrderContext context){System.out.println("Order created, waiting for payment");// 可以执行创建订单后的其他逻辑}}// 具体状态2:支付状态classPaidStateimplementsOrderState{@OverridepublicvoidprocessOrder(OrderContext context){System.out.println("Payment received, preparing for shipment");// 可以执行支付后的其他逻辑}}// 具体状态3:发货状态classShippedStateimplementsOrderState{@OverridepublicvoidprocessOrder(OrderContext context){System.out.println("Order shipped, waiting for confirmation");// 可以执行发货后的其他逻辑}}// 具体状态4:完成状态classCompletedStateimplementsOrderState{@OverridepublicvoidprocessOrder(OrderContext context){System.out.println("Order completed, thank you for your purchase");// 可以执行订单完成后的其他逻辑}}
// 环境类:订单上下文classOrderContext{privateOrderState currentState;publicOrderContext(){// 初始状态为创建状态
currentState =newCreatedState();}publicvoidsetState(OrderState state){this.currentState = state;}publicvoidprocessOrder(){
currentState.processOrder(this);}}
// 客户端publicclassStatePatternExample{publicstaticvoidmain(String[] args){OrderContext order =newOrderContext();// 创建订单
order.processOrder();// 支付订单
order.setState(newPaidState());
order.processOrder();// 发货
order.setState(newShippedState());
order.processOrder();// 完成订单
order.setState(newCompletedState());
order.processOrder();}}
在这个版本的实现中,我们定义了订单的不同状态,并使用状态模式来处理订单状态的变化。每个具体状态类都实现了 OrderState 接口,提供了处理订单的具体逻辑。OrderContext 类是环境类,维护了当前订单的状态,并通过委托给当前状态对象来执行相应的操作。
总结
优点
- 封装性好: 将每个状态封装到一个类中,使得每个状态的实现对其他状态都是独立的,更容易添加新的状态。
- 可扩展性好: 容易添加新的状态类,符合开闭原则。
- 避免了使用大量的条件语句: 状态模式将不同状态的逻辑分离,避免了使用大量的条件语句来判断当前状态。
版权归原作者 Be reborn 所有, 如有侵权,请联系我们删除。