千家信息网

如何理解Java设计模式的状态模式

发表于:2025-11-08 作者:千家信息网编辑
千家信息网最后更新 2025年11月08日,本篇内容介绍了"如何理解Java设计模式的状态模式"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、
千家信息网最后更新 2025年11月08日如何理解Java设计模式的状态模式

本篇内容介绍了"如何理解Java设计模式的状态模式"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

一、什么是状态模式

定义:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。

主要解决:当控制一个对象状态的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类中,可以把复杂的判断逻辑简化。

意图:允许一个对象在其内部状态改变时改变它的行为

二、状态模式的结构

在该类图中,我们看到三个角色:

(1)Context: 环境类,定义客户感兴趣的接口,维护一个State子类的实例,这个实例对应的是对象当前的状态。

(2)State:抽象状态类或者状态接口,定义一个或者一组行为接口,表示该状态下的行为动作。

(3)ConcreteState: 具体状态类,实现State抽象类中定义的接口方法,从而达到不同状态下的不同行为。

三、状态模式的使用场景

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

2.一个操作中含有庞大的多分支结构,并且这些分支决定于对象的状态。

例子:我们在微博上看到一篇文章,觉得还不错,于是想评论或者转发,但如果用户没有登录,这个时候就会先自动跳转到登录注册界面,如果已经登录,当然就可以直接评论或者转发了。这里我们可以看到,我们用户的行为是由当前是否登录这个状态来决定的,这就是典型的状态模式情景。

当然还包括很多其他动作,例如转发、分享、打赏等等,都要重复判断状态才行,如果程序随着需求的改动或者功能逻辑的增加需要修改代码,那么你只要遗漏了一个判断,就会出问题。

而使用状态模式,可以很好地避免过多的if-else -分支,状态模式将每一个状态分支放入一个独立的类中,每一个状态对象都可以独立存在,程序根据不同的状态使用不同的状态对象来实现功能。

四、状态模式和策略模式对比

如果我们在编写代码的时候,遇到大量的条件判断的时候,可能会采用策略模式来优化结构,因为这时涉及到策略的选择,但有时候仔细查看下,就会发现,这些所谓的策略其实是对象的不同状态,更加明显的是,对象的某种状态也成为判断的条件。

策略模式的Context含有一个Strategy的引用,将自身的功能委托给Strategy来完成。

我们把Strategy接口改个名字为State,这就是状态模式了,同样Context也有一个State类型的引用,也将自己的部门功能委托给State来完成。

要使用状态模式,我们必须明确两个东西:状态和每个状态下执行的动作。

在状态模式中,因为所有的状态都要执行相应的动作,所以我们可以考虑将状态抽象出来。

状态的抽象一般有两种形式:接口和抽象类。如果所有的状态都有共同的数据域,可以使用抽象类,但如果只是单纯的执行动作,就可以使用接口。

他们之间真正的区别在策略模式对Strategy的具体实现类有绝对的控制权,即Context要感知Strategy具体类型。而状态模式,Context不感知State的具体实现,Context只需调用自己的方法,这个调用的方法会委托给State来完成,State会在相应的方法调用时,自动为Context设置状态,而这个过程对Context来说是透明的,不被感知的。

五、状态模式的优缺点

优点:

1、封装了转换规则。

2、枚举可能的状态,在枚举状态之前需要确定状态种类。

3、将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为。

4、允许状态转换逻辑与状态对象合成一体,而不是某一个巨大的条件语句块。

5、可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数。

缺点:

1、状态模式的使用必然会增加系统类和对象的个数。

2、状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱。

3、状态模式对"开闭原则"的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态;而且修改某个状态类的行为也需修改对应类的源代码。

六、状态模式的实现

抽象状态类,定义一个接口以封装与Context类(Work)的一个特定状态相关的行为。

public abstract class State{    public abstract void WriteProgram(Work w);}

工作状态类,每一个子类实现一个与Context类(Work)的一个状态相关的行为。

//上午工作状态public class ForeNoonState : State{    public override void WriteProgram(Work w)    {        if (w.Hour < 12)        {            Console.WriteLine("当前时间:{0}点,上午工作,精神百倍", w.Hour);        }        else        {            //超过12点,则转入中午工作状态            w.SetState(new NoonState());            w.WriteProgram();        }    }}
//中午工作状态public class NoonState : State{    public override void WriteProgram(Work w)    {        if (w.Hour < 13)        {            Console.WriteLine("当前时间:{0}点,吃午饭,午休", w.Hour);        }        else        {            //超过13点,则转入下午工作状态            w.SetState(new AfterNoonState());            w.WriteProgram();        }    }}
//下午工作状态public class AfterNoonState : State{    public override void WriteProgram(Work w)    {        if (w.Hour < 17)        {            Console.WriteLine("当前时间:{0}点,下午工作,继续努力", w.Hour);        }        else        {            //超过17点,则转入晚上工作状态            w.SetState(new EveningState());            w.WriteProgram();        }    }}
//晚上工作状态public class EveningState : State{    public override void WriteProgram(Work w)    {        if (w.Finish)        {            //如果状态已完成,则转入下班状态            w.SetState(new RestState());            w.WriteProgram();        }        else        {            if (w.Hour < 21)            {                Console.WriteLine("当前时间:{0}点,加班", w.Hour);            }            else            {                //超过21点,则转入睡眠工作状态                w.SetState(new SleepingState());                w.WriteProgram();            }        }    }}
//睡眠工作状态public class SleepingState : State{    public override void WriteProgram(Work w)    {        Console.WriteLine("当前时间:{0}点,睡觉", w.Hour);    }}//下班休息状态public class RestState : State{    public override void WriteProgram(Work w)    {        Console.WriteLine("当前时间:{0}点,下班", w.Hour);    }}

工作类,Context类,维护一个ConcreteState子类(工作状态类)的实例,这个实例定义当前的状态

public class Work{    private State current;    public Work()    {        //工作初始化为上午工作状态        current = new ForeNoonState();    }    //"钟点"属性,状态转换的依据    private double hour;    public double Hour    {        get { return hour; }        set { hour = value; }    }    //"任务完成"属性,是否能下班的依据    private bool finish = false;    public bool Finish    {        get { return finish; }        set { finish = value; }    }     public void SetState(State s)    {        current = s;    }     public void WriteProgram()    {        current.WriteProgram(this);    }}

客户端代码

class Program{    //客户端代码    static void Main(string[] args)    {        Work w = new Work();        w.Hour = 9;        w.WriteProgram();        w.Hour = 10;        w.WriteProgram();        w.Hour = 12;        w.WriteProgram();        w.Hour = 13;        w.WriteProgram();        w.Hour = 14;        w.WriteProgram();        w.Hour = 17;         w.Finish = false;        //w.Finish = true;        w.WriteProgram();        w.Hour = 19;        w.WriteProgram();        w.Hour = 22;        w.WriteProgram();         Console.Read();    }}

结果

当前时间:9点,上午工作,精神百倍
当前时间:10点,上午工作,精神百倍
当前时间:12点,吃午饭,午休
当前时间:13点,下午工作,继续努力
当前时间:14点,下午工作,继续努力
当前时间:17点,加班
当前时间:19点,加班
当前时间:22点,睡觉

"如何理解Java设计模式的状态模式"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

状态 模式 工作 对象 时间 行为 接口 不同 策略 代码 动作 结构 分支 功能 实例 方法 条件 逻辑 登录 复杂 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 金税开票未连接数据库 二0一九年网络技术专科 java使用数据库 常用网络安全系统分析工具 fifa足球数据库 软件开发工程师数据库 广州速游网络技术有限公司 服务器硬盘闪黄灯怎么更换 威行法律数据库使用教程 内外网络物理隔离数据转发服务器 计算机网络技术找什么实习 jquery 操作数据库 考勤由数据库导入怎样操作 珠海公文机器人rpa软件开发 数据库关联表需要主键吗 风电场网络安全指哪些设备 工程审批管控软件开发平台 武汉国家网络安全基地监理单位 上海夺汇网络技术石家庄 江苏千游网络技术有限公司广东 杭州知协网络技术有限公司app 网络安全法培训内容文档 网络安全的关键是 js向键值对中添加数据库 华为云数据库最新价格 银行负责网络安全职务 软件开发和设计英文 jquery 操作数据库 徐汇区提供软件开发质量保障 mysql数据库编码5.5
0