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 状态模式总结
相关推荐
万粉变现经纪人37 分钟前
如何解决 pip install -r requirements.txt 私有索引未设为 trusted-host 导致拒绝 问题
开发语言·python·scrapy·flask·beautifulsoup·pandas·pip
qq_4798754342 分钟前
C++ std::Set<std::pair>
开发语言·c++
毕业设计制作和分享43 分钟前
springboot150基于springboot的贸易行业crm系统
java·vue.js·spring boot·后端·毕业设计·mybatis
云知谷3 小时前
【C++基本功】C++适合做什么,哪些领域适合哪些领域不适合?
c语言·开发语言·c++·人工智能·团队开发
l1t4 小时前
DeepSeek辅助利用搬移底层xml实现快速编辑xlsx文件的python程序
xml·开发语言·python·xlsx
C_Liu_6 小时前
C++:list
开发语言·c++
my rainy days6 小时前
C++:友元
开发语言·c++·算法
小梁努力敲代码6 小时前
java数据结构--List的介绍
java·开发语言·数据结构
摸鱼的老谭6 小时前
构建Agent该选Python还是Java ?
java·python·agent
云知谷6 小时前
【HTML】网络数据是如何渲染成HTML网页页面显示的
开发语言·网络·计算机网络·html