zoukankan      html  css  js  c++  java
  • 设计模式 笔记 状态模式 State


    //---------------------------15/04/28----------------------------


    //State  状态模式----对象行为型模式


    /*

        1:意图:

            允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。

        2:别名:

            状态对象(Objects for States)

        3:动机:

        4:使用性:

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

            2>一个操作中含有庞大的多分支条件语句,且这些分支依赖于该对象的状态。这个状态通常用一个或

              多个枚举常量表示。

        5:结构:

            Context

            state---------------------------------->State:

            Request()                               Handle()

            {state->Handle()}                          |

                                            ----------------------

                                            |                     |

                                        ConcreteStateA:     ConcreteStateB:

                                        Handle()            Handle()

        6:参与者:

            1>Context

                1)定义客户感兴趣的接口。

                2)维护一个ConcreteState子类的实例,这个实例定义当前状态。

            2>State

                定义一个接口以封装与Context的一个特定状态相关的行为。

            3>ConcreteState

                每一个子类实现一个与Context的一个状态相关的行为。

        7:协作:

            1>Context将与状态相关的请求委托给当前的ConcreteState对象处理。

            2>Context可将自身作为一个参数传递给处理该请求的状态对象。这使得状态对象在必要时可访问Context

            3>Context是客户使用的主要接口。客户可用状态对象来配置一个Context,一旦一个Context配置完毕,

              它的客户不再需要直接与状态对象打交道。

            4>ContextConcreteState子类都可决定哪个状态是另外哪一个的后继者,以及是在何种条件下进行状态转换。

        8:效果:

            1>它将与特定状态相关的行为局部话,并且将不用状态的行为分割开来:

                把一些需要使用大量case的语句分割到不同的状态子类中去,能使结构看起来更加清晰,同时能很容易增加

                和转换一个状态。

            2>使得状态转换显式化:

                Context看来,状态转换是原子的--只需要重新绑定一个State变量。这样可以保证内部状态一致。

            3>State对象可被共享:

                如果State对象没有实例变量,就可被很容易共享,因为这样他们只有外部状态,而没有内部状态。

        9:实现:

            1>谁定义状态转换:

                1)Context来进行转换:这需要转换是遵循固定准则的。

                2)State自身指定后继者状态,以及何时转换:这样更佳灵活,但是State子类就必须拥有其他子类的信息

                  这样就产生了依赖,也就是耦合变大。

            2>创建和销毁State对象:

                1)仅当需要State对象时才创建它们并随后销毁它们

                2)提前创建它们并且始终不销毁它们。

                也就是空间和时间的对抗,第一种方法注重空间的利用,第二种方法看重时间的重要性。

        10:代码示例:                                                                    */

    //说明这两个是类

    class TCPOctetStream;

    class TCPState;


    //Context:定义了接口

    class TCPConnection

    {

    public:

        TCPConnection();

        

        void ActiveOpen();

        void PassiveOpen();

        void Close();

        void Send();

        void Acknowledge();

        void Synchronize();

        void ProcessOctet(TCPOctetStream*);

    private:

        //设置为友元类才能使用ChanggeState接口。

        friend class TCPState;

        void ChangeState(TCPState*);

    private:

        TCPState* _state;

    };


    //abstract State:定义接口,以及实现默认操作

    class TCPState

    {

        virtual void Transmit(TCPConnection*, TCPOctetStream*);

        virtual void ActiveOpen(TCPConnection*);

        virtual void PassiveOpen(TCPConnection*);

        virtual void Close(TCPConnection*);

        virtual void Send(TCPConnection*);

        virtual void Acknowledge(TCPConnection*);

        virtual void Synchronize(TCPConnection*);

    protected:

        void ChangeState(TCPConnection*, TCPState*);

    };


    //初始化为关闭状态

    TCPConnection::TCPConnection()

    {

        _state = TCPClosed::Instance();

    }


    //设置状态

    void TCPConnection::ChangeState(TCPState*)

    {

        _state = s;

    }


    //所有调用都转到状态对象去调用的

    void TCPConnection::ActiveOpen()

    {

        _state->ActiveOpen(this);

    }

    void TCPConnection::PassiveOpen()

    {

        _state->PassiveOpen(this);

    }

    void TCPConnection::Close()

    {

        _state->Close(this);

    }

    void TCPConnection::Send()

    {

        _state->Send(this);

    }

    void TCPConnection::Acknowledge()

    {

        _state->Acknowledge(this);

    }

    void TCPConnection::Synchronize()

    {

        _state->Synchronize(this);

    }


    //定义默认实现

    void TCPState::Transmit(TCPConnection*, TCPOctetStream*) {}

    void TCPState::ActiveOpen(TCPConnection*){}

    void TCPState::PassiveOpen(TCPConnection*){}

    void TCPState::Close(TCPConnection*){}

    void TCPState::Send(TCPConnection*){}

    void TCPState::Acknowledge(TCPConnection*){}

    void TCPState::Synchronize(TCPConnection*){}



    void TCPState::ChangeState(TCPConnection*, TCPState* s)

    {

        t->ChangeState(s);

    }


    //ConcreteState:这三个都适用单例模式实现

    class TCPEstablished : public TCPState

    {

    public:

        static TCPState* Instance();

        virtual void Transmit(TCPConnection*, TCPOctetStream*);

        virtual void Close(TCPConnection*);

    };


    //ConcreteState

    class TCPListen : public TCPState

    {

    public:

        static TCPState* Instance();

        virtual void Send(TCPConnection*);

        //...

    };


    //ConcreteState

    class TCPClosed : public TCPState

    {

        static TCPState* Instance();

        

        virtual void ActiveOpen(TCPConnection*);

        virtual void PassiveOpen(TCPConnection*);

    };


    //通过接受到的参数,实现一些具体操作,并且使用这个参数来转换状态

    void TCPClosed::ActiveOpen(TCPConnection* t)

    {

        //send SYN, reveive SYN,ACK,etc.这就是具体要做的事。

        ChangeState(t,TCPEstablished::Instance());

    }


    void TCPClosed::PassiveOpen(TCPConnection* t)

    {

        ChangeState(t, TCPListen::Instance());

    }


    void TCPEstablished::Close(TCPConnection* t)

    {

        //send FIN,reveive ACK of FIN

        ChangeState(t, TCPListen::Instance());

    }


    void TCPEstablished::Transmit(TCPConnection* t, TCPOctetStream* o)

    {

        t->ProcessOctet(o);

    }


    void TCPListen::Send(TCPConnection* t)

    {

        //send SYN, receive SYN, ACK etc

        ChangeState(t, TCPEstablished::Instance());

    }



  • 相关阅读:
    Rsync常见运维操作命令
    [图文详解] Sublime Text在Windows/Ubuntu/Mac OSX中配置使用CTags
    Sublime Text : 创建工程
    Sublime Text 插件 & 使用技巧
    如何解决adb devices 端口被占用的问题zz
    Nginx 服务器安装及配置文件详解
    把notepad++设置为系统全局文本默认打开应用
    Ubuntu 下载 & 编译 Android5.1 源码
    同步、更新、下载Android Source & SDK from 国内镜像站
    如何为Linux生成和打上patch
  • 原文地址:https://www.cnblogs.com/boydfd/p/4983115.html
Copyright © 2011-2022 走看看