【Java 设计模式】行为型之状态模式

文章目录

    • 1. 定义
    • 2. 应用场景
    • 3. 代码实现
    • 结语

状态模式(State Pattern)是一种行为型设计模式,用于通过将对象的行为封装到不同的状态类中,使得对象在不同的状态下具有不同的行为。状态模式允许对象在内部状态发生改变时改变其行为,而无需修改其代码。在本文中,我们将深入研究Java中状态模式的定义、结构、使用场景以及如何在实际开发中应用。

1. 定义

状态模式是一种行为型设计模式,用于通过将对象的行为封装到不同的状态类中,使得对象在不同的状态下具有不同的行为。状态模式允许对象在内部状态发生改变时改变其行为,而无需修改其代码。状态模式通常包含三个主要角色:上下文(Context)、抽象状态(Abstract State)和具体状态(Concrete State)。

  • 上下文(Context): 定义了一个接口,用于维护一个当前状态的引用,并提供一个用于切换状态的方法
  • 抽象状态(Abstract State): 定义了一个接口,用于封装与上下文相关的一个或多个行为
  • 具体状态(Concrete State): 实现了抽象状态的接口,负责处理与状态相关的行为

2. 应用场景

状态模式通常在以下场景中使用:

  • 一个对象的行为取决于其内部状态,并且需要在运行时根据内部状态改变其行为:

    当一个对象的行为取决于其内部状态,并且需要在运行时根据内部状态改变其行为时,可以使用状态模式

  • 一个对象具有多个状态,并且状态之间存在转换关系:

    当一个对象具有多个状态,并且这些状态之间存在转换关系时,可以使用状态模式

  • 避免使用过多的条件语句来控制对象的行为:

    当需要避免使用过多的条件语句来控制对象的行为时,可以使用状态模式,将每个状态封装到一个类中,使得代码更加清晰和可维护

3. 代码实现

下面通过一个简单的例子来演示状态模式的实现。假设有一个电梯系统,电梯有开门、关门、上行、下行和停止等状态,我们可以使用状态模式来管理电梯的不同状态。

上下文 - 电梯 ElevatorContext

package com.cheney.demo;

class ElevatorContext {
    private ElevatorState currentState;

    public ElevatorContext() {
        this.currentState = new StoppedState();
    }

    public void setState(ElevatorState state) {
        this.currentState = state;
    }

    public void openDoor() {
        currentState.openDoor(this);
    }

    public void closeDoor() {
        currentState.closeDoor(this);
    }

    public void moveUp() {
        currentState.moveUp(this);
    }

    public void moveDown() {
        currentState.moveDown(this);
    }
}

抽象状态 - 电梯状态 ElevatorState

package com.cheney.demo;

interface ElevatorState {
    void openDoor(ElevatorContext context);

    void closeDoor(ElevatorContext context);

    void moveUp(ElevatorContext context);

    void moveDown(ElevatorContext context);
}

具体状态 - 停止状态 StoppedState

package com.cheney.demo;

class StoppedState implements ElevatorState {
    @Override
    public void openDoor(ElevatorContext context) {
        System.out.println("开门");
        context.setState(new OpenedState());
    }

    @Override
    public void closeDoor(ElevatorContext context) {
        System.out.println("门已经关上了");
    }

    @Override
    public void moveUp(ElevatorContext context) {
        System.out.println("向上移动");
        context.setState(new MovingUpState());
    }

    @Override
    public void moveDown(ElevatorContext context) {
        System.out.println("向下移动");
        context.setState(new MovingDownState());
    }
}

具体状态 - 开门状态 OpenedState

package com.cheney.demo;

class OpenedState implements ElevatorState {
    @Override
    public void openDoor(ElevatorContext context) {
        System.out.println("门已经打开了");
    }

    @Override
    public void closeDoor(ElevatorContext context) {
        System.out.println("关上门");
        context.setState(new StoppedState());
    }

    @Override
    public void moveUp(ElevatorContext context) {
        System.out.println("门打开时无法向上移动");
    }

    @Override
    public void moveDown(ElevatorContext context) {
        System.out.println("门打开时无法向下移动");
    }
}

具体状态 - 上行状态 MovingUpState

package com.cheney.demo;

class MovingUpState implements ElevatorState {
    @Override
    public void openDoor(ElevatorContext context) {
        System.out.println("向上移动时无法打开门");
    }

    @Override
    public void closeDoor(ElevatorContext context) {
        System.out.println("关上门");
        context.setState(new StoppedState());
    }

    @Override
    public void moveUp(ElevatorContext context) {
        System.out.println("继续向上移动");
    }

    @Override
    public void moveDown(ElevatorContext context) {
        System.out.println("改变方向向下移动");
        context.setState(new MovingDownState());
    }
}

具体状态 - 下行状态 MovingDownState

package com.cheney.demo;

class MovingDownState implements ElevatorState {
    @Override
    public void openDoor(ElevatorContext context) {
        System.out.println("向下移动时无法打开门");
    }

    @Override
    public void closeDoor(ElevatorContext context) {
        System.out.println("关上门");
        context.setState(new StoppedState());
    }

    @Override
    public void moveUp(ElevatorContext context) {
        System.out.println("改变方向向上移动");
        context.setState(new MovingUpState());
    }

    @Override
    public void moveDown(ElevatorContext context) {
        System.out.println("继续向下移动。");
    }
}

客户端启动类 Main

package com.cheney.demo;

public class Main {
    public static void main(String[] args) {
        // 使用状态模式管理电梯状态
        ElevatorContext elevator = new ElevatorContext();

        // 打开门
        elevator.openDoor();
        // 关上门
        elevator.closeDoor();
        // 向上移动
        elevator.moveUp();
        // 改变方向向下移动
        elevator.moveDown();
        // 向下移动时无法打开门
        elevator.openDoor();
    }
}

在上述例子中,ElevatorContext 是上下文类,维护了当前状态的引用,并提供了用于切换状态的方法。ElevatorState 是抽象状态接口,定义了与电梯状态相关的行为。StoppedStateOpenedStateMovingUpStateMovingDownState 是具体状态类,分别实现了抽象状态接口,负责处理不同状态下的行为。

在客户端中,我们使用状态模式管理电梯的状态。通过将电梯的不同状态封装到不同的状态类中,实现了电梯状态的切换,而无需修改 ElevatorContext 的代码。

结语

状态模式是一种用于通过将对象的行为封装到不同的状态类中,使得对象在不同的状态下具有不同的行为的设计模式。通过使用状态模式,可以使代码更加清晰、可维护,并降低对象之间的耦合度。在实际开发中,状态模式常被用于处理对象的状态转换、状态机等场景。通过合理使用状态模式,可以提高系统的可扩展性和灵活性。

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