`

状态模式 state

 
阅读更多
状态模式:允许对象的内部状态改变时改变它的行为,对想看起来好像修改了它的类。
      状态模式和策略模式比较相似(类图就完全一样),都是A对象关联B对象,而B是可以更换的,A对象的功能随着B的具体实现的改变而改变。策略模式一般都是B对象在A对象所在的上下文中改变。而状态模式则是在B对象(状态对象)完成一定的操作在B对象内部吧A关联的B的具体实现更换。对于A来说就像是一个封闭的机器,内部实现了一套状态转换的流程而无需外界的干涉。
下面是一个糖果机的例子。
先讨论四种状态,有25分钱,没有25分钱,售出,售罄。然后扩展一个赢家状态。
基本方法有 插入硬币,退出货币,摇动手柄,发出糖果。
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> class GumballMachine
    
{
        
int count = 5;

        
public int Count
        
{
            
get return count; }
            
set { count = value; }
        }

        
public State state;
        
public GumballMachine()
        
{
            state 
= new NoQuarterState(this);
        }

        
public void InsertQuarter()
        
{
            state.InsertQuarter();
        }

        
public void EjectQuarter()
        
{
            state.EjectQuarter();
        }

        
public void TrunCrank()
        
{
            state.TrunCrank();
        }

        
public void Dispense()
        
{
            state.Dispense();
        }

    }

糖果机的行为都委托给状态对象去实现。随着状态(对象)的改变糖果机的行为也会改变,也就是说糖果机在不同的状态下表现出不同的行为。

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> abstract class State
    
{
       
protected GumballMachine gumballmachine;
        
public virtual void InsertQuarter()
        
{
        }

        
public  virtual void EjectQuarter()
        
{
            Console.WriteLine(
"\t没糖了,钱退给你!");
        }

        
public virtual void TrunCrank()
        
{
        }

        
public virtual void Dispense()
        
{
        }

    }
四个方法在状态基类中都提供默认实现。

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> class NoQuarterState:State
    
{
        
public NoQuarterState( GumballMachine gumballmachine)
        
{
            
this.gumballmachine = gumballmachine;
        }

       
        
public override void InsertQuarter()
        
{
            
if (gumballmachine.Count < 1)
            
{
                gumballmachine.state 
= new SoldOutState(gumballmachine);
                gumballmachine.state.EjectQuarter();
            }

            
else
            
{
                gumballmachine.state 
= new HasQuarterState(gumballmachine);
            }

        }

    }
    在没有25分钱的状态下,插入硬币,如果有糖果则糖果机变成有25分钱状态。没有糖果则变成售罄状态然后把钱退回。(为什么售罄状态不在首先就确定而要插入硬币后才确定呢(1?))
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> class HasQuarterState : State
    
{
        Random ran 
= new Random();
        
public HasQuarterState(GumballMachine gumballmachine)
        
{
            
this.gumballmachine = gumballmachine;
        }

        
public override void TrunCrank()
        
{

            
if (gumballmachine.Count > 0)
            
{
                
if (ran.Next(10== 5)
                
{
                    gumballmachine.state 
= new WinnerState(gumballmachine);
                }

                
else
                
{
                    gumballmachine.state 
= new SoldState(gumballmachine);
                }

                gumballmachine.state.Dispense();
            }

            
else
            
{
                gumballmachine.state 
= new SoldOutState(gumballmachine);
                gumballmachine.state.EjectQuarter();
            }


        }


    }
有25分钱状态下转动手柄,马上变成售出状态。
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> class SoldOutState:State
    
{
        
public SoldOutState(GumballMachine gumballmachine)
        
{
            
this.gumballmachine = gumballmachine;
        }

        
public override void InsertQuarter()
        
{
            EjectQuarter();
        }

    }
售罄状态,插入钱之后马上退出钱。和初始状态下没有糖果的糖果机保持一致。
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> public SoldState(GumballMachine gumballmachine)
        
{
            
this.gumballmachine = gumballmachine;
        }

        
public override void Dispense()
        
{
            Console.WriteLine(
"Give you a candy!");
            
if (gumballmachine.Count > 0)
            
{
                gumballmachine.Count
--
                gumballmachine.state 
= new NoQuarterState(gumballmachine);
            }

            
else
            
{
                gumballmachine.state 
= new SoldOutState(gumballmachine);
            }

        }

    }
售出状态自然就要发放糖果咯。
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> class WinnerState : State
    
{
        
public WinnerState( GumballMachine gumballmachine)
        
{
            
this.gumballmachine = gumballmachine;
        }

        
public override void Dispense()
        
{
            Console.WriteLine(
"you are winner");

                
for (int i = 0; i < 2; i++)
                
{
                    
if (gumballmachine.Count > 0)
                    
{
                        Console.WriteLine(
"Give you a candy!");
                        gumballmachine.Count
--;
                    }

                }



                gumballmachine.state 
= new NoQuarterState(gumballmachine);
        }

    }
为了增加糖果机的趣味性,运营商希望增加一个功能,顾客有1/10的机会获得两颗糖果。那么我们很轻松的扩展一个状态:赢家状态。
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> static void Main(string[] args)
        
{
            GumballMachine gum 
= new GumballMachine();
            
for (int i = 0; i < 8; i++)
            
{
                gum.InsertQuarter();
                gum.TrunCrank();
                Console.WriteLine(gum.Count);
            }

            Console.ReadLine();
        }
测试代码。

(1?)上面已经提到糖果机内部实现了一套状态转换的流程而无需外界的干涉,那么售罄状态自然也会从某一状态而来,又转向某一状态而去。具体来说就是在售出状态下发放糖果后马上检查还有没有糖果,没有糖果则转到售罄状态,难道这不是售罄状态的所有“来路”吗?在正常状况下自然是这样。我们在初始化糖果机的时候会给出一个初始状态--没有25分钱状态(貌似这样还算比较合理)。但是如果糖果机中一开始就没有糖果那他本身又是一种售罄状态。同时它还没有钱嘛。所以就在插入硬币的时候判断咯,没有糖果就转到售罄然后退出钱。

这里的状态才看起来是有点犯晕。因为这些状态不是互斥的状态。也就是说这里的状态划分不是一种不重不漏的方式。在有钱状态下同时还可以是售罄,没钱也可以是售罄。有25分钱,没有25分钱,表示有没有钱,售罄,表示还有没有糖果,售出表示糖果机的正要进行的动作。表示3类东西的状态竟然放在一起来相互转换 orz,orz。居然还算perfect。懂得模式很重要
分享到:
评论

相关推荐

    状态模式 State Pattern

    ### 状态模式(State Pattern) #### 概念与定义 状态模式是一种行为设计模式,它允许对象在其内部状态改变时改变其行为,使对象看起来像是修改了它的类。该模式通过引入一个代表各种状态的类以及一个行为随着这些...

    设计模式之状态模式State

    状态模式通常包含三个主要角色:Context(上下文)、State(抽象状态)和ConcreteState(具体状态)。 上下文是拥有状态的对象,它定义了与该状态相关的接口,并负责在适当的时候将请求委托给相应的状态对象处理。...

    每天感悟总结-状态模式State

    2009-03-10模式State:一个事件(消息)引起环境或数据的变化,可能导致状态变化,于是处理流程改变,这里的状态是把处理流程分成了很多阶段,通过状态机来根据传来的事件(消息)引发状态转换,管理状态属性和状态行为,...

    设计模式C++学习之状态模式(State)

    状态模式是一种行为设计模式,它允许对象在内部状态改变时改变其行为,对象看起来似乎修改了它的类。这种模式常用于处理对象的状态变化,并且使代码结构清晰,易于维护。 在C++中,状态模式通常包含以下几个关键...

    设计模式之状态模式(State)

    状态模式是一种行为设计模式,它使对象能够在内部状态改变时改变其行为,看起来好像改变了它的类。这种模式常用于处理对象在不同状态下表现各异的情况,避免了复杂的条件语句,提高了代码的可读性和可维护性。 在...

    Android的状态机模式StateMachine与State

    在博文《Android的状态机模式StateMachine与State》中,作者可能会详细介绍如何创建和使用这两种组件。通常,状态机的实现会涉及到以下步骤: 1. **定义状态接口或抽象类**:创建一个State接口或抽象类,其中包含...

    设计模式之状态模式(State Pattern)

    状态模式是一种行为设计模式,它使你能在运行时改变对象的行为。在状态模式中,一个对象的状态变化会导致其行为的变化,这种变化不是通过改变对象的类来实现的,而是通过改变对象的状态。这个模式的核心是封装可能...

    Head First 设计模式 (十) 状态模式(State pattern) C++实现

    状态模式是一种行为设计模式,它允许对象在内部状态改变时改变其行为,对象看起来似乎修改了它的类。这种模式常用于处理对象的状态变化,并且根据不同的状态,对象的行为也相应地变化。在C++中实现状态模式,我们...

    JackChan1999#Java-Degisn-Patterns#状态模式-State Pattern1

    状态模式-State Pattern状态模式-State Pattern【学习难度:,使用频率:】状态模式-State Pattern处理对象的多种状态及其相互

    《设计模式》实战---状态模式(State Pattern)

    在《设计模式》实战---状态模式(State Pattern)这篇文章中,作者可能详细探讨了以下关键点: 1. **模式定义**:状态模式允许对象在内部状态改变时改变其行为,对象看起来好像修改了它的类。这通过将每个状态封装...

    设计模式 - 状态模式(C++实例)

    在C++中实现状态模式,我们通常会定义一个抽象状态类(State),它声明了所有可能的状态行为。然后,创建一系列具体状态类(ConcreteState)来实现这些行为。每个具体状态类代表一种特定的状态,并且在内部维护当前...

    状态模式(State Pattern)是一种行为设计模式

    状态模式(State Pattern)是一种行为设计模式,它允许对象在内部状态改变时改变其行为,对象看起来似乎修改了它的类。这种模式将一个对象的行为分解为各个独立的状态,并且每个状态都封装在自己的类中,使得对象在...

    设计模式State模式源码

    State模式在实际使用中比较多,适合"状态的切换".因为我们经常会使用If elseif else 进行状态切换, 如果针对状态的这样判断切换反复出现,我们就要联想到是否可以采取State模式了. 不只是根据状态,也有根据属性.如果...

    状态模式代码示例

    在提供的压缩包`state.zip`中,很可能包含一个简单的状态模式实现,可能包括`Context`、`AbstractState`和几个`ConcreteState`类。这些类的结构可能是这样的: ```java // Context public class Context { ...

    C#面向对象设计模式纵横谈(22):(行为型模式) State 状态模式

    标题和描述均提到了"C#面向对象设计模式"中的State状态模式,这表明文章的核心内容是围绕State模式在C#编程语言中的应用展开。State模式是一种行为设计模式,旨在允许对象在其内部状态改变时,其行为也能相应地改变...

    c++状态模式

    状态模式是一种行为设计模式,它允许对象在内部状态改变时改变其行为,对象看起来似乎修改了它的类。在C++中,状态模式通常通过定义一系列的类来表示各种状态,并用一个上下文类来管理这些状态的切换。下面将详细...

    管理订单状态,该上状态机吗?轻量级状态机COLA StateMachine保姆级入门教程.doc

    在订单状态管理中,状态机模式是一种常用的解决方案,但是在实际项目中,状态机的使用率并没有想象中那么高。笔者在电商领域进行后端开发时,发现了状态机的重要性,但是在使用 Spring StateMachine 时,发现了它的...

    java 设计模式之状态模式

    状态模式是一种行为设计模式,它允许对象在内部状态改变时改变其行为,看起来好像对象改变了它的类。在Java中,状态模式通常通过定义不同的状态类和一个上下文类来实现,其中上下文类持有状态对象并调用其方法来响应...

    设计模式:状态模式TCPConnection案例

    状态模式是一种行为设计模式,它使你能在运行时改变对象的行为。在TCP连接中,状态模式的应用尤为常见,因为TCP连接在不同的阶段会有不同的行为,比如建立连接、数据传输、断开连接等。下面我们将详细探讨这个模式...

Global site tag (gtag.js) - Google Analytics