C#学习笔记-状态模式
题目1:通过代码描述每一天的不同时间段的工作效率
分析:
首先确定,工作状态指正在工作,或者以及下班这些情况,而这些情况所受影响的因素包括:当前时间以及任务是否已经完成。所以在Work中需要两个属性:hour和finish。然后根据这两个属性直接判断当前的工作状态即可。
实现:
class Program
{
static void Main(string[] args)
{
//紧急项目
Work emergencyProject = new Work();
emergencyProject.Hour = ;
emergencyProject.WriteProgram();
emergencyProject.Hour = ;
emergencyProject.WriteProgram();
emergencyProject.Hour = ;
emergencyProject.WriteProgram();
emergencyProject.Hour = ;
emergencyProject.WriteProgram();
emergencyProject.Hour = ;
emergencyProject.WriteProgram();
emergencyProject.Hour = ;
emergencyProject.Finish = false;
emergencyProject.WriteProgram();
emergencyProject.Hour = ;
emergencyProject.WriteProgram();
emergencyProject.Hour = ;
emergencyProject.WriteProgram(); Console.Read();
}
public class Work
{
private int hour;
private bool finish = false; public int Hour
{
get { return hour; }
set { hour = value; }
}
public bool Finish
{
get { return finish; }
set { finish = value; }
}
/// <summary>
/// 根据时间来判断当前的工作状态如何
///
/// 方法过长
/// </summary>
public void WriteProgram()
{
if (hour < )
{
Console.WriteLine("当前时间:{0}点 上午工作,精神百倍", hour);
}
else if (hour < )
{
Console.WriteLine("当前时间:{0}点 饿了,午饭;犯困,午休", hour);
}
else if (hour < )
{
Console.WriteLine("当前时间:{0}点 下午状态还不错,继续努力", hour);
}
else
{
if (finish)
{
Console.WriteLine("当前时间:{0}点 下班回家了", hour);
}
else
{
if (hour < )
{
Console.WriteLine("当前时间:{0}点 加班哦,疲惫至极", hour);
}
else
{
Console.WriteLine("当前时间:{0}点 不行了,睡着了。", hour);
}
}
}
}
}
}
题目2:从1中可以很明显的看出WriteProgram()函数几乎承载了所有的判断处理,且函数函数过长,所以在Work类中违背了“单一职责原则"。
分析:
面向对象设计就是希望做到代码的责任分解,在这个情况中,我们将所有的判断全部添加在了WriteProgram()一个函数中,不仅是函数冗长,如果我临时添加新的情况,可能对原来判断有出入的时间也会造成很多麻烦,对于将来的修改百害而无一利。
所以我们需要根据情况来分解函数和类。
本题目中,我们需要获得当前的工作状态,而这个的直接影响因素包括时间Hour和是否已经完成任务TaskFinished。
所以我们根据当前的时间可以很明显的分为不同时间段,也就是WriteProgram()的if,else都可以自己单独拥有一个类,他们都继承于同一个抽象类State即可。
然后我们初始化直接进入ForenoonState类,毕竟每天早上的时间不会变,如果当前时间不再是早上,那么我们就需要进入下一个时间段进行判断,所以在ForenoonState类中我们需要加入判断,如果当前时间满足早上的时间段,显示工作状态,如果当前时间不再是早上的时间段,那么我们进入下一个时间段,以此类推,找到我们当前时间段的工作状态。

实现:
class Program
{
static void Main(string[] args)
{
//紧急项目
Work emergencyProject = new Work();
emergencyProject.Hour = ;
emergencyProject.WriteProgram();
emergencyProject.Hour = ;
emergencyProject.WriteProgram();
emergencyProject.Hour = ;
emergencyProject.WriteProgram();
emergencyProject.Hour = ;
emergencyProject.WriteProgram();
emergencyProject.Hour = ;
emergencyProject.WriteProgram();
emergencyProject.Hour = ;
emergencyProject.TaskFinished = false;
emergencyProject.WriteProgram();
emergencyProject.Hour = ;
emergencyProject.WriteProgram();
emergencyProject.Hour = ;
emergencyProject.WriteProgram(); Console.Read();
}
public class Work
{
private int hour;
private bool finish = false;
private State current;
//初始化进入的时候是上午工作状态
public Work()
{
current = new ForenoonState();
}
public int Hour
{
get { return hour; }
set { hour = value; }
}
public bool TaskFinished
{
get { return finish; }
set { finish = value; }
} public void SetState(State s)
{
current = s;
}
public void WriteProgram()
{
current.WriteProgram(this);
}
}
/// <summary>
/// 抽象状态
/// </summary>
public abstract class State
{
public abstract void WriteProgram(Work w);
}
/// <summary>
/// 上午工作状态
///
/// 逻辑是:根据时间推移,上午工作后,移至中午午饭时间
/// </summary>
public class ForenoonState : State
{
public override void WriteProgram(Work w)
{
if (w.Hour < )
{
Console.WriteLine("当前时间:{0} 上午工作,精神百倍", w.Hour);
}
else
{
w.SetState(new NoonState());
w.WriteProgram();
}
}
}
/// <summary>
/// 中午工作状态
///
/// 逻辑是:根据时间推移,午休时间后,移至下午工作时间
/// </summary>
public class NoonState : State
{
public override void WriteProgram(Work w)
{
if (w.Hour < )
{
Console.WriteLine("当前时间:{0} 饿了,午饭;犯困,午休", w.Hour);
}
else
{
w.SetState(new AfternoonState());
w.WriteProgram();
}
}
}
/// <summary>
/// 下午工作状态
///
/// 逻辑是:根据时间推移,下午工作后,移至晚间工作状态
/// </summary>
public class AfternoonState : State
{
public override void WriteProgram(Work w)
{
if (w.Hour < )
{
Console.WriteLine("当前时间:{0} 下午状态还不错,继续努力", w.Hour);
}
else
{
w.SetState(new EveningState());
w.WriteProgram();
}
}
}
/// <summary>
/// 晚间工作状态
///
/// 逻辑是:已完成工作的可以准点下班,移至下班休息状态
/// 未完成工作的继续加班:这里又分为未超过人体承受能力的(21小时)就继续加班(此处已是最底层,没有再多加其他的操作了)
/// 超过21小时的将移至睡眠状态
/// </summary>
public class EveningState : State
{
public override void WriteProgram(Work w)
{
if (w.TaskFinished)
{
w.SetState(new RestState());
w.WriteProgram();
}
else
{
//最底层,不要再次调用,会无限往复的
if (w.Hour < )
{
Console.WriteLine("当前时间:{0} 加班哦,疲惫至极", w.Hour);
}
else
{
w.SetState(new SleepingState());
w.WriteProgram();
}
}
}
}
/// <summary>
/// 睡眠状态
///
/// 最底层,不要再次调用,会无限往复的
/// </summary>
public class SleepingState : State
{
public override void WriteProgram(Work w)
{
Console.WriteLine("当前时间:{0}点 不行了,睡着了", w.Hour);
}
}
/// <summary>
/// 下班休息状态
///
/// 最底层,不要再次调用,会无限往复的
/// </summary>
public class RestState : State
{
public override void WriteProgram(Work w)
{
if (w.TaskFinished)
{
Console.WriteLine("当前时间:{0}点 下班回家", w.Hour);
}
}
}
}
总结:
这里用到的就是状态模式(State):当一个对象的内在状态改变时,允许改变其行为,这个对象看起来像是改变了其类。
状态模式主要解决的是当控制一个对象状态转换的调节表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以吧复杂的判断逻辑简化。
状态模式的好处是将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。
注:文中所有代码及知识点均来自于《大话设计模式》,本人属于边学边看边敲代码边总结的阶段。
C#学习笔记-状态模式的更多相关文章
- 《Head First 设计模式》学习笔记——状态模式
在软件开发过程中.应用程序可能会依据不同的情况作出不同的处理. 最直接的解决方式是将这些全部可能发生的情况全都考虑到.然后使用if... ellse语句来做状态推断来进行不同情况的处理. 可是对复杂状 ...
- 学习笔记——状态模式State
状态模式,主要是用于存在大量case判断的操作执行,同时这些case依赖于对象的状态,那么就可以将大量的case判断封装为独立的类. Context: -state,当前状态对象. ChangeSta ...
- Java设计模式学习记录-状态模式
前言 状态模式是一种行为模式,用于解决系统中复杂的对象状态转换以及各个状态下的封装等问题.状态模式是将一个对象的状态从该对象中分离出来,封装到专门的状态类中,使得对象的状态可以灵活多变.这样在客户端使 ...
- 《Head first设计模式》学习笔记 – 迭代器模式
<Head first设计模式>学习笔记 – 迭代器模式 代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示. 爆炸性新闻:对象村餐厅和对象村煎饼屋合并了!真是个 ...
- 设计模式 笔记 状态模式 State
//---------------------------15/04/28---------------------------- //State 状态模式----对象行为型模式 /* 1:意图: ...
- 《Head First 设计模式》学习笔记——迭代模式 + 组合模式
迭代模式设置共生死亡,一般来说.我们只是想实现一个集,我们需要的同时提供这个集合的迭代器,喜欢java中间Collection.List.Set.Map等,这些集合都有自己的迭代器.假如我们要实现一个 ...
- 学习笔记——解释器模式Interpreter
解释器模式,其实就是编译原理中的语法解释器,如果用在项目中,可以用于实现动态脚本的解析,也就是说项目可以支持用户脚本扩展. 但实际上,这种运行时解释,效率很慢,如果不是很需要的话,不建议使用. 一种简 ...
- 学习笔记——备忘录模式Memento
备忘录模式,可以将当前状态保存,并随时恢复. Originator存在状态state,当需要保存此状态时,通过CreateMemento创建一个备忘录对象Memento保存此状态:而需要恢复相应状态时 ...
- C#学习笔记-备忘录模式
什么是备忘录模式? 备忘录模式(Memento):在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态. 这样以后就可将该对象恢复到原先保存的状态. 备忘录模式的组成 Orig ...
随机推荐
- .NET Core 2.0下载和文档
.NET Core 2.0 RTM 正式版2017/8/14 发布.对应发布 ASP.NET Core 2.0 .EF Core 2.0以及.NET Standard 2.0. 你可以通过 Visua ...
- .NET Core RSA 签名和验签(密钥为 16 进制编码)
使用 OpenSSL 生成公私钥对,命令: $ openssl genrsa -out rsa_1024_priv.pem $ openssl pkcs8 -topk8 -inform PEM -in ...
- Java的流程控制结构,细节详解
位运算符 &与 |或 ^异或 <<左移 >>右移 >>>无符号右移 ~取反 注意:位运算是针对整数运算的 int i = 6,j = 10; 方式一 ...
- 3D Game Programming withDX11 学习笔记(一) 数学知识总结
在图形学中,数学是不可或缺的一部分,所以本书最开始的部分就是数学知识的复习.在图形学中,最常用的是矢量和矩阵,所以我根据前面三个章节的数学知识,总结一下数学知识. 一.矢量 数学中的矢量,拥有方向和长 ...
- 写给小白的JAVA链接MySQL数据库的步骤(JDBC):
作为复习总结的笔记,我罗列了几个jdbc步骤,后边举个简单的例子,其中的try块请读者自行处理. /* * 1.下载驱动包:com.mysql.jdbc.Driver;网上很多下载资源,自己找度娘,此 ...
- 百度文库的实现——java利用openoffice,批量word转pdf
百度文库的主要功能就是将上传的word文档,转码成pdf格式再展示出来.其中有四种方法可以实现这样的操作: 方法一:用apache pio 读取doc文件,然后转成html文件用Jsoup格式化htm ...
- Nodejs密集型CPU解决方案
首先说一下nodejs单线程的优势: 高性能,与php相比,避免了频繁创建切换线程的开销,执行更加迅速,资源占用小. 线程安全,不用担心同一变量被多线程读写,造成程序崩溃. 单线程的异步和非阻塞,其实 ...
- python爬虫爬取人人车(二手车)、利用padas、matplotlib生成图表,将信息打成csv格式
该程序主要为了抓取人人车卖车信息,包括车系.车型号.购车日期.卖车价格.行驶路程.首付价格等等信息.话不多说直接代码. 入库之后将Mongodb里的信息导出成Excel语句 mongoexport - ...
- [编织消息框架][JAVA核心技术]annotation基础
应用动态代理技术要先掌握annotation技术 注解是JDK1.5之后才有的新特性,JDK1.5之后内部提供的三个注解 @Deprecated 意思是“废弃的,过时的” @Override 意思是“ ...
- csv文件转json
http://stackoverflow.com/questions/19766266/directly-convert-csv-file-to-json-file-using-the-jackson ...