设计模式-状态模式

1、概述

状态模式是一种行为设计模式,它允许对象在其内部状态改变时改变其行为。这种模式主要用于实现对象之间的解耦,使得对象可以在不修改其结构的情况下改变其行为。

角色:

上下文(Context):负责维护当前状态和根据当前状态调用相应的状态处理方法。
状态(State):表示对象的状态,每个状态都有一个对应的处理方法。
具体状态(Concrete State):是状态的具体实现,继承自状态接口。

2、优缺点

优点:
1、封装了转换规则。
2、枚举可能的状态,在枚举状态之前需要确定状态种类。
3、将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为。
4、允许状态转换逻辑与状态对象合成一体,而不是某一个巨大的条件语句块。
5、可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数。

缺点:
1、状态模式的使用必然会增加系统类和对象的个数。
2、状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱。
3、状态模式对“开闭原则”的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态;而且修改某个状态类的行为也需修改对应类的源代码。

3、实现方式



// 应用程序
public class Test {
    public static void main(String[] args) {
        Elevator elevator = new Elevator();
        elevator.openDoor();  // 输出:电梯门已打开
        elevator.closeDoor();  // 输出:电梯门已关闭
        elevator.goUp();  // 输出:电梯开始上升
        elevator.closeDoor();  // 输出:电梯正在运行,无需关闭门
        elevator.goDown();  // 输出:电梯继续下降
    }
}


// 状态接口
interface State {
    void openDoor();
    void closeDoor();
    void goUp();
    void goDown();
}

// 停止状态
class StopState implements State {
    private Elevator context;

    public StopState(Elevator elevator) {
        this.context = elevator;
    }

    @Override
    public void openDoor() {
        System.out.println("电梯门已打开");
    }

    @Override
    public void closeDoor() {
        System.out.println("电梯门已关闭");
    }

    @Override
    public void goUp() {
        System.out.println("电梯开始上升");
        // 切换到运行状态
        context.setState(new RunState(context));
    }

    @Override
    public void goDown() {
        System.out.println("电梯开始下降");
        // 切换到运行状态
        context.setState(new RunState(context));
    }
}

// 运行状态
class RunState implements State {
    private Elevator context;

    public RunState(Elevator elevator) {
        this.context = elevator;
    }

    @Override
    public void openDoor() {
        System.out.println("电梯正在运行,无法打开门");
    }

    @Override
    public void closeDoor() {
        System.out.println("电梯正在运行,无需关闭门");
    }

    @Override
    public void goUp() {
        System.out.println("电梯继续上升");
    }

    @Override
    public void goDown() {
        System.out.println("电梯继续下降");
    }
}

// 故障状态
class FaultState implements State {
    private Elevator context;

    public FaultState(Elevator elevator) {
        this.context = elevator;
    }

    @Override
    public void openDoor() {
        System.out.println("电梯故障,无法打开门");
    }

    @Override
    public void closeDoor() {
        System.out.println("电梯故障,无需关闭门");
    }

    @Override
    public void goUp() {
        System.out.println("电梯故障,无法上升");
    }

    @Override
    public void goDown() {
        System.out.println("电梯故障,无法下降");
    }
}

// 电梯类
class Elevator {
    private State state;

    public Elevator() {
        this.state = new StopState(this);
    }

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

    public void openDoor() {
        state.openDoor();
    }

    public void closeDoor() {
        state.closeDoor();
    }

    public void goUp() {
        state.goUp();
    }

    public void goDown() {
        state.goDown();
    }
}

4、应用场景

当一个对象的行为取决于它的状态,并且在运行时需要根据状态改变行为时,可以考虑使用状态模式。
当一个对象有多个状态,并且状态之间存在复杂的转换逻辑时,可以使用状态模式来简化代码和提高可维护性。
当需要避免使用大量的条件语句来控制对象的行为时,状态模式可以提供一种更加优雅的解决方案。

This entry was posted in 应用, 设计模式. Bookmark the permalink.