[Head First设计模式]生活中学设计模式——状态模式

简介:

系列文章

[Head First设计模式]山西面馆中的设计模式——装饰者模式

[Head First设计模式]山西面馆中的设计模式——观察者模式

[Head First设计模式]山西面馆中的设计模式——建造者模式

[Head First设计模式]饺子馆(冬至)中的设计模式——工厂模式

[Head First设计模式]一个人的平安夜——单例模式

[Head First设计模式]抢票中的设计模式——代理模式

[Head First设计模式]面向对象的3特征5原则

[Head First设计模式]鸭子模型——策略模式

[Head First设计模式]云南米线馆中的设计模式——模版方法模式

[Head First设计模式]餐馆中的设计模式——命令模式

[Head First设计模式]身边的设计模式——适配器模式

[Head First设计模式]生活中学设计模式——迭代器模式

[Head First设计模式]生活中学设计模式——组合模式

[Head First设计模式]生活中学设计模式——外观模式

引言

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

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

状态模式

允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。

类图

Context:状态管理器,它定义了客户感兴趣的接口,这个接口是由State去实现的;并维护一个ConcreteState子类的实例,这个实例定义当前的状态,当前状态变化的时候,会将变化后的ConcreteState返回给当前状态。

角色

state:状态,定义一个接口以封装与Context的特定状态相关的行为,但是行为本身是空的,该行为是由ConcreteState来实现的。

ConcreteState:具体状态子类,每一个子类实现一个与Contex的一个状态相关的行为。

一个例子

在过马路的时候,交通灯的状态,红,黄,绿,时间到了,在三个状态中切换。现在就用代码进行模拟。

复制代码
 1 namespace Wolfy.状态模式
 2 {
 3     /// <summary>
 4     /// 抽象状态类,定义一个接口以封装与Context的一个特定状态相关的行为
 5     /// </summary>
 6     public abstract class TrafficLightState
 7     {
 8         /// <summary>
 9         /// 改变状态的方法
10         /// </summary>
11         public abstract void ChangeState(TrafficLight context);
12     }
13 }
复制代码
复制代码
 1 namespace Wolfy.状态模式
 2 {
 3     /// <summary>
 4     /// 具体状态类 绿灯状态
 5     /// </summary>
 6     public class GreenState:TrafficLightState
 7     {
 8         public override void ChangeState(TrafficLight contex)
 9          {
10              Console.WriteLine("绿灯行");
11              contex.SetState(new RedState());
12         }
13     }
14 }
复制代码
复制代码
 1 namespace Wolfy.状态模式
 2 {
 3     /// <summary>
 4     /// 具体状态类 黄灯状态
 5     /// </summary>
 6     public class YellowState : TrafficLightState
 7     {
 8       
 9         public override void ChangeState(TrafficLight contex)
10         {
11             Console.WriteLine("黄灯亮了等一等");
12             //改变状态
13             contex.SetState(new GreenState());
14         }
15     }
16 }
复制代码
复制代码
 1 namespace Wolfy.状态模式
 2 {
 3     /// <summary>
 4     /// 具体状态类 红灯状态
 5     /// </summary>
 6     public class RedState : TrafficLightState
 7     {
 8         public override void ChangeState(TrafficLight contex)
 9         {
10             Console.WriteLine("红灯停");
11             //改变状态
12             contex.SetState(new YellowState());
13         }
14     }
15 }
复制代码
复制代码
 1 namespace Wolfy.状态模式
 2 {
 3     /// <summary>
 4     ///TrafficLight相当于 Context(上下文)类 拥有一些内部状态
 5     /// </summary>
 6     public class TrafficLight
 7     {
 8         //定时器 为了模拟等待的过程 定义一个定时器
 9         private Timer timer;
10         //记录状态
11         private TrafficLightState state;
12         /// <summary>
13         /// 构造函数 
14         /// </summary>
15         /// <param name="time">时间间隔</param>
16         public TrafficLight(int time)
17         {
18             this.timer = new Timer();
19             this.timer.Start();
20             this.timer.Elapsed += timer_Elapsed;
21             this.timer.Interval = time;
22 
23         }
24         void timer_Elapsed(object sender, ElapsedEventArgs e)
25         {
26             this.Request();
27         }
28         public void SetState(TrafficLightState state)
29         {
30             this.state = state;
31         }
32         /// <summary>
33         /// 对请求做处理,并设置下一个状态
34         /// </summary>
35         public void Request()
36         {
37             //时间到 改变一次状态
38             state.ChangeState(this);
39         }
40     }
41 }
复制代码

测试

复制代码
 1 namespace Wolfy.状态模式
 2 {
 3     class Program
 4     {
 5         static void Main(string[] args)
 6         {
 7             TrafficLight trafficLight = new TrafficLight(10000);
 8             //初始化第一个状态
 9             trafficLight.SetState(new RedState());
10             //发送请求 显示第一个状态 不用等待
11             trafficLight.Request();
12             Console.Read();
13         }
14     }
15 }
复制代码

结果

总结

优点

状态模式将与特定状态相关的行为局部化,并且将不同状态的行为分割开。

State模式将所有与一个特定的状态相关的行为都放入一个对象中。因为所有与状态相关的代码都存在于某一个State子类中, 所以通过定义新的子类可以很容易的增加新的状态和转换。另一个方法是使用数据值定义内部状态并且让 Context操作来显式地检查这些数据。但这样将会使整个Context的实现中遍布看起来很相似的条件if else语句或switch case语句。增加一个新的状态可能需要改变若干个操作, 这就使得维护变得复杂了。State模式避免了这个问题, 但可能会引入另一个问题, 因为该模式将不同状态的行为分布在多个State子类中。这就增加了子类的数目,相对于单个类的实现来说不够紧凑。但是如果有许多状态时这样的分布实际上更好一些, 否则需要使用巨大的条件语句。正如很长的过程一样,巨大的条件语句是不受欢迎的。它们形成一大整块并且使得代码不够清晰,这又使得它们难以修改和扩展。 State模式提供了一个更好的方法来组织与特定状态相关的代码。决定状态转移的逻辑不在单块的 i f或s w i t c h语句中, 而是分布在State子类之间。将每一个状态转换和动作封装到一个类中,就把着眼点从执行状态提高到整个对象的状态。这将使代码结构化并使其意图更加清晰。

它使得状态转换显式化

当一个对象仅以内部数据值来定义当前状态时 , 其状态仅表现为对一些变量的赋值,这不够明确。为不同的状态引入独立的对象使得转换变得更加明确。而且, State对象可保证Context不会发生内部状态不一致的情况,因为从 Context的角度看,状态转换是原子的—只需重新绑定一个变量(即Context的State对象变量),而无需为多个变量赋值

State对象可被共享

如果State对象没有实例变量—即它们表示的状态完全以它们的类型来编码—那么各Context对象可以共享一个State对象。当状态以这种方式被共享时, 它们必然是没有内部状态, 只有行为的轻量级对象。

缺点

导致较多的ConcreteState子类。

适用场景

当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式。

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

参考

《Head First 设计模式》

http://blog.csdn.net/hguisu/article/details/7557252

博客地址: http://www.cnblogs.com/wolf-sun/
博客版权: 本文以学习、研究和分享为主,欢迎转载,但必须在文章页面明显位置给出原文连接。
如果文中有不妥或者错误的地方还望高手的你指出,以免误人子弟。如果觉得本文对你有所帮助不如【推荐】一下!如果你有更好的建议,不如留言一起讨论,共同进步!
再次感谢您耐心的读完本篇文章。

转载:http://www.cnblogs.com/wolf-sun/p/3661043.html
目录
相关文章
|
1月前
|
设计模式 Java Go
【再谈设计模式】状态模式~对象行为的状态驱动者
状态模式属于行为型设计模式。它将对象的行为封装在不同的状态类中,使得对象在不同的状态下表现出不同的行为。上下文(Context):这是一个包含状态对象的类,它定义了客户感兴趣的接口,并维护一个具体状态对象的引用。上下文将操作委托给当前的状态对象来处理。抽象状态(State):这是一个抽象类或者接口,它定义了一个特定状态下的行为接口。所有具体的状态类都实现这个接口。具体状态(Concrete State):这些是实现抽象状态接口的类,每个具体状态类实现了与该状态相关的行为。
73 18
|
6月前
|
设计模式 Java 测试技术
Java设计模式-状态模式(18)
Java设计模式-状态模式(18)
|
7月前
|
设计模式 网络协议 Java
【十五】设计模式~~~行为型模式~~~状态模式(Java)
文章详细介绍了状态模式(State Pattern),这是一种对象行为型模式,用于处理对象在其内部状态改变时的行为变化。文中通过案例分析,如银行账户状态管理和屏幕放大镜工具,展示了状态模式的应用场景和设计方法。文章阐述了状态模式的动机、定义、结构、优点、缺点以及适用情况,并提供了Java代码实现和测试结果。状态模式通过将对象的状态和行为封装在独立的状态类中,提高了系统的可扩展性和可维护性。
【十五】设计模式~~~行为型模式~~~状态模式(Java)
|
8月前
|
设计模式 JavaScript Go
js设计模式【详解】—— 状态模式
js设计模式【详解】—— 状态模式
125 7
|
8月前
|
设计模式 Java
Head First设计模式学习笔记
Head First设计模式学习笔记
|
9月前
|
设计模式
状态模式-大话设计模式
状态模式-大话设计模式
|
9月前
|
设计模式 存储
行为设计模式之状态模式
行为设计模式之状态模式
|
10月前
|
设计模式 Go
[设计模式 Go实现] 行为型~状态模式
[设计模式 Go实现] 行为型~状态模式
|
10月前
|
设计模式 JavaScript Java
[设计模式Java实现附plantuml源码~行为型] 对象状态及其转换——状态模式
[设计模式Java实现附plantuml源码~行为型] 对象状态及其转换——状态模式
101 0
|
3月前
|
设计模式 前端开发 搜索推荐
前端必须掌握的设计模式——模板模式
模板模式(Template Pattern)是一种行为型设计模式,父类定义固定流程和步骤顺序,子类通过继承并重写特定方法实现具体步骤。适用于具有固定结构或流程的场景,如组装汽车、包装礼物等。举例来说,公司年会节目征集时,蜘蛛侠定义了歌曲的四个步骤:前奏、主歌、副歌、结尾。金刚狼和绿巨人根据此模板设计各自的表演内容。通过抽象类定义通用逻辑,子类实现个性化行为,从而减少重复代码。模板模式还支持钩子方法,允许跳过某些步骤,增加灵活性。
174 11