22 行为型模式-状态模式

1 状态模式介绍
2 状态模式结构


3 状态模式实现

代码示例

java 复制代码
//抽象状态接口
public interface State {
	//声明抽象方法,不同具体状态类可以有不同实现
	void handle(Context context);
}
java 复制代码
/**
 * 上下文类
 **/
public class Context {

    //维持一个对状态对象的有引用
    private State currentState;

    public Context() {
        this.currentState = null;
    }

    public Context(State currentState) {
        this.currentState = currentState;
    }

    public State getCurrentState() {
        return currentState;
    }

    public void setCurrentState(State currentState) {
        this.currentState = currentState;
    }

    @Override
    public String toString() {
        return "Context{" +
                "currentState=" + currentState +
                '}';
    }
}
java 复制代码
public class ConcreteStateA implements State {

    @Override
    public void handle(Context context) {
        System.out.println("进入到状态模式A......");
        context.setCurrentState(this);
    }

    @Override
    public String toString() {
        return "当前状态: ConcreteStateA";
    }
}
java 复制代码
public class ConcreteStateB implements State {

    @Override
    public void handle(Context context) {
        System.out.println("进入到状态模式B......");
        context.setCurrentState(this);
    }

    @Override
    public String toString() {
        return "当前状态: ConcreteStateB";
    }
}
java 复制代码
public class Client {

    public static void main(String[] args) {

        Context context = new Context();

        State state1 = new ConcreteStateA();
        state1.handle(context);
        System.out.println(context.getCurrentState().toString());

        System.out.println("=================================");
        State state2 = new ConcreteStateB();
        state2.handle(context);
        System.out.println(context.getCurrentState().toString());
    }
}
4 状态模式应用实例
  1. 不使用设计模式
java 复制代码
/**
 * 交通灯类有三种状态
 *     红灯(禁行) ,黄灯(警示),绿灯(同行)
 **/
public class TrafficLight {

    //初始化状态
    private String state = "红色";

    //切换为绿灯,通行状态
    public void switchToGreen(){
        if("绿".equals(state)){ //当前是绿灯
            System.out.println("当前为绿灯,无需切换!");
        }else if("红".equals(state)){
            System.out.println("红灯不能切换为绿灯");
        }else if("黄".equals(state)){
            state = "绿";
            System.out.println("绿灯亮起...时长: 60秒");
        }
    }

    //切换为黄灯,警示状态
    public void switchToYellow() {
        if ("黄".equals(state)) { //当前是黄灯
            System.out.println("当前为黄灯,无需切换!");
        } else if ("红".equals(state) || "绿".equals(state)) {
            System.out.println("红灯不能切换为绿灯");
            state = "黄";
            System.out.println("黄灯亮起...时长:10秒");
        }
    }

    //切换为红灯,禁止状态
    public void switchToRed(){
        if("红".equals(state)){ //当前是红灯
            System.out.println("当前为红灯,无需切换!");
        }else if("绿".equals(state)){
            System.out.println("绿灯不能切换为红灯");
        }else if("黄".equals(state)){
            state = "红";
            System.out.println("红灯亮起...时长: 90秒");
        }
    }
}

问题: 状态切换的操作全部在一个类中,如果有很多的交通灯进行联动,这个程序

的逻辑就会变得非常复杂,难以维护.

2) 使用状态模式,将交通灯的切换逻辑组织起来,把跟状态有关的内容从交通灯类
里抽离出来,使用类来表示不同的状态.

java 复制代码
/**
 * 交通灯类
 **/
public class TrafficLight {

    //初始化-红灯
    State state =  new RedState();

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

    //切换为绿灯,通行状态
    public void switchToGreen(){
        state.switchToGreen(this);
    }

    //切换为黄灯,警示状态
    public void switchToYellow() {
        state.switchToYellow(this);
    }

    //切换为红灯,禁止状态
    public void switchToRed(){
        state.switchToRed(this);
    }

}
java 复制代码
/**
 * 交通灯状态接口
 **/
public interface State {

    void switchToGreen(TrafficLight trafficLight);  //切换为绿灯

    void switchToYellow(TrafficLight trafficLight);  //切换为黄灯

    void switchToRed(TrafficLight trafficLight);  //切换为红灯
}
java 复制代码
public class RedState implements State {

    @Override
    public void switchToGreen(TrafficLight trafficLight) {
        System.out.println("红灯不能切换为绿灯!");
    }

    @Override
    public void switchToYellow(TrafficLight trafficLight) {
        System.out.println("黄灯亮起...时长: 10秒");
    }

    @Override
    public void switchToRed(TrafficLight trafficLight) {
        System.out.println("当前为红灯,无需切换!");
    }
}
java 复制代码
public class GreenState implements State {

    @Override
    public void switchToGreen(TrafficLight trafficLight) {
        System.out.println("当前是绿灯,无需切换!");
    }

    @Override
    public void switchToYellow(TrafficLight trafficLight) {
        System.out.println("黄灯亮起...时长: 10秒");
    }

    @Override
    public void switchToRed(TrafficLight trafficLight) {
        System.out.println("绿灯不能够切换为红灯!");
    }
}
java 复制代码
public class YellowState implements State {

    @Override
    public void switchToGreen(TrafficLight trafficLight) {
        System.out.println("绿灯亮起...时长:60秒!");
    }

    @Override
    public void switchToYellow(TrafficLight trafficLight) {
        System.out.println("当前是黄灯,无需切换!");
    }

    @Override
    public void switchToRed(TrafficLight trafficLight) {
        System.out.println("红灯亮起...时长:90秒!");
    }
}
java 复制代码
public class Client {

    public static void main(String[] args) {

        TrafficLight trafficLight = new TrafficLight();
        trafficLight.switchToRed();
        trafficLight.switchToGreen();
        trafficLight.switchToYellow();
    }
}

通过代码重构,将"状态" 接口化、模块化,最终将它们从臃肿的交通类中抽了出来,

消除了原来TrafficLight类中的if...else,代码看起来干净而优雅.

5 状态模式总结
相关推荐
傻乐u兔3 小时前
C语言进阶————指针4
c语言·开发语言
大模型玩家七七3 小时前
基于语义切分 vs 基于结构切分的实际差异
java·开发语言·数据库·安全·batch
历程里程碑3 小时前
Linux22 文件系统
linux·运维·c语言·开发语言·数据结构·c++·算法
牛奔4 小时前
Go 如何避免频繁抢占?
开发语言·后端·golang
寻星探路8 小时前
【深度长文】万字攻克网络原理:从 HTTP 报文解构到 HTTPS 终极加密逻辑
java·开发语言·网络·python·http·ai·https
lly2024069 小时前
Bootstrap 警告框
开发语言
2601_9491465310 小时前
C语言语音通知接口接入教程:如何使用C语言直接调用语音预警API
c语言·开发语言
曹牧10 小时前
Spring Boot:如何测试Java Controller中的POST请求?
java·开发语言
KYGALYX10 小时前
服务异步通信
开发语言·后端·微服务·ruby