真实项目案例实战——【状态设计模式】使用场景

2023-11-03

写在前面:设计模式源于生活,而又高于生活!

什么是状态模式

状态模式允许一个对象在其内部状态改变的时候改变其行为。这个对象看上去就像是改变了它的类一样。

状态模式应用场景

1.一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为。

2.操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。这个状态通常用一个或多个枚举常量表示。 通常,有多个操作包含这一相同的条件结构。State模式将每一个条件分支放入一个独立的类中。这使得你可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化。

状态模式实现

需要重构的代码
public class OrderService {


    public String orderState(String state) {
        if (state.equals("0")) {
            return "已经发货";
        }
        if (state.equals("1")) {
            return "正在运送中...";
        }
        if (state.equals("2")) {
            return "正在派送中...";
        }
        if (state.equals("3")) {
            return "已经签收";
        }
        if (state.equals("4")) {
            return "拒绝签收";
        }
        if (state.equals("5")) {
            return "订单交易失败";
        }
        return "未找到对应的状态";
    }
}

状态模式与策略模式区别

策略模式结构图:

7a1adfe2c18f86d7f8cbbfd303c0cdd64ae.jpg

状态模式结构图

ccb928f3d0160ac85810e43fe2fa0cd45c9.jpg

1、状态模式重点在各状态之间的切换从而做不同的事情,而策略模式更侧重于根据具体情况选择策略,并不涉及切换。

2、状态模式不同状态下做的事情不同,而策略模式做的都是同一件事,例如聚合支付平台,有支付宝、微信支付、银联支付,虽然策略不同,但最终做的事情都是支付,也就是说他们之间是可替换的。反观状态模式,各个状态的同一方法做的是不同的事,不能互相替换。

状态模式封装了对象的状态,而策略模式封装算法或策略。因为状态是跟对象密切相关的,它不能被重用;而通过从Context中分离出策略或算法,我们可以重用它们。

在状态模式中,每个状态通过持有Context的引用,来实现状态转移;但是每个策略都不持有Context的引用,它们只是被Context使用。

状态模式实现

OrderState 定义统一抽象接口

public interface OrderState {

    /**
     * 返回都会不一样
     *
     * @return
     */
    public Object orderService();

}

OrderState 实现类:AlreadySignedOrderState 

@Slf4j
@Component
public class AlreadySignedOrderState implements OrderState {
    @Override
    public Object orderService() {
        log.info(">> 切换已经签收状态");
        return "切换已经签收状态";
    }
}

OrderState 实现类:InTransitOrderState 

@Slf4j
@Component
public class InTransitOrderState implements OrderState {
    @Override
    public String orderService() {
        log.info(">>>切换为正在运送状态...");
        return "success";
    }
}

OrderState 实现类:ShippedAlreadyOrderState 

@Slf4j
@Component
public class ShippedAlreadyOrderState implements OrderState {
    public String orderService() {
        log.info(">>>切换为已经发货状态..");
        return "已经发货..";
    }
}

Context上下文:StateContext 

public class StateContext {
    private OrderState orderState;

    public StateContext(OrderState orderState) {
        this.orderState = orderState;
    }

    public void switchStateOrder() {
        orderState.orderService();
    }
}

OrderController 

@RestController
public class OrderController {

    @RequestMapping("/order")
    public String order(String stateBeanId) {

        //1.使用Spring上下文获取bean中对象
        OrderState orderState = SpringUtils.getBean(stateBeanId, OrderState.class);
        // 2.使用上下文切换到不同的状态
        StateContext stateContext = new StateContext(orderState);
        stateContext.switchStateOrder();

        // 如果写多重if判断的话 整个代码流程 耗时比较长   直接Spring中精准定位到策略或者是状态的话 Map get方法的时候底层是数组
        return "success";
    }
}

SpringUtils 

@Component
public class SpringUtils implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    //获取applicationContext
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    //通过name获取 Bean.
    public static Object getBean(String name){
        return getApplicationContext().getBean(name);
    }

    //通过class获取Bean.
    public static <T> T getBean(Class<T> clazz){
        return getApplicationContext().getBean(clazz);
    }

    //通过name,以及Clazz返回指定的Bean
    public static <T> T getBean(String name,Class<T> clazz){
        return getApplicationContext().getBean(name, clazz);
    }

}

pom依赖

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
    </parent>
    <dependencies>
        <!-- sprinboot web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.10</version>
        </dependency>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>
    </dependencies>

启动类

@SpringBootApplication
public class AppOrderState {
    public static void main(String[] args) {
        SpringApplication.run(AppOrderState.class);
    }
}

测试结果

访问:http://127.0.0.1:8080/order?stateBeanId=alreadySignedOrderState

控制台输出:>> 切换已经签收状态

访问:http://127.0.0.1:8080/order?stateBeanId=inTransitOrderState

控制台输出:>>>切换为正在运送状态...

访问:http://127.0.0.1:8080/order?stateBeanId=shippedAlreadyOrderState

控制台输出:>>>切换为已经发货状态..

版权@须臾之余https://my.oschina.net/u/3995125

本文参考:蚂蚁课堂:http://www.mayikt.com

转载于:https://my.oschina.net/u/3995125/blog/3054183

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

真实项目案例实战——【状态设计模式】使用场景 的相关文章

随机推荐

  • word2vec

    Author kangbingbing Email kangb93 126 com Datawhale word2vec简介 Word2vec是Google实现word embedding的一种具体的方式 因为速度快效果好 而广为人知 而W
  • 一些好用的vscode插件

    一直用的sublime text 喜欢它的轻巧 不过最近试了下vscode 发现还是蛮中意的 插件生态丰富而且配置挺人性化 另外一些shortcuts功能确实提高编辑效率 缺点是如果安装太多插件 内存会飙高些 这里记下目前用的一些觉得不错的
  • 何为智能指针以及QT中的智能指针

    目的 对于指针的使用中有两个导致软件崩溃的问题 一是忘记释放动态申请的内存 二是指针指向的内存被释放 为了解决这个问题 出现了智能指针 效果 智能指针其实是一个类 在这个类的构造函数和析构函数实现以下功能 当有一个指针指向对象A时 计数器加
  • printf、sprintf、fprintf的区别

    printf sprintf fprintf的区别 int printf const char format int fprtintf FILE stream const char format int sprintf char str c
  • chromecast投屏_利用谷歌Chromecast,3个简单的步骤教你将手机投屏到电视上

    无论是在线观看电影 视频通话 展示度假照片还是在电视上玩游戏 把你的安卓 Android 手机的屏幕内容投屏到电视机上都很简单 放过你的家人和朋友们吧 与其让他们挤在你的Android手机或平板电脑的小屏幕上前浏览照片或观看最新的疫情播报视
  • python文件读写函数总结

    1 python读取csv文件 usr bin python coding UTF 8 df pd read csv filepath usecols func name para value df t df fillna value 对空
  • 线性回归算法及案例

    线性回归 寻找 一种能预测的趋势 回归问题的条件 前提 1 收集的数据 2 假设的模型 即一个函数 这个函数里含有未知的参数 通过学习 可以估计出参数 然后利用这个模型去预测 分类新的数据 案例 from sklearn datasets
  • DRBD分布式存储解决方案实战

    一 DRBD分布式存储解决方案 1 DRBD简介 DRBD的全称为 Distributed Replicated Block Device DRBD 分布式块设备复制 DRBD是由内核模块和相关脚本而构成 用以构建高可用性 HA 的集群 其
  • Cas5.3.2 服务端 自定义登入界面

    第一 项目整体结构 自定义页面涉及资源全部存放再src main resources 文件夹目录下 目录 含义 services 配置自定义登入网站模板 static 静态文件目录 用于存放js css代码的 templates 模板文件目
  • Linux mount 命令

    mount 命令用来挂载文件系统 其基本命令格式为 mount t type o options device dirdevice 指定要挂载的设备 比如磁盘 光驱等 dir 指定把文件系统挂载到哪个目录 type 指定挂载的文件系统类型
  • 使用Python,OpenCV执行视觉显著性检测(Visual Saliency Detection)

    使用Python OpenCV执行视觉显著性检测 Visual Saliency Detection 这篇博客将介绍如何使用Python OpenCV执行显著性检测 这是一个应用图像处理和计算机视觉算法来自动定位图像中最 显著 区域的过程
  • 使用python读取xml文件批量生成ground-truth标注图片

    目标检测中 在对比自己算法的检测效果时 需要和标注的真实值进行对比 在网上找到的大部分功能是一样的 只不过不完全符合画出真实标注的训练图片 import cv2 import numpy as np import xml dom minid
  • ASP.NET中新建Web网站并部署到IIS上(详细图文教程)

    场景 ASP NET中新建MVC项目并连接SqlServer数据库实现增删改查 https blog csdn net BADAO LIUMANG QIZHI article details 107024544 在上面实现了新建简单的MVC
  • String index out of range: 100 报错详解与解决方案

    问题出错情况 字符串截取长度 没有那么长的长度所以截取失败 在这里进行debug之后可以看到 异常在substring中 也就是判断字符串的时候报错 具体原因就是string字符串indexof的值本身只有5 然后在这里去取其第100 个字
  • MFC六大关键技术(4)——永久保存(串行化)

    MFC六大关键技术 第四部分 永久保存 串行化 先用一句话来说明永久保存的重要 弄懂它以后 你就越来越像个程序员了 如果我们的程序不需要永久保存 那几乎可以肯定是一个小玩儿 那怕我们的记事本 画图等小程序 也需要保存才有真正的意义 对于MF
  • Java项目之使用Bootstraptable批量操作

    Java项目之使用Bootstraptable批量操作 开发工具与关键技术 IntelliJ IDEA java 作者 刘剑鸿 撰写时间 2021 5 15 一开始认识一下bootstrap table插件介绍 它是一个基于bootstra
  • solr 服务器 配置文件,Solr的部署模式详解

    前言 本文介绍的Solr版本 solr 7 7 3 部署环境 windows Solr的两种部署模式 Solr程序包安装好后 可以以两种模式来启动solr服务器 Standalone Server 独立服务器模式 适用于数据规模不大的场景
  • 无人机运动场景下移动物体检测和跟踪系统

  • Python+pytest邮件发送测试报告,附件添加测试报告,邮件正文显示测试报告内容

    发送邮件测试报告 这个可以直接复制粘贴代码 都通用 我这个文件里还有其他的代码 导入的包比较多 单说发邮件的话 只导入邮件相关的几个就可以了 coding utf 8 import smtplib import time from emai
  • 真实项目案例实战——【状态设计模式】使用场景

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 写在前面 设计模式源于生活 而又高于生活 什么是状态模式 状态模式允许一个对象在其内部状态改变的时候改变其行为 这个对象看上去就像是改变了它的类一样 状态模式应用场景 1