状态模式与状态图

2024-05-05 00:58
文章标签 模式 状态 状态图

本文主要是介绍状态模式与状态图,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

       说到状态模式,书上给出的解释是:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。看不懂?没关系,毕竟我们都不是小菜。

       我们还是从熟悉的状态图说起吧。

       故事是这样的:我们来看一个人他的下午时光是如何度过的。在12:00~13:00之间,他在吃饭。过了13点,他就开始午睡。睡醒以后,到了15点,他就出去玩了。也就是说,他的下午时间就在吃饭——睡觉——玩耍之间转换。

用状态图描述,基本上是这个样子的。(简化理解)



        联系我们的状态模式,其实状态模式根本上就是几个状态之间的转换,但精髓之处在于如何使得我们的代码更好,设计更完善。这就要结合我们之前讲的设计模式的一些原则和面向对象设计的知识了。首先,方法过长是坏味道。一般来看,状态之间的转换我们会用到很多的分支语句,这样使得一个方法代码过长,那么它的责任就过大了。所以,我们要让代码的责任分解。分解之后,需求改变之后代码的改动就会减少很多了。这也就符合之前说的开放-封闭原则。


用代码来表示:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace ConsoleApplication2
{class Program{static void Main(string[] args){//紧急项目lifeState emergencyProjects = new lifeState();emergencyProjects.Hour = 12;emergencyProjects.WriteProgram();emergencyProjects.Hour = 14;emergencyProjects.WriteProgram();emergencyProjects.Hour = 18;emergencyProjects.WriteProgram();emergencyProjects.TaskFinished = false;Console.Read();}}//抽象状态public abstract class State{public abstract void WriteProgram(lifeState w);}//吃饭状态public class EatingState : State{public override void WriteProgram(lifeState w){if (w.Hour <13){Console.WriteLine( "我在吃饭",w.Hour);}else{w.SetState(new SleepingState()); w.WriteProgram();   //12点之后,就开始午睡了,进入睡觉状态}}}//睡觉状态public class SleepingState : State{public override void WriteProgram(lifeState w){if (w.Hour <15){Console.WriteLine("我在睡觉",w.Hour);}else{w.SetState(new PlayingState()); w.WriteProgram(); //14点之后,进入玩耍状态}}}//玩耍状态public class PlayingState : State{public override void WriteProgram(lifeState w){Console.WriteLine("我在玩",w.Hour);         }}public class lifeState{private State current;public lifeState(){current = new EatingState();}private double  hour;public double  Hour    //“钟点”属性,状态转换的依据{get { return hour ; }set {hour = value; }}private bool finish = false;  //“任务完成”属性public bool TaskFinished{get { return finish; }set { finish = value; }}public void SetState(State s){current = s;}public void WriteProgram(){current.WriteProgram(this);}}}


运行结果:


      看完这个小例子,我们来看一下状态模式的结构。我们把特定的状态相关的行为(如吃饭)放在一个对象中,因为代码都在Eating中,所以通过定义新的子类就可以很容易的增加新的状态和转换。把各个状态转移逻辑分布到Sleeping,Playing,Eating之中,减少了相互之间的依赖。



这篇关于状态模式与状态图的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/960470

相关文章

Prometheus+cpolar如何在手机上也能监控服务器状态?

《Prometheus+cpolar如何在手机上也能监控服务器状态?》本文强调了通过Cpolar这一内网穿透工具,轻松突破Prometheus仅限于局域网访问的限制,实现外网随时随地访问监控数据,教你... 目录前言1.安装prometheus2.安装cpolar实现随时随地开发3.配置公网地址4.保留固定

Go语言实现桥接模式

《Go语言实现桥接模式》桥接模式是一种结构型设计模式,它将抽象部分与实现部分分离,使它们可以独立地变化,本文就来介绍一下了Go语言实现桥接模式,感兴趣的可以了解一下... 目录简介核心概念为什么使用桥接模式?应用场景案例分析步骤一:定义实现接口步骤二:创建具体实现类步骤三:定义抽象类步骤四:创建扩展抽象类步

Spring Boot基于 JWT 优化 Spring Security 无状态登录实战指南

《SpringBoot基于JWT优化SpringSecurity无状态登录实战指南》本文介绍如何使用JWT优化SpringSecurity实现无状态登录,提高接口安全性,并通过实际操作步骤... 目录Spring Boot 实战:基于 JWT 优化 Spring Security 无状态登录一、先搞懂:为什

C++中的解释器模式实例详解

《C++中的解释器模式实例详解》这篇文章总结了C++标准库中的算法分类,还介绍了sort和stable_sort的区别,以及remove和erase的结合使用,结合实例代码给大家介绍的非常详细,感兴趣... 目录1、非修改序列算法1.1 find 和 find_if1.2 count 和 count_if1

Redis中群集三种模式的实现

《Redis中群集三种模式的实现》Redis群集有三种模式,分别是主从同步/复制、哨兵模式、Cluster,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录1. Redis三种模式概述2、Redis 主从复制2.1 主从复制的作用2.2 主从复制流程2

深入理解MySQL流模式

《深入理解MySQL流模式》MySQL的Binlog流模式是一种实时读取二进制日志的技术,允许下游系统几乎无延迟地获取数据库变更事件,适用于需要极低延迟复制的场景,感兴趣的可以了解一下... 目录核心概念一句话总结1. 背景知识:什么是 Binlog?2. 传统方式 vs. 流模式传统文件方式 (非流式)流

Java发送SNMP至交换机获取交换机状态实现方式

《Java发送SNMP至交换机获取交换机状态实现方式》文章介绍使用SNMP4J库(2.7.0)通过RCF1213-MIB协议获取交换机单/多路状态,需开启SNMP支持,重点对比SNMPv1、v2c、v... 目录交换机协议SNMP库获取交换机单路状态获取交换机多路状态总结交换机协议这里使用的交换机协议为常

JWT + 拦截器实现无状态登录系统

《JWT+拦截器实现无状态登录系统》JWT(JSONWebToken)提供了一种无状态的解决方案:用户登录后,服务器返回一个Token,后续请求携带该Token即可完成身份验证,无需服务器存储会话... 目录✅ 引言 一、JWT 是什么? 二、技术选型 三、项目结构 四、核心代码实现4.1 添加依赖(pom

C#和Unity中的中介者模式使用方式

《C#和Unity中的中介者模式使用方式》中介者模式通过中介者封装对象交互,降低耦合度,集中控制逻辑,适用于复杂系统组件交互场景,C#中可用事件、委托或MediatR实现,提升可维护性与灵活性... 目录C#中的中介者模式详解一、中介者模式的基本概念1. 定义2. 组成要素3. 模式结构二、中介者模式的特点

深度解析Nginx日志分析与499状态码问题解决

《深度解析Nginx日志分析与499状态码问题解决》在Web服务器运维和性能优化过程中,Nginx日志是排查问题的重要依据,本文将围绕Nginx日志分析、499状态码的成因、排查方法及解决方案展开讨论... 目录前言1. Nginx日志基础1.1 Nginx日志存放位置1.2 Nginx日志格式2. 499