原文 第20章 状态模式(State Pattern)

状态模式

 概述:

 

当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。

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

意图:

 

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

结构图:

 

   

 

 

      举例:

       

             在日常生活中最为熟悉的点灯开关,按一下开灯,在按一下关灯,我们用代码来实现这种效果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
    /// <summary>
    /// 它定义了客户程序需要的接口并维护一个具体状态角色的实例,将与状态相关的操作委托给当前的Concrete State对象来处理。
    /// </summary>
  public   class Context
    {
 
        private AbstractState _state;
        public AbstractState State
        {
            get{return _state;}
            set { _state=value;}
        }
        //初始状态
        public Context(AbstractState state)
        {
            _state = state;
        }
        //按下开关
        public void Press()
        {
            //传入当前的状态
            _state.Press(this);
        }
 
    }
    /// <summary>
    /// 抽象状态(State):定义一个接口以封装使用上下文环境的的一个特定状态相关的行为。
    /// </summary>
  public  abstract class  AbstractState
   {
       //按下动作
       public  abstract void Press(Context context);
     
   }
    /// <summary>
   /// 具体状态(Concrete State):实现抽象状态定义的接口。开灯
    /// </summary>
   public class ConcreteStateOn:AbstractState
   {
 
       public override void Press(Context context)
       {
           Console.WriteLine("开灯");
           //开灯了 那么久得把下一个动作设置成关灯
           context.State = new ConcreteStateOff();
            
       }
   }
   /// <summary>
   /// 具体状态(Concrete State):实现抽象状态定义的接口。关灯
   /// </summary>
   public class ConcreteStateOff : AbstractState
   {
 
       public override void Press(Context context)
       {
           Console.WriteLine("关灯");
           //关灯了就得把下一个动作设置成开灯
           context.State = new ConcreteStateOn();
       }
   }

客户端调用:

1
2
3
4
5
6
7
8
9
10
11
    class Program
    {
        static void Main(string[] args)
        {
            //灯处于关闭状态 第一次是开灯动作
            Context context = new Context(new ConcreteStateOn());
            context.Press();//按下开关
            context.Press();//在按下开关
            Console.ReadLine();
        }
    }

 适用场景:

1.一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为。

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

设计模式系列文章入口:http://www.diyibk.com/post/39.html

第20章 状态模式(State Pattern)的更多相关文章

  1. 二十四种设计模式:状态模式(State Pattern)

    状态模式(State Pattern) 介绍允许一个对象在其内部状态改变时改变它的行为.对象看起来似乎修改了它所属的类. 示例有一个Message实体类,对它的操作有Insert()和Get()方法, ...

  2. 乐在其中设计模式(C#) - 状态模式(State Pattern)

    原文:乐在其中设计模式(C#) - 状态模式(State Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 状态模式(State Pattern) 作者:webabcd 介绍 允 ...

  3. 状态模式-State Pattern(Java实现)

    状态模式-State Pattern 在状态模式(State Pattern)中,类的行为是基于它的状态改变的.当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类. State接口 ...

  4. [设计模式] 20 状态模式 State Pattern

    在GOF的<设计模式:可复用面向对象软件的基础>一书中对状态模式是这样说的:允许一个对象在其内部状态改变时改变它的行为.对象看起来似乎修改了它的类.状态模式的重点在于状态转换,很多时候,对 ...

  5. 设计模式(十二):通过ATM取款机来认识“状态模式”(State Pattern)

    说到状态模式,如果你看过之前发布的重构系列的文章中的<代码重构(六):代码重构完整案例>这篇博客的话,那么你应该对“状态模式”并不陌生,因为我们之前使用到了状态模式进行重构.上一篇博客我们 ...

  6. 十一个行为模式之状态模式(State Pattern)

    定义: 当一个对象有多个状态,并且在每个状态下有不同的行为,可以使用状态模式来在其内部改变状态时改变其行为,而客户端不会察觉状态的改变,仍使用同样的方法或接口与对象进行交互. 结构图: Context ...

  7. 【UE4 设计模式】状态模式 State Pattern

    概述 描述 允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类. 其别名为状态对象(Objects for States),状态模式是一种对象行为型模式. 有限状态机(FSMs) ...

  8. 状态模式(State Pattern)

    当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类. 状态模式主要解决的是当控制一个对象状态的条件表达式过于复杂时的情况.把状态的判断逻辑转移到表示不同状态的一系列类中,可以把复杂 ...

  9. C#设计模式——状态模式(State Pattern)

    一.概述在面向对象软件设计时,常常碰到某一个对象由于状态的不同而有不同的行为.如果用if else或是switch case等方法处理,对象操作及对象的状态就耦合在一起,碰到复杂的情况就会造成代码结构 ...

随机推荐

  1. hdu1964之插头DP求最优值

    Pipes Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Subm ...

  2. Java没有源代码的同步集合~

    存档~~~~ Synchronized,volatile,lock 锁定->[就绪队列,阻塞队列] 第一个是jvm等级达到. 与volatile所不同的是,后者不能从工作存储器写回到主存储器. ...

  3. 读书时间《JavaScript高级程序设计》三:函数,闭包,作用域

    上一次看了第6章,面向对象.这里接着看第7章. 第7章:函数表达式 定义函数有两种方式:函数声明.函数表达式 //函数声明 function functionName(arg0,arg1,arg2){ ...

  4. 【转】ubuntu终端方向键不能用(主机名不显示)问题的解决

    sudo gedit /etc/passwd 在/etc/passwd中修改该用户对应的shell:/bin/sh改为/bin/bash即可解决该问题 来自:http://blog.csdn.net/ ...

  5. ajaxFileUpload+struts2多文件上传(动态添加文件上传框)

    上一篇文章http://blog.csdn.net/itmyhome1990/article/details/36396291介绍了ajaxfileupload实现多文件上传, 但仅仅是固定的文件个数 ...

  6. ListView分页显示

    出在:http://blog.csdn.net/tu_bingbing/article/details/13275107         当ListView要显示的数据过多时,为了更快的响应用户,这个 ...

  7. BestCoder Round #16

    BestCoder Round #16 题目链接 这场挫掉了,3挂2,都是非常sb的错误 23333 QAQ A:每一个数字.左边个数乘上右边个数,就是能够组成的区间个数,然后乘的过程注意取模不然会爆 ...

  8. FastReport的再次使用

    FastReport.Net是一款功能齐全的报表分析解决方案. 前两年工作的时候就是使用FastReport进行报表设计,只是当时使用的时候都是调用别人写好的帮助类,直接调用即可.当时让人觉得不明觉厉 ...

  9. [LeetCode] Combinations [38]

    称号 Given two integers n and k, return all possible combinations of k numbers out of 1 ... n. For exa ...

  10. HDU 1710-Binary Tree Traversals(二进制重建)

    Binary Tree Traversals Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/O ...