State mode: One of the behavioral patterns that allows an object to change its behavior when it changes its state internally, and the object appears to modify its class.
The state mode mainly solves the problem that when the state transition condition expression of an object is too complex, the logical judgment of State is transferred to a series of classes that represent different States, and the complex judgment logic can be simplified. The benefit is to localize the behavior associated with a particular state and separate the different state behaviors. For example, we have a dosomething function that has a large number of if else branches or case branches, and functions perform different operations under different branches. One of the basic guidelines in programming is code bad taste, the function code is too long is often a bad taste, the usual practice is to split the function into several small functions, and in the object-oriented, you can use the state mode, the characteristics of the state and the state of the relevant behavior into a separate state class, It is advantageous for the development of the system to divide the complex state logic judgment, and it is necessary to add only one State class when it is necessary to increase the condition to judge the branch, without the need to increase the judgment branch in the original function (breaking open-closed principle).
UML class diagram for general state mode
Context: Defines an interface that is of interest to the customer and maintains a reference to the state that holds the current status.
State: An abstract status class that defines a unified abstract interface for the corresponding behavior that needs to be performed in each state.
Concretestate: The concrete state class, which implements the interface of the state of abstraction and defines the related behavior in its own state.
Take a basic socket communication code for example, write a simple version of the sample code:
State.h
Class Tcpstate;
Class Tcpconn
{public
:
tcpconn (tcpstate* state) {this->m_state = state;}
void Settcpstate (tcpstate* state);
void Request ();
Private:
tcpstate* m_state;
Class Tcpstate
{public
:
virtual void Handle (tcpconn*) = 0;
Virtual ~tcpstate () {};
};
Class Tcpclose:public tcpstate
{public
:
virtual~tcpclose () {};
virtual void Handle (tcpconn*);
Class Tcplisten:p ublic tcpstate
{public
:
virtual ~tcplisten () {};
virtual void Handle (tcpconn*);
Class tcpaccepted:p ublic tcpstate
{public
:
virtual ~tcpaccepted () {};
virtual void Handle (tcpconn*);
Class tcpconnected:p ublic tcpstate
{public
:
virtual ~tcpconnected () {};
virtual void Handle (tcpconn*);
State.cpp
#include "State.h"
#include <iostream>
void Tcplisten::handle (tcpconn* tcpconn)
{
// Can call socket bind, listen function
std::cout << "TCP STAT listening\n";
Tcpconn->settcpstate (New tcpaccepted ());
}
void Tcpaccepted::handle (tcpconn* tcpconn)
{
//can call accepted wait for client connection
std::cout << "TCP STAT accepted\n ";
Tcpconn->settcpstate (New tcpconnected ());
}
void Tcpconnected::handle (tcpconn* tcpconn)
{
//can write read-write function here send recv
std::cout << "TCP STAT connected\n ";
Tcpconn->settcpstate (New Tcpclose ());
}
void Tcpclose::handle (tcpconn* tcpconn)
{
//can be called here again close closes socket
std::cout << "TCP STAT close\n ";
Tcpconn->settcpstate (New Tcplisten ());
}
void Tcpconn::settcpstate (tcpstate* state)
{
if (NULL!= m_state)
delete m_state;
This->m_state = State;
}
void Tcpconn::request ()
{
m_state->handle (this);
}
Client code:
#include "State.h"
int main ()
{
tcpconn* tcpconn = new Tcpconn (new Tcplisten ());
Tcpconn->request ();
Tcpconn->request ();
Tcpconn->request ();
Tcpconn->request ();
Delete tcpconn;
}
Code Run Screenshot: