步步为营 .NET 设计模式学习笔记 八、State(状态模式)
2011-04-12 00:55
811 查看
概述
意图
状态模式主要解决的是当控制一个对象状态装换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类中,可以把复杂的判断逻辑简单化。
当一个对象行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式了。
<DesignPattern>State模式结构图
示例关系图
描述:一年有12个月,有四个季度,每个月都有一属于一个季度,根据月份得到这个季度的天气信息.可以用State模式来实现.
关系图:
代码设计:
先创建接口IQuarter.cs:
再创建Quarter.cs:
再创建Summer.cs:
再创建Autumn.cs:
再创建Winter.cs:
再创建MonthInfo.cs:
再调用它:
结果如图:
何时采用
3.从代码角度来说,如果一个类有多种状态,并且在类内部通过的条件语句判断的类状态来实现不同行为时候可以把这些行为单独封装为状态类。
4.从应用角度来说,如果一个对象有多种状态,如果希望把对象状态的转化以及由不同状态产生的行为交给具体的状态类去做,那么可以考虑状态模式。
效果及实现要点
1.在环境角色中拥有状态角色的实例。
2.在状态角色中拥有环境角色的实例用于在具体状态中修改环境角色的状态。
3.状态对象之间的依赖可以通过加载外部配置的转化规则表等方法来消除。
4.状态模式和策略模式的主要区别是,前者的行为实现方式是由条件决定的,并且应当能不在客户端干预的情况下自己迁移到合适的状态,而后者的行为实现方式是由客户端选择的,并且能随时替换。
总结
1.优点:避免了为判断状态而产生的巨大的if或case语句。将对象行为交给状态类维护后,对于上层程序而言,仅需要维护状态之间的转换规则。
2.缺点:会导致某些系统有过多的具体状态类。
3.过多的状态对象可能会增加系统负担,可以考虑把各种状态角色实现为无状态对象的享元,需要保存的额外状态由环境角色进行统一管理和处理。
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它所属的类。
意图
状态模式主要解决的是当控制一个对象状态装换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类中,可以把复杂的判断逻辑简单化。
当一个对象行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式了。
<DesignPattern>State模式结构图
示例关系图
描述:一年有12个月,有四个季度,每个月都有一属于一个季度,根据月份得到这个季度的天气信息.可以用State模式来实现.
关系图:
代码设计:
先创建接口IQuarter.cs:
01 | public interface IQuarter |
02 | { |
03 | ///<summary> |
04 | ///通过月份获取季度 |
05 | ///</summary> |
06 | ///<paramname="Month"></param> |
07 | ///<returns></returns> |
08 | QuarterGetQuarter(); |
09 |
10 | ///<summary> |
11 | ///气候条件 |
12 | ///</summary> |
13 | ///<returns></returns> |
14 | string Climate(); |
15 | } |
01 | public abstract class Quarter:IQuarter |
02 | { |
03 | private int _Month=0; |
04 | public int Month |
05 | { |
06 | get |
07 | { |
08 | return _Month; |
09 | } |
10 | set |
11 | { |
12 | _Month=value; |
13 | } |
14 | } |
15 | public Quarter( int month) |
16 | { |
17 | this .Month=month; |
18 | } |
19 |
20 | #regionIQuarter成员 |
21 |
22 | public abstract QuarterGetQuarter(); |
23 |
24 | public abstract string Climate(); |
25 |
26 | #endregion |
27 |
28 |
29 | } |
1 | 再创建Spring.cs: |
01 | public class Spring:Quarter |
02 | { |
03 |
04 | private Quarterquarter; |
05 | public override string Climate() |
06 | { |
07 | return "春风宜人,鸟语花香,正是旅游的好季节。" ; |
08 | } |
09 |
10 | public override QuarterGetQuarter() |
11 | { |
12 | if (Month>3) |
13 | { |
14 | quarter= new Summer(Month); |
15 | return quarter.GetQuarter(); |
16 | } |
17 | return new Spring(Month); |
18 | } |
19 | public Spring( int month): base (month) |
20 | { |
21 |
22 | } |
23 | } |
01 | public class Summer:Quarter |
02 | { |
03 | private Quarterquarter; |
04 | public override string Climate() |
05 | { |
06 | return "夏季天气炎热,酷暑难熬." ; |
07 | } |
08 | public override QuarterGetQuarter() |
09 | { |
10 | if (Month<4) |
11 | { |
12 | quarter= new Spring(Month); |
13 | return quarter.GetQuarter(); |
14 | } |
15 | if (Month>6) |
16 | { |
17 | quarter= new Autumn(Month); |
18 | return quarter.GetQuarter(); |
19 | } |
20 |
21 | return new Summer( this .Month); |
22 |
23 | } |
24 | public Summer( int month): base (month) |
25 | { |
26 |
27 | } |
28 | } |
01 | public class Autumn:Quarter |
02 | { |
03 | private Quarterquarter; |
04 | public override string Climate() |
05 | { |
06 | return "秋高气爽." ; |
07 | } |
08 | public override QuarterGetQuarter() |
09 | { |
10 | if (Month<7) |
11 | { |
12 | quarter= new Summer(Month); |
13 | return quarter.GetQuarter(); |
14 | } |
15 | if (Month>9) |
16 | { |
17 | quarter= new Winter(Month); |
18 | return quarter.GetQuarter(); |
19 | } |
20 | return new Autumn(Month); |
21 |
22 | } |
23 | public Autumn( int month): base (month) |
24 | { |
25 |
26 | } |
27 |
28 | } |
01 | public class Winter:Quarter |
02 | { |
03 | private Quarterquarter; |
04 | public override string Climate() |
05 | { |
06 | return "冬天风寒,空气干燥." ; |
07 | } |
08 | public override QuarterGetQuarter() |
09 | { |
10 |
11 | if (Month<10) |
12 | { |
13 | return quarter.GetQuarter(); |
14 | quarter= new Autumn(Month); |
15 | } |
16 | return new Winter(Month); |
17 |
18 | } |
19 | public Winter( int month): base (month) |
20 | { |
21 |
22 | } |
23 | } |
01 | public class MonthInfo |
02 | { |
03 | private Quarterquarter; |
04 | public MonthInfo( int month) |
05 | { |
06 | //初始化为春季 |
07 | quarter= new Spring(month); |
08 | quarter=quarter.GetQuarter(); |
09 | } |
10 | public string ShowInfo() |
11 | { |
12 | if (CheckMonthInfo()) |
13 | { |
14 | return GetQuarterClimate(); |
15 | } |
16 | else |
17 | { |
18 | return GetError(); |
19 | } |
20 | } |
21 | private string GetQuarterClimate() |
22 | { |
23 | return string .Format( "月份是:{0}月份,气候是:{1}" , this .quarter.Month.ToString(), this .quarter.Climate()); |
24 | } |
25 | private string GetError() |
26 | { |
27 | return string .Format( "月份是:{0},是一个错误的信息." , this .quarter.Month.ToString()); |
28 | } |
29 | private bool CheckMonthInfo() |
30 | { |
31 | if ( this .quarter.Month>12|| this .quarter.Month<1) |
32 | { |
33 | return false ; |
34 | } |
35 | return true ; |
36 | } |
37 | } |
01 | public partial class Run:Form |
02 | { |
03 | public Run() |
04 | { |
05 | InitializeComponent(); |
06 | } |
07 |
08 | private void btnRun_Click( object sender,EventArgse) |
09 | { |
10 | for ( int i=0;i<15;i++) |
11 | { |
12 | MonthInfomonthInfo= new MonthInfo(i); |
13 | rtbResult.AppendText(monthInfo.ShowInfo()+ "\n" ); |
14 | } |
15 | } |
16 | } |
1 |
1.一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为。 2.一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。这个状态通常用一个或多个枚举常量表示。通常,有多个操作包含这
一相同的条件结构。tate模式将每一个条件分支放入一个独立的类中。这使得你可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不
依赖于其他对象而独立变化。
3.从代码角度来说,如果一个类有多种状态,并且在类内部通过的条件语句判断的类状态来实现不同行为时候可以把这些行为单独封装为状态类。
4.从应用角度来说,如果一个对象有多种状态,如果希望把对象状态的转化以及由不同状态产生的行为交给具体的状态类去做,那么可以考虑状态模式。
效果及实现要点
1.在环境角色中拥有状态角色的实例。
2.在状态角色中拥有环境角色的实例用于在具体状态中修改环境角色的状态。
3.状态对象之间的依赖可以通过加载外部配置的转化规则表等方法来消除。
4.状态模式和策略模式的主要区别是,前者的行为实现方式是由条件决定的,并且应当能不在客户端干预的情况下自己迁移到合适的状态,而后者的行为实现方式是由客户端选择的,并且能随时替换。
总结
1.优点:避免了为判断状态而产生的巨大的if或case语句。将对象行为交给状态类维护后,对于上层程序而言,仅需要维护状态之间的转换规则。
2.缺点:会导致某些系统有过多的具体状态类。
3.过多的状态对象可能会增加系统负担,可以考虑把各种状态角色实现为无状态对象的享元,需要保存的额外状态由环境角色进行统一管理和处理。
相关文章推荐
- 步步为营 .NET 设计模式学习笔记 八、State(状态模式)
- 步步为营 .NET 设计模式学习笔记 八、State(状态模式)
- 设计模式C++学习笔记之十九(State状态模式)
- 步步为营 .NET 设计模式学习笔记 二十三、Interpreter(解释器模式)
- 步步为营 .NET 设计模式学习笔记 四、Singleton(单例模式)
- 步步为营 .NET 设计模式学习笔记 五、Prototype(原型模式)
- 步步为营 .NET 设计模式学习笔记 十二、Observer (观察者模式)
- 设计模式C++学习笔记之十九(State状态模式)
- 设计模式C++学习笔记之十九(State状态模式)
- 步步为营 .NET 设计模式学习笔记 十四、Decorator(装饰模式)
- 步步为营 .NET 设计模式学习笔记 十三、Bridge (桥接模式)
- 步步为营 .NET 设计模式学习笔记 二十二、Memento(备望录模式)
- 【设计模式】学习笔记14:状态模式(State)
- 【设计模式学习笔记二十一】【行为模式】【状态模式(State)】
- 设计模式学习笔记——State状态模式
- 步步为营 .NET 设计模式学习笔记 十四、Decorator(装饰模式)
- 步步为营 .NET 设计模式学习笔记 四、Singleton(单例模式)
- 步步为营 .NET 设计模式学习笔记 七、Proxy(代理模式
- 步步为营 .NET 设计模式学习笔记 十五、Composite(组合模式)
- 设计模式学习笔记——State状态模式