设计模式学习——状态模式

设计模式|状态机模式(State Machine Pattern) 状态机模式(State Machine Pattern)是一种用于描述对象的行为软件设计模式,属于行为型设计模式。在状态机模式中,对象的行为取决于其内部状态,并且在不同的状态下,对象可能会有不同的行为。 阅读详情



基本介绍

  1. 状态模式(state Pattern):它主要用来解决对象在多种状态转换时,需要对外输出不同的行为的问题。状态和行为是一一对应的,状态之间可以相互转换。
  2. 当一个对象的内在状态发生改变时,允许改变其行为,这个对象看起来像是改变了其类。

原理类图

在这里插入图片描述
对原理类图的说明-即(状态模式的角色及职责)

  1. Context类 为环境角色,用于维护ConcreteState实例,这个实例定义当前状态
  2. State 是抽象状态角色,定义一个接口封装与Context的一个特定接口相关行为
  3. ConcreteState 具体的状态角色,每个子类实现一个与Context的一个状态相关行为

状态模式类图实例

在这里插入图片描述


状态模式代码实例

/**
 * 状态抽象类
 */
public abstract class State {

    // 扣除积分 - 50
    public abstract void deducMoney();

    // 是否抽中奖品
    public abstract boolean raffle();

    // 发放奖品
    public abstract void dispensePrize();
}
/**
 * 不能抽奖状态
 */
public class NoRaffleState extends State {

    //初始化时传入活动引用,扣除积分后改变其状态
    RaffleActivity activity;

    public NoRaffleState(RaffleActivity activity) {
        this.activity = activity;
    }

    // 当前状态可以扣积分,扣除后,将状态设置成可以抽奖状态
    @Override
    public void deducMoney() {
        System.out.println("扣除50积分成功,您可以抽奖了");
        activity.setState(activity.getCanRaffleState());
    }

    //当前状态不能抽奖
    @Override
    public boolean raffle() {
        System.out.println("扣了积分才能抽奖");
        return false;
    }

    //当前状态不能发放奖品
    @Override
    public void dispensePrize() {
        System.out.println("不能发放奖品");
    }
}
/**
 * 可以抽奖的状态
 */
public class CanRaffleState extends State {

    RaffleActivity activity;

    public CanRaffleState(RaffleActivity activity) {
        this.activity = activity;
    }

    //已经扣除积分,不能再扣
    @Override
    public void deducMoney() {
        System.out.println("已经扣除了积分");
    }

    //可以抽奖,抽完奖后根据实际情况设置新的状态
    @Override
    public boolean raffle() {
        System.out.println("正在抽奖,请稍等!");
        Random r = new Random();
        int num = r.nextInt(10);
        // 10%中奖机会
        if (num == 0) {
            //改变活动状态为发放奖品
            activity.setState(activity.getDispenseState());
            return true;
        } else {
            System.out.println("很遗憾没有抽中奖品!");
            //改变状态为不能抽奖
            activity.setState(activity.getNoRafflleState());
            return false;
        }
    }

    //不能发放奖品
    @Override
    public void dispensePrize() {
        System.out.println("没中奖,不能发放奖品");
    }
}
/**
 * 发放奖品的状态
 */
public class DispenseState extends State {

    //初始化时传入活动引用,发放奖品后改变其状态
    RaffleActivity activity;

    public DispenseState(RaffleActivity activity) {
        this.activity = activity;
    }

    @Override
    public void deducMoney() {
        System.out.println("不能扣除积分");
    }

    @Override
    public boolean raffle() {
        System.out.println("不能抽奖");
        return false;
    }

    //发放奖品
    @Override
    public void dispensePrize() {
        if (activity.getCount() > 0) {
            System.out.println("恭喜中奖了");
            //改变状态为不能抽奖
            activity.setState(activity.getNoRafflleState());
        } else {
            System.out.println("很遗憾,奖品发送完了");
            //改变状态为奖品发送完毕,则关闭抽奖
            activity.setState(activity.getDispensOutState());
            System.exit(0);
        }
    }
}
/**
 * 奖品发放完毕状态
 * 说明,当我们activity 改变成DispenseOutState,抽奖活动结束
 */
public class DispenseOutState extends State {

    //初始化时传入活动引用
    RaffleActivity activity;

    public DispenseOutState(RaffleActivity activity) {
        this.activity = activity;
    }

    @Override
    public void deducMoney() {
        System.out.println("奖品发送完了,请下次再参加");
    }

    @Override
    public boolean raffle() {
        System.out.println("奖品发送完了,请下次再参加");
        return false;
    }

    @Override
    public void dispensePrize() {
        System.out.println("奖品发送完了,请下次再参加");
    }
}
/**
 * 抽奖活动
 */
public class RaffleActivity {

    // state 表示活动当前的状态是变化
    State state = null;
    //奖品数量
    int count = 0;

    //四个属性,表示四种状态
    State noRafflleState = new NoRaffleState(this);
    State canRaffleState = new CanRaffleState(this);
    State dispenseState = new DispenseState(this);
    State dispenseOutState = new DispenseOutState(this);

    //构造器
    //1. 初始化当前的状态为不可抽奖的状态
    //2. 初始化奖品的数量
    public RaffleActivity(int count) {
        this.state = getNoRafflleState();
        this.count = count;
    }

    //扣分,调用当前状态的deductMoney
    public void debuctMoney() {
        state.deducMoney();
    }

    //抽奖
    public void raffle() {
        //如果当前的状态是抽奖成功
        if (state.raffle()) {
            //领取奖品
            state.dispensePrize();
        }
    }

    public State getState() {
        return state;
    }

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

    //每领一次奖品,count数量就减1.
    public int getCount() {
        int curCount = count;
        count--;
        return curCount;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public void setNoRafflleState(State noRafflleState) {
        this.noRafflleState = noRafflleState;
    }

    public void setCanRaffleState(State canRaffleState) {
        this.canRaffleState = canRaffleState;
    }

    public void setDispenseState(State dispenseState) {
        this.dispenseState = dispenseState;
    }

    public void setDispenseOutState(State dispenseOutState) {
        this.dispenseOutState = dispenseOutState;
    }

    public State getNoRafflleState() {
        return noRafflleState;
    }

    public State getDispenseState() {
        return dispenseState;
    }

    public State getCanRaffleState() {
        return canRaffleState;
    }

    public State getDispensOutState() {
        return dispenseOutState;
    }
}
public class Client {

    public static void main(String[] args) {
        //创建活动对象,奖品池有5个奖品
        RaffleActivity activity = new RaffleActivity(5);
        for (int i = 0; i < 300; i++) {
            System.out.println("-----第 " + (i + 1) + " 次抽奖------");
            //参加抽奖,第一步扣除积分
            activity.debuctMoney();
            //第二步抽奖
            activity.raffle();
        }
    }
}

状态模式注意事项和细节

  1. 代码有很强的可读性,状态模式将每个状态的行为封装到对应的一个类中
  2. 方便维护,将容易产生问题的if-else语句删除了,如果把每个状态的行为都放到一个类中,每次调用方法时都要判断当前是什么状态,不但会产生很多if-else语句,而且容易出错。
  3. 符合“开闭原则”。容易增删状态
  4. 会产生很多类,每个状态都要一个对应的类,当状态过多时会产生很多类,加大维护难度
  5. 当一个事件或者对象有很多种状态,状态之间会相互转换,对不同的状态要求有不同的行为的时候,可以考虑使用状态模式。
Java架构-状态机如何实现 先来解释什么是“状态”( State )。现实事物是有不同状态的,例如一个自动门,就有 open 和 closed 两种状态。我们通常所说的状态机是有限状态机,也就是被描述的事物的状态的数量是有限个,例如自动门的状态就是两个 open 和 closed。状态机,也就是 State Machine ,不是指一台实际机器,而是指一个数学模型。说白了,一般就是指一张状态转换图。例如,根据自动门的运行规则,我们可以抽象出下面这么一个图。 阅读详情

相关推荐

设计模式学习笔记--状态模式

今天来学习一下设计模式中的状态模式。之前经常听说状态机之类的东东,自己也有用过,但是状态机和状态模式还是有一些区别,今天主要看一下状态模式的定义,例子,应用,最后再分析一下状态模式和我们所说的有限状态机之间到底是什么关系。 一.状态模式的定义 所谓状态,我们经常提到。比如水有几种状态,液态,固态,气态,而且达到一定条件之后,水可以在这三种状态之间相互转化。所谓状态模式,是指当一个对象的

puppet_master的专栏 3583

状态设计模式

状态模式是状态机的一种实现方式即可。状态机又叫有限状态机,它有3个部分组成:状态、事件、动作。其中,事件也称为转移条件。事件触发状态的转移及动作的执行。不过,动作不是必须的,也可能只转移状态,不执行任何动作。状态机的三种实现方式第一种实现方式叫分支逻辑法。利用if-else或者分支逻辑,参照状态转移图,将每一个状态转移原模原样地直译成代码。对于简单的状态机来说,这种实现方式最简单、最直接,是首选。第二种实现方式叫查表法。对于状态很多、状态转移比较复杂的状态机来说,查表法比较合适。

weixin_44399827的博客 5009

Java设计模式之状态模式(State模式)介绍

主要介绍了Java设计模式之状态模式(State模式)介绍,本文讲解了何时使用状态模式、如何使用状态模式等内容,需要的朋友可以参考下

20.状态模式

状态模式 一、状态模式 1.状态模式 1)状态模式(State Pattern):它主要用来解决对象在多种状态转换时,需要对外输出不同的行为的问题。状态和行为是一一对应的,状态之间可以相互转换 2)当一个对象的内在状态改变时,允许改变其行为,这个对象看起来像是改变了其类 2.原理类图 1)Context 类为环境角色,用于维护State实例,这个实例定义当前状态 2)State是抽象状...

weixin_30835923的博客 308

ArcGIS | 全球新冠肺炎地图数据下载和处理

ArcGIS

thinkpang的博客 2901

uni-app项目中引入Vant UI组件库(完美避坑!!!)纯净版

uni-app项目中引入Vant UI组件库(纯净版--无uni-ui)

Wzmlzrr的博客 3万+

设计模式学习—状态模式(State Design Pattern)

设计模式之状态模式,一种行为型模式

闲鱼的博客 1034

AIDC供电系统与算电协同

AIDC供电系统的技术革新为算电协同提供了基础保障,而算电协同则是解决AIDC高能耗问题、推动数字经济可持续发展的关键路径

数据中心全生命周期价值管理 2570

认真学习设计模式之状态模式(State Pattern)

【1】概述 状态模式允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。这个模式将状态封装成独立的类,并将动作委托到 代表当前状态的对象,我们知道行为会随着内部状态而改变。 一个对象“看起来好像修改了它的类”是什么意思呢?从客户的视角来看:如果说你使用的对象能够完全改变它的行为,那么你会觉得,这个对象实际上是从别的类实例化而来的。然而,实际上,你知道我们是在使用组合通过简单引用不同的状态对象来造成类改变的假象。 ① UML类图 Context是一个类,它可以拥有一些内部状态。 State接

小小默:进无止境 593

复合材料RVE建模与力学性能分析实战指南

代表体积元(RVE)建模是复合材料多尺度分析的核心技术,通过建立微观结构与宏观性能的定量关联,可准确预测材料力学行为。本文基于ABAQUS平台,详细解析三材料(纤维/基体/界面相)RVE建模全流程,包括参数化几何建模、周期性网格划分策略、材料属性定义技巧等关键技术环节。针对碳纤维增强环氧树脂等典型复合材料,提供网格控制参数建议和材料参数参考表,并重点说明周期性边界条件的实现方法与验证标准。通过Python脚本自动化处理和优化分析流程,可显著提升计算效率,为复合材料设计提供可靠仿真依据。

weixin_34062469的博客 549

天融信防火墙NGFW4000(TG-4628)安装配置笔记

配置一台全新的天融信防火墙NGFW4000,配置完后,内网用户10.10.1.0/24和10.10.2.0/24可以通过防火墙上网,外网用户可以通过访问防火墙的外网接口地址来访问内网的WEB服务器10.10.1.200,并且内网用户也可以通过WEB服务器的外网地址进行访问。 网络说明: 防火墙外网接口地址:218.90.123.121/30 防火墙内网接口地址:19...

weixin_33671935的博客 4455

设计模式学习--状态模式(State Pattern)

其实Android开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。下图是我进阶学习所积累的历年腾讯、头条、阿里、美团、字节跳动等公司2019-2021年的高频面试题,博主还把这些技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节祝大家都能得到自己心仪工作。《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!

2301_79600088的博客 447

基于IEEE39节点系统的风力发电机组并网改造与稳定性研究

本文研究了基于IEEE39节点系统的风力发电机组并网改造与稳定性问题。首先将系统工作频率从60Hz转换为50Hz,并对同步发电机、变压器、线路和负荷参数进行相应调整。随后将30、32、34、37号节点的同步发电机替换为不同容量的永磁同步发电机(PMSG)和双馈感应发电机(DFIG),详细建立了两种风电机组的数学模型和控制策略。通过Simulink仿真验证,改造后的系统能够稳定运行并满足并网要求。研究成果为大规模风电并网系统仿真提供了参考,对提高电力系统可再生能源消纳能力具有重要意义。

huanghm88的专栏 110

HeadFirst 设计模式学习笔记11——状态模式

本文已搬家至【HeadFirst 设计模式学习笔记】11 状态模式

gnuhpc的专栏 3170

11、基于多阵列电极的表面肌电信号运动估计

本文介绍了一种基于多阵列电极的表面肌电信号运动估计技术,旨在实现对手腕和手指运动的高精度估计,解决传统人机接口在操控多自由度机器人时的局限性。通过多阵列电极系统采集前臂肌肉活动信号,结合独立成分分析(ICA)和非负矩阵分解(NMF)等信号处理方法,提取肌肉协同作用,进而生成运动指令以控制机器人或假肢手。文章对比了多阵列电极与传统电极的优势,展示了运动估计算法的整体流程,并以假肢手控制为例说明其实际应用。最后探讨了该技术在测量精度、应用拓展、智能化和便携化等方面的未来发展方向。该技术为假肢控制、康复训练和人机

ik678901234的博客 87

传感器校准与标定:传感器的灵敏度校准_(11).常见传感器的灵敏度校准方法

线性校准:适用于传感器输出与输入之间存在线性关系的情况。通过收集数据并使用最小二乘法拟合线性方程,可以确定斜率和截距,从而实现校准。非线性校准:适用于传感器输出与输入之间存在非线性关系的情况。通过收集数据并使用非线性拟合方法(如最小二乘法),可以确定多项式或其他非线性方程的参数,从而实现校准。温度补偿校准:适用于传感器在不同温度下输出特性变化的情况。通过收集不同温度下的数据并使用温度补偿方程,可以提高传感器在不同温度下的测量精度。其他校准方法。

2401_87715305的博客 917

设计模式学习--状态模式(State Pattern)(2)

同时我还搜集整理2020年字节跳动,以及腾讯,阿里,华为,小米等公司的面试题,把面试的要求和技术点梳理成一份大而全的“ Android架构师”面试 Xmind(实际上比预期多花了不少精力),包含。同时我还搜集整理2020年字节跳动,以及腾讯,阿里,华为,小米等公司的面试题,把面试的要求和技术点梳理成一份大而全的“ Android架构师”面试 Xmind(实际上比预期多花了不少精力),包含。但是如果你仅仅是看一遍,而不去学习和深究。学习方向很容易规划,但是如果只通过碎片化的学习,对自己的提升是很慢的。

2401_84009215的博客 506

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

基于Python学习《Head First设计模式》第十章 状态模式

先大致了解,更多细节后续用到再扩展学习补充。

wzx77的博客 531

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

设计模式学习--状态模式(State Pattern)(1)

其实Android开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。当然我也为你们整理好了百度、阿里、腾讯、字节跳动等等互联网超级大厂的历年面试真题集锦。这也是我这些年来养成的习惯,一定要学会把好的东西,归纳整理,然后系统的消化吸收,这样才能极大的提高学习效率和成长进阶。碎片、零散化的东西,我觉得最没有价值的。就好比你给我一张扑克牌,我只会觉得它是一张废纸,但如果你给我一副扑克牌,它便有了它的价值。

2401_84009192的博客 356

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

尚硅谷设计模式学习(22)---[状态模式(State Pattern)]

尚硅谷传送门==>B站尚硅谷Java设计模式 ❤❤❤感谢尚硅谷❤❤❤ 最近开始计划学习一下设计模式了,加油!!! 状态模式 来解决对象在多种状态转换时,需要对外输出不同的行为的问题。状态和行为一一对应,状态之间可以相互转换. 原理图 当一个对象的内在状态改变时,允许改变其行为,这个对象看起来就像是改变了这个类. 当一个对象有很多种状态,状态之间还会相互转换,对不同的状态要求有不同的行为,可考虑用状态模式 解决一个案例 APP抽奖活动 具体要求: 1假如每参加一次这个活动要扣除用户5

从零开始的异世界JAVA学习 311

设计模式学习笔记——状态模式

在状态模式(State Pattern)中,类的行为是基于它的状态改变的。这种类型的设计模式属于行为型模式。 在状态模式中,我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象。 介绍 意图:允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类。 主要解决:对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为。 何时使...

Stephen 253

设计模式学习--21.状态模式(State Pattern)

package com.designepattern.statepattern.v2; /** * @Author:glx * @Date:2020/12/10 * @Content: */ public class MainDemo { public static void main(String[] args) { Context context=new Context(); context.handle(); con...

u010031813的博客 166

设计模式学习(十二)状态模式

设计模式学习(十二)状态模式

ACGkaka的博客 888

java设计模式学习之【状态模式】

这篇教程不仅提供了状态模式的理论基础,还通过具体的Java代码示例展示了如何实现和应用这种模式。简单理解,通俗易懂

qq_33129875的博客 2952
上一篇: 设计模式学习——解释器模式
下一篇: 编程案例——layui的table表格并获取选中的数据、layui监控select下拉框并将隐藏的div显示
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值