04、状态模式(State)
一、概念:
当一个对象的内在状态改变时,允许改变其行为,这个对象看起来像是改变了其类。【DP】
二、作用:
状态模式的主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。吧状态的判断逻辑转移到表示不同状态的一系列当中,
可以把复杂的判断逻辑简化。当然如果这个状态的判断很简单,那么就没必要用“状态模式”了,千万注意不要为了设计模式而去用设计模式。
三、通俗的概念理解:
就是为了消除庞大的条件分支语句。当一个对象的行为取决于他的状态,并且他必须在运行时刻根据状态改变他的行为时,就可以考虑使用状态模式了。
四、状态模式类图;

五、对概念的理解和针对类图进行代码的开展
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace State
{
//State类,抽象状态类,定义一个接口一封装与Context的一个特定状态相关的行为
public abstract class State
{
public abstract void Handle(Context context);
} //ConcreteState类,具体状态类,每一个子类实现一个与Context的一个状态相关的行为
public class ConcreteStateA : State
{
public override void Handle(Context context)
{
context.State = new ConcreteStateB(); //设置ConcreStateA的下一状态是ConcreStateB
}
} public class ConcreteStateB : State
{
public override void Handle(Context context)
{
context.State = new ConcreteStateA(); //设置ConcreStateB的下一状态是ConcreStateA
}
} //Context类,维护一个ConcreteState子类的实例,这个实例定义当前的状态
public class Context
{
private State state;
public State State
{
get { return state; }
set
{
state = value;
Console.WriteLine("当前状态:" + state.GetType().Name);
}
} public Context(State state) //定义Context的初始状态
{
this.state = state;
} public void Request()
{
state.Handle(this); //对请求做处理,并设置下一状态
} } class Program
{
//客户端代码;
static void Main(string[] args)
{
Context context = new Context(new ConcreteStateA()); //设置Context的初始状态为ConcreStateA context.Request();
context.Request();
context.Request();
context.Request();
Console.ReadKey(); }
}
}
结果显示

六、接下啦就是对概念进行实例的操作了,概念记得再熟,也不如实战一把
这里就是以程序员的加班来进行案例的解释了,对一天的工作时间与下班来进行一个状态的切换。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Test_02
{ //抽象的状态
public abstract class State
{
public abstract void WriteProgram(Work work);
} //上午的工作状态
public class ForenoonState : State
{
public override void WriteProgram(Work work)
{
if (work.Hour < )
{
Console.WriteLine("当前时间:" + work.Hour + "点,上午工作,精神还行");
}
else //否则,超过12点进行状态的切换
{
work.SetState(new NoonState());
work.WriteProgram();
}
}
} //中午的工作状态
public class NoonState : State
{
public override void WriteProgram(Work work)
{
if (work.Hour < )
{
Console.WriteLine("当前时间:" + work.Hour + "点,中午,饿了,犯困");
}
else //转到下午的工作状态
{
work.SetState(new AfternoonState());
work.WriteProgram();
} }
} public class AfternoonState : State
{
public override void WriteProgram(Work work)
{
if (work.Hour < )
{
Console.WriteLine("当前时间:" + work.Hour + "点,下午状态还不错,继续努力");
}
else//否则,转为傍晚的工作状态
{
work.SetState(new EveningState());
work.WriteProgram();
} }
}
//晚间工作状态
public class EveningState : State
{
public override void WriteProgram(Work work)
{
if (work.Finish == true) //当工作完成了,则转入下班的装态
{
work.SetState(new RestState());
work.WriteProgram();
}
else
{
if (work.Hour < )
{
Console.WriteLine("当前时间:" + work.Hour + "点,加班哦,疲累至极");
}
else //当时间超过21点则转入睡觉的状态
{
work.SetState(new SleepState());
work.WriteProgram();
}
}
}
}
//睡眠状态
public class SleepState : State
{
public override void WriteProgram(Work work)
{
Console.WriteLine("当前时间:" + work.Hour + "点,已经撑不住了,睡着了");
}
} //下班休息状态
public class RestState : State
{
public override void WriteProgram(Work work)
{
Console.WriteLine("当前时间:" + work.Hour + "点,下吧回家休息了");
}
} //工作类
public class Work
{
private State current;
public Work()
{
current = new ForenoonState();//工作的初始状态为上午工作状太,9点开始工作
}
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 state)
{
current = state;
} public void WriteProgram()
{
current.WriteProgram(this);
} }
class Program
{
static void Main(string[] args)
{
Work work = new Work();
work.Hour = ;
work.WriteProgram();
Console.ReadKey();
}
}
}
七、总结:
当一个对象的行为取决于他的状态,并且他必须在运行时刻根据状态改变他的行为时,就可以考虑使用状态模式了,
例如可以在角色的AI切换的时候使用,在游戏界面的登录界面以及其他界面的切换中使用,
八:扩充:
在写代码的时候,一定要避免在一个类中的方法过于太长了的情况发生,看起来也是不太舒服的!
2017-12-14 00:27:06
04、状态模式(State)的更多相关文章
- 【转】设计模式 ( 十七) 状态模式State(对象行为型)
设计模式 ( 十七) 状态模式State(对象行为型) 1.概述 在软件开发过程中,应用程序可能会根据不同的情况作出不同的处理.最直接的解决方案是将这些所有可能发生的情况全都考虑到.然后使用if... ...
- 二十四种设计模式:状态模式(State Pattern)
状态模式(State Pattern) 介绍允许一个对象在其内部状态改变时改变它的行为.对象看起来似乎修改了它所属的类. 示例有一个Message实体类,对它的操作有Insert()和Get()方法, ...
- 设计模式 ( 十七) 状态模式State(对象行为型)
设计模式 ( 十七) 状态模式State(对象行为型) 1.概述 在软件开发过程中,应用程序可能会根据不同的情况作出不同的处理.最直接的解决方案是将这些所有可能发生的情况全都考虑到.然后使用if... ...
- 乐在其中设计模式(C#) - 状态模式(State Pattern)
原文:乐在其中设计模式(C#) - 状态模式(State Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 状态模式(State Pattern) 作者:webabcd 介绍 允 ...
- 状态模式-State Pattern(Java实现)
状态模式-State Pattern 在状态模式(State Pattern)中,类的行为是基于它的状态改变的.当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类. State接口 ...
- 北风设计模式课程---状态模式State(对象行为型)
北风设计模式课程---状态模式State(对象行为型) 一.总结 一句话总结: 状态模式 具体状态的行为在具体的状态类中就解决,不用交给外部做判断.实质是将多条件判断弄成了多个类,在不同的类中做判断 ...
- 状态模式(State)-设计模式
软件模式是将模式的一般概念应用于软件开发领域,即软件开发的 总体指导思路或参照样板.软件模式并非仅限于设计模式,还包括 架构模式.分析模式和过程模式等,实际上,在软件生存期的每一个阶段都存在着一些被认 ...
- 设计模式 笔记 状态模式 State
//---------------------------15/04/28---------------------------- //State 状态模式----对象行为型模式 /* 1:意图: ...
- 设计模式(十二):通过ATM取款机来认识“状态模式”(State Pattern)
说到状态模式,如果你看过之前发布的重构系列的文章中的<代码重构(六):代码重构完整案例>这篇博客的话,那么你应该对“状态模式”并不陌生,因为我们之前使用到了状态模式进行重构.上一篇博客我们 ...
- 十一个行为模式之状态模式(State Pattern)
定义: 当一个对象有多个状态,并且在每个状态下有不同的行为,可以使用状态模式来在其内部改变状态时改变其行为,而客户端不会察觉状态的改变,仍使用同样的方法或接口与对象进行交互. 结构图: Context ...
随机推荐
- 前端开发JS——快速入门
1.JS的核心标准ECMAScript 组成 ECMAScript------>核心语法标准 DOM------------->对文档节点的操作 ...
- 英语chrismatite黄蜡石chrismatite单词
黄蜡石chrismatite的原岩均为硅质岩,各种原岩受到构造变动.火山活动.热液作用等影响,产生复杂的物理和化学变化,包括重结晶.热变质等,导致矿物成分及结构构造的变化,后受构造变动的影响,岩石露出 ...
- Jenkins的CI持续集成
Jenkins的CI持续集成 全局配置 系统管理->全局工具配置,配置Git,JDK和Maven 1)解压maven到当前目录 tar zxf apache-maven-3.5.4-bin.ta ...
- GCN 简单numpy实现
`#参考:https://blog.csdn.net/weixin_42052081/article/details/89108966 import numpy as np import networ ...
- Django框架(十九)--Django rest_framework-认证组件
一.什么是认证 只有认证通过的用户才能访问指定的url地址,比如:查询课程信息,需要登录之后才能查看,没有登录,就不能查看,这时候需要用到认证组件 二.利用token记录认证过的用户 1.什么是tok ...
- commons-dbutils【不推荐】
Apache 组织提供的一个开源 JDBC工具类库,它是对JDBC的简单封装. 一般项目开发过程中,要么选择 ORM框架,要么自己编写DBUtils类+数据库连接池就足够了.
- Java前后端的跨域问题
1 前端127.0.0.1:8888 2 后端127.0.0.1:8080 前端和后端因为来自不同的网域,所以在http的安全协议策略下,不信任 3 解决方案,在springmvc的控制层加入@Cro ...
- JS高阶---函数
[问题] [主体] 1.什么是函数? ①实现特定功能 ②多条语句的封装体 ③可以重复执行的代码块 2.为什么用函数? 提高代码的复用性,提升效率 3.如何定义函数? ①函数声明定义 ②函数表达式定义③ ...
- LoadRunner Controller集合点策略灰色问题 解决
1.脚本里已经添加了集合点,但是在Controller里集合点策略是灰色的无法点击 2.问题解决: 将下图的勾选项去掉即可(系统默认是勾选上的) 去掉勾选后可以选择了:
- zz独家专访AI大神贾扬清:我为什么选择加入阿里巴巴?
独家专访AI大神贾扬清:我为什么选择加入阿里巴巴? Natalie.Cai 拥有的都是侥幸,失去的都是人生 关注她 5 人赞同了该文章 本文由 「AI前线」原创,原文链接:独家专访AI大神贾扬清:我 ...