一.状态模式介绍与使用场景
状态模式是一种行为设计模式,它允许对象在内部状态发生改变时改变其行为。该模式将对象的行为包装在不同的状态类中,使得对象的行为可以根据其当前状态动态改变。
状态模式通常由以下几个角色组成:
环境类(Context):环境类是拥有状态的对象,它将会根据当前状态来执行相应的行为。它维护了一个对抽象状态类的引用,用于切换和委托不同的状态处理。
抽象状态类(State):抽象状态类定义了一个接口,用于具体状态类的实现。在该接口中声明了具体状态类需要实现的方法。具体状态类(Concrete State):具体状态类实现了抽象状态类的接口,并负责定义该状态下的具体行为。它包含了对环境类的引用,可以根据需要切换环境类的状态。
状态模式适用场景:
当一个对象的行为取决于其内部状态,并且需要在运行时根据状态改变行为时,状态模式非常有用。它允许对象在不同状态下执行不同的操作,而不需要使用复杂的条件判断语句。
当对象具有大量的状态以及与每个状态相关的行为时,状态模式可以提供一种结构化的方式来管理和组织这些状态和行为。每个状态都可以表示为一个独立的状态类,使得代码更加清晰、可读性更高。
当需要向对象的状态变化进行动态扩展时,状态模式提供了一种灵活的解决方案。通过添加新的状态类,并相应地调整环境类与状态类之间的关联,可以轻松地增加新的状态和行为。
当多个对象需要共享同一组状态时,状态模式可以减少重复代码的编写。通过将状态封装在独立的状态类中,多个对象可以共享相同的状态实例,从而节省内存和代码维护成本。
总结起来,状态模式适用于以下情况:
- 对象的行为取决于其内部状态,并且需要在运行时根据状态改变行为。
- 对象具有多个状态以及与每个状态相关的行为。
- 需要动态扩展对象的状态和行为。
- 多个对象需要共享同一组状态。
通过使用状态模式,可以将复杂的条件判断逻辑转化为一组独立的状态类,提高代码的可读性、可维护性和可扩展性。同时,状态模式也能够帮助我们将对象的状态与行为进行解耦,使得代码更加灵活和可复用。
二.状态模式实现
下面用一个简单的demo描述一下状态模式:
// 环境类 - 订单 class Order { private OrderState state; public Order() { state = new NewState(); } public void setState(OrderState state) { this.state = state; } public void process() { state.processOrder(this); } } // 抽象状态类 interface OrderState { void processOrder(Order order); } // 具体状态类 - 新订单 class NewState implements OrderState { public void processOrder(Order order) { System.out.println("Processing new order"); // 在新订单状态下的处理逻辑 // ... order.setState(new ShippedState()); // 切换状态 } } // 具体状态类 - 已发货订单 class ShippedState implements OrderState { public void processOrder(Order order) { System.out.println("Processing shipped order"); // 在已发货订单状态下的处理逻辑 // ... order.setState(new DeliveredState()); // 切换状态 } } // 具体状态类 - 已交付订单 class DeliveredState implements OrderState { public void processOrder(Order order) { System.out.println("Processing delivered order"); // 在已交付订单状态下的处理逻辑 // ... } } // 使用示例 public class Main { public static void main(String[] args) { Order order = new Order(); order.process(); // 处理新订单 order.process(); // 处理已发货订单 order.process(); // 处理已交付订单 } }
我们模拟了一个订单的状态变化过程。订单类 Order 是拥有状态的对象,它将根据当前状态来执行相应的行为。
抽象状态类 OrderState 定义了一个接口 processOrder(),具体状态类 NewState、ShippedState 和 DeliveredState 实现了该接口,并分别负责定义相应状态下的具体行为。
在 Main 类的 main 方法中,我们创建了一个订单对象,并连续调用了 process() 方法来处理订单。初始状态为新订单状态,调用 process() 方法后会切换到已发货订单状态,再次调用 process() 方法后会切换到已交付订单状态。
通过使用状态模式,订单对象能够根据不同的状态来改变其行为,避免了大量的条件判断语句,并使得代码更加可扩展和易维护。
以上只是一个简单的实现demo,实际开发中,还有很多场景适用于状态模式,例如电商订单的状态流转,下面我们写一个实现电商订单状态流转的状态模式例子:
// 环境类 - 订单 class Order { private OrderState state; public Order() { state = new NewState(); } public void setState(OrderState state) { this.state = state; } public void process() { state.processOrder(this); } public void cancel() { state.cancelOrder(this); } } // 抽象状态类 interface OrderState { void processOrder(Order order); void cancelOrder(Order order); } // 具体状态类 - 新订单 class NewState implements OrderState { public void processOrder(Order order) { System.out.println("Processing new order"); // 在新订单状态下的处理逻辑 // ... order.setState(new ShippedState()); // 切换状态 } public void cancelOrder(Order order) { System.out.println("Cancelling new order"); // 在新订单状态下的取消逻辑 // ... order.setState(new CancelledState()); // 切换状态 } } // 具体状态类 - 已发货订单 class ShippedState implements OrderState { public void processOrder(Order order) { System.out.println("Processing shipped order"); // 在已发货订单状态下的处理逻辑 // ... order.setState(new DeliveredState()); // 切换状态 } public void cancelOrder(Order order) { System.out.println("Cancelling shipped order"); // 在已发货订单状态下的取消逻辑 // ... order.setState(new CancelledState()); // 切换状态 } } // 具体状态类 - 已交付订单 class DeliveredState implements OrderState { public void processOrder(Order order) { System.out.println("Processing delivered order"); // 在已交付订单状态下的处理逻辑 // ... } public void cancelOrder(Order order) { System.out.println("Cancelling delivered order"); // 在已交付订单状态下的取消逻辑 // ... order.setState(new CancelledState()); // 切换状态 } } // 具体状态类 - 取消订单 class CancelledState implements OrderState { public void processOrder(Order order) { System.out.println("Cannot process cancelled order"); // 取消订单状态下不执行任何处理逻辑 } public void cancelOrder(Order order) { System.out.println("Cannot cancel already cancelled order"); // 取消订单状态下不执行任何取消逻辑 } } // 使用示例 public class Main { public static void main(String[] args) { Order order = new Order(); order.process(); // 处理新订单 order.process(); // 处理已发货订单 order.cancel(); // 取消已发货订单 order.process(); // 处理已交付订单 } }
上述示例中,我们模拟了一个电商系统中的订单状态变化过程。订单类 Order 是拥有状态的对象,它根据当前状态来执行相应的操作。
抽象状态类 OrderState 定义了两个方法 processOrder() 和 cancelOrder(),具体状态类 NewState、ShippedState、DeliveredState 和 CancelledState 实现了该接口,并分别负责定义相应状态下的具体行为。
在 Main 类的 main 方法中,我们创建了一个订单对象,并通过连续调用 process() 方法和 cancel() 方法来模拟订单状态的变化。初始状态为新订单状态,调用 process() 方法后会切换到已发货订单状态,再次调用 cancel() 方法后会切换到取消订单状态,最后再次调用 process() 方法会输出无法处理已取消订单的提示信息。
通过使用状态模式,订单对象能够根据不同的状态来改变其行为,避免了大量的条件判断语句,并使得代码更加可扩展和易维护。状态模式也能够帮助我们将对象的状态与行为进行解耦,使得代码更加灵活和可复用。