[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

时间: 2024-10-28 02:17:40

[Head First设计模式]生活中学设计模式——状态模式的相关文章

[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设计模式]一个人的平安夜--单例模式 [Head First设计模式]抢票中的设计模式--代理模式 [Head First设计模式]面向对象的3特征5原则 [Head First设计模式]鸭子

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

系列文章 [Head First设计模式]山西面馆中的设计模式--装饰者模式 [Head First设计模式]山西面馆中的设计模式--观察者模式 [Head First设计模式]山西面馆中的设计模式--建造者模式 [Head First设计模式]饺子馆(冬至)中的设计模式--工厂模式 [Head First设计模式]一个人的平安夜--单例模式 [Head First设计模式]抢票中的设计模式--代理模式 [Head First设计模式]面向对象的3特征5原则 [Head First设计模式]鸭子

传统设计模式(十)状态模式

谈到状态模式我们在这里所谈论的是一个通用的技巧:如何对对象内的状态建模----通过创建一个实例变量来持有状态值,并在方法内书写条件代码来处理不同状态.我们要把一个状态的所有行为放在一个类中.这么一来我们将行为局部化了,并使得事情更容易改变和理解. 虫子还是拿订单系统来说事了 /// <summary> /// 状态接口 /// </summary> public interface SimpleState { //检查购物车 void CheckCart(); //检查账号 voi

详解C++设计模式编程中对状态模式的运用_C 语言

状态模式:当一个对象的内在状态发生变化时,允许改变其行为,这个对象看来像是改变了其类. 状态模式与策略模式的UML图几乎一模一样,下面列举了两者的不同: (1)可以通过环境类状态的个数来决定是使用策略模式还是状态模式. (2)策略模式的环境类自己选择一个具体策略类,具体策略类无须关心环境类:而状态模式的环境类由于外在因素需要放进一个具体状态中,以便通过其方法实现状态的切换,因此环境类和状态类之间存在一种双向的关联关系. (3)使用策略模式时,客户端需要知道所选的具体策略是哪一个,而使用状态模式时

实例讲解C++设计模式编程中State状态模式的运用场景_C 语言

State模式允许一个对象在其内部状态改变时改变它的行为.对象看起来似乎修改了它的类. 在面向对象系统的开发和设计过程,经常会遇到一种情况就是需求变更(Requirement Changing),经常我们做好的一个设计.实现了一个系统原型,咱们的客户又会有了新的需求.我们又因此不得不去修改已有的设计,最常见就是解决方案就是给已经设计.实现好的类添加新的方法去实现客户新的需求,这样就陷入了设计变更的梦魇:不停地打补丁,其带来的后果就是设计根本就不可能封闭.编译永远都是整个系统代码. 访问者模式则提

策略模式的孪生兄弟——对状态模式的深度复习总结

俗话说,自己写的代码,6个月后也是别人的代码--复习!复习!复习!涉及的总结知识点如下: 和策略模式的比较 状态模式概念和例子 应用场景 责任链模式和状态模式对比 一种代码优化的思路 java.util.Iterator里也有状态模式的影子 状态模式的优缺点 有限状态机及其应用 前面有总结--策略模式,之前早就觉得策略和状态设计模式有一些相似-- 接口的常用用法都有什么?策略设计模式复习总结 我知道策略模式是对象的行为模式,其实就是对一系列级别平等的算法的封装,它不关心算法实现,让客户端去动态的

详解state状态模式及在C++设计模式编程中的使用实例_C 语言

每个人.事物在不同的状态下会有不同表现(动作),而一个状态又会在不同的表现下转移到下一个不同的状态(State).最简单的一个生活中的例子就是:地铁入口处,如果你放入正确的地铁票,门就会打开让你通过.在出口处也是验票,如果正确你就可以 ok,否则就不让你通过(如果你动作野蛮,或许会有报警(Alarm),:)). 有限状态自动机(FSM)也是一个典型的状态不同,对输入有不同的响应(状态转移). 通常我们在实现这类系统会使用到很多的 Switch/Case 语句,Case 某种状态,发生什么动作,C

设计模式(8)-状态模式(关注状态之间的变化)

状态模式(State Pattern)是设计模式的一种,属于行为模式. 定义(源于Design Pattern):当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类. 状态模式主要解决的是当控制一个对象状态的条件表达式过于复杂时的情况.把状态的判断逻辑转移到表示不同状态的一系列类中,可以把复杂的判断逻辑简化. 意图:允许一个对象在其内部状态改变时改变它的行为 适用场景: 1.一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为. 2.一个操作中含有庞大的多分