【设计模式】用Java实现状态模式

一.状态模式介绍与使用场景

状态模式是一种行为设计模式,它允许对象在内部状态发生改变时改变其行为。该模式将对象的行为包装在不同的状态类中,使得对象的行为可以根据其当前状态动态改变。

状态模式通常由以下几个角色组成:

  • 环境类(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(),具体状态类 NewStateShippedState 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(),具体状态类 NewStateShippedStateDeliveredState CancelledState 实现了该接口,并分别负责定义相应状态下的具体行为。

Main 类的 main 方法中,我们创建了一个订单对象,并通过连续调用 process() 方法和 cancel() 方法来模拟订单状态的变化。初始状态为新订单状态,调用 process() 方法后会切换到已发货订单状态,再次调用 cancel() 方法后会切换到取消订单状态,最后再次调用 process() 方法会输出无法处理已取消订单的提示信息。

通过使用状态模式,订单对象能够根据不同的状态来改变其行为,避免了大量的条件判断语句,并使得代码更加可扩展和易维护。状态模式也能够帮助我们将对象的状态与行为进行解耦,使得代码更加灵活和可复用。

你可能感兴趣的:(设计模式,设计模式,java,状态模式)