当前位置: 首页 > article >正文

22 行为型模式-状态模式

1 状态模式介绍

在这里插入图片描述

2 状态模式结构

在这里插入图片描述
在这里插入图片描述

3 状态模式实现

代码示例

//抽象状态接口
public interface State {
	//声明抽象方法,不同具体状态类可以有不同实现
	void handle(Context context);
}
/**
 * 上下文类
 **/
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 +
                '}';
    }
}
public class ConcreteStateA implements State {

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

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

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

    @Override
    public String toString() {
        return "当前状态: ConcreteStateB";
    }
}
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. 不使用设计模式
/**
 * 交通灯类有三种状态
 *     红灯(禁行) ,黄灯(警示),绿灯(同行)
 **/
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) 使用状态模式,将交通灯的切换逻辑组织起来,把跟状态有关的内容从交通灯类
里抽离出来,使用类来表示不同的状态.

/**
 * 交通灯类
 **/
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);
    }

}
/**
 * 交通灯状态接口
 **/
public interface State {

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

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

    void switchToRed(TrafficLight trafficLight);  //切换为红灯
}
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("当前为红灯,无需切换!");
    }
}
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("绿灯不能够切换为红灯!");
    }
}
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秒!");
    }
}
public class Client {

    public static void main(String[] args) {

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

通过代码重构,将"状态" 接口化、模块化,最终将它们从臃肿的交通类中抽了出来,
消除了原来TrafficLight类中的if…else,代码看起来干净而优雅.

5 状态模式总结

在这里插入图片描述


http://www.kler.cn/news/107033.html

相关文章:

  • python:使用Scikit-image对遥感影像进行形态学轮廓特征提取(contour)
  • kafka入门03——简单实战
  • 负载均衡策略 LVS
  • 云服务器的先驱,亚马逊云科技海外云服务器领军者
  • 【Java题】输出基本数据类型的最大值和最小值,以及float和double的正无穷大值和负无穷大值
  • NodeJS爬取墨刀上的设计图片
  • 【密评】商用密码应用安全性评估从业人员考核题库(十五)
  • 视频剪辑高手必学:批量制作画中画效果的秘诀
  • arduino抢答器
  • 【java】建筑施工一体化智慧工地信息管理系统源码
  • AutoCAD 2024 Mac中文附激活补丁 兼容M1.M2电脑
  • 竞赛选题 深度学习卷积神经网络垃圾分类系统 - 深度学习 神经网络 图像识别 垃圾分类 算法 小程序
  • 大厂面试题-JVM中的三色标记法是什么?
  • JVM 参数
  • 分治算法解决归并排序问题
  • 【ROS入门】雷达、摄像头及kinect信息仿真以及显示
  • 前端的基本介绍
  • 5.MySQL基本查询
  • 智慧垃圾站:AI视频智能识别技术助力智慧环保项目,以“智”替人强监管
  • MongoDB 的集群架构与设计
  • Angular-03:组件模板
  • 如何在 uniapp 里面使用 pinia 数据持久化 (pinia-plugin-persistedstate)
  • 关于路由转发
  • Mysql binlog日志功能使用,简单易懂
  • centos更改yum源
  • 2023大湾区杯粤港澳金融数学建模竞赛思路+模型+代码
  • 直方图均衡化算法
  • 最长公共子序列(LCS)与最长上升子序列(LIS)问题的相互转换
  • uni-app集成uni-simple-router,报错:Uncaught ReferenceError: ROUTES is not defined
  • element-plus form表单的二次封装