Behavior.State (behavioral mode - state mode)

Definition of State Pattern

(1) Definition: Allows an object to change its behavior when its internal state changes . The object appears to modify its class.

  ① state and behavior, their relationship can be described as " state determines behavior "

  ②Because the state is changed during the runtime, the behavior will also change according to the change of the state during the runtime. It seems that the same object behaves differently at different runtimes, just like the class has been modified .

(2) The structure and description of the state mode

 

  ①Context: The environment, also known as the context, is usually used to define the interface that the customer is interested in , while maintaining an instance object that specifically handles the current state .

  ②State: The state interface is used to encapsulate the behavior corresponding to a specific state of the context.

  ③ConcreteState: A class that specifically implements state processing . Each class implements a specific processing of a context-related state.

mode of thinking

(1) The essence of the state pattern : the separation and selection of behavior according to the state

(2) State and behavior

  ①The function of the state pattern is to separate the state and the behavior corresponding to the state, and the function processing corresponding to each state is encapsulated in a separate class. By maintaining the changes of the state, different functions corresponding to different states are called.

  ②In order to operate different state classes, define a state interface to constrain them, so that external programming can be directed to this unified state interface without caring about the specific state class implementation.

  ③ State and behavior are related, and their relationship can be described as state determines behavior . Because the state is changed at runtime, the behavior will also change according to the change of state at runtime. It seems that the same object behaves differently at different runtimes, just like the class has been modified.

(3) Parallelism of Behavior

  ① Attention is parallelism, not equality . The so-called parallelism means that the behavior of each state is at the same level, independent and unrelated to each other, and it is determined which parallel line to follow according to different states. Because the behaviors are different, of course, the corresponding implementations are also different, and they are irreplaceable .

 

  ②Equality : Emphasizes the replaceability of use . Everyone is a different description or implementation of the same behavior. Therefore, when the same behavior occurs, any implementation can be selected according to the conditions to deal with it accordingly.

 

  ③ The structure of the state pattern is exactly the same as that of the strategy pattern. But their purpose, realization, and essence are completely different. The characteristics of behaviors are also an important difference between the state mode and the strategy mode. The behavior of the state mode is parallel and cannot be replaced with each other ; while the behavior of the strategy mode is equal and can be replaced with each other .

(4) Context and state

  ①In the state mode, the context holds the state object, but the context itself does not handle the behavior related to the state , but delegates the function of processing the state to the state processing class corresponding to the state .

  ②In the specific state processing class , it is often necessary to obtain the data of the context itself , and even call back the methods in the context when necessary. Therefore, the context itself is usually passed as a parameter to the concrete state handling class .

  ③ The client generally only interacts with the context. The client is usually not responsible for maintaining state during runtime, nor is it responsible for deciding which specific state processing object to use in the future, which is different from the strategy pattern .

(5) Imperfect OCP experience (open-closed principle)

  ①Modification function: Since the processing corresponding to each state has been encapsulated into the corresponding state class, if you want to modify the function of an existing state, you can directly modify that class, which has no effect on other programs.

  ②Add a new implementation class: you have to modify the request method in the Context . This doesn't quite follow OCP principles . It should be noted that the design principles are to be followed as much as possible in design and development, but not necessarily, especially completely. Because in actual development, it is almost impossible to fully comply with those principles.

(6) Create and destroy state objects

  ①If the state to be entered is unknowable at runtime , and the context is relatively stable, the state will not be changed frequently, and the use is not frequent, you can create state objects when you need them, and destroy them after use .

  ②If the state changes very frequently , that is, the state objects need to be created frequently, and the state objects also store a large amount of quantitative information. In this case, they can be created in advance and never destroyed .

  ③ If it is impossible to determine whether the state changes frequently , and some state objects have a large amount of data, some are relatively small, and everything is unknown, a combination of lazy loading and caching can be used , that is, when the state object needs to be used for the first time, it is created. After use, the object is not destroyed, but the object is cached, waiting for the next use, and when appropriate, the state object is destroyed by the caching framework. In the actual engineering development process, this scheme is the first choice, because it takes into account the advantages of the first two schemes and avoids their shortcomings.

[Programming Experiment] Your company finally obtained a system development project for a hotel after all the difficulties, and it finally fell on your head. The following figure is the main work of their system (simple enough). When you see the system for the first time, you can see that this is a state diagram, each box represents the state of the room, and the arrows represent the transition of the room state. The analysis is as follows: The room has three states: free, booked, and checked in, and the states can be converted according to the customer's actions. Define the value for each state.


Picture 1

yyyy

//declaration file

#include<iostream>
#include<iomanip>
using namespace std;



class CAbsState{
public:
	virtual void BookRoom() = 0;//Book a room
	virtual void UnsubscribeRoom() = 0;//Unsubscribe the room
	virtual void CheckInRoom() = 0;//Check in
	virtual void CheckOutRoom() = 0;//Check out
};

//Room  
class CRoom{
private:
	CAbsState* pFreeState;//Free state
	CAbsState* pCheckInState;//Check-in state
	CAbsState* pBookedState;//Booked state
	CAbsState* pCurrState;//Current state
public:
	CRoom();
	~CRoom();
	void BookRoom();
	void UnsubscribeRoom();
	void CheckInRoom();
	void CheckOutRoom();
	void RoomState();
public:
	void SetFreeState (CAbsState * freestate);
	CAbsState* GetFreeState();
	void SetCheckInState(CAbsState* checkinstate);
	CAbsState* GetCheckInState();
	void SetBookedState(CAbsState* bookedstate);
	CAbsState* GetBookedState();
	void SetCurrState(CAbsState* currstate);
	CAbsState* GetCurrState();
};
//The idle state can only book and check in
class CFreeState : public CAbsState{
private:
	CRoom* pRoom;
public:
	CFreeState(CRoom* room);
	void BookRoom();
	void CheckInRoom();
	void UnsubscribeRoom();
	void CheckOutRoom();
};
//Reserved room can be cancelled and checked in
class CBookedState : public CAbsState{
private:
	CRoom* pRoom;
public:
	CBookedState(CRoom* room);
	void BookRoom();
	void CheckInRoom();
	void CheckOutRoom();
	void UnsubscribeRoom();
};

// check in and check out
class CCheckInState : public CAbsState{
private:
	CRoom* pRoom;
public:
	CCheckInState(CRoom* room);
	void BookRoom();
	void CheckInRoom();
	void CheckOutRoom();
	void UnsubscribeRoom();
};

//implementation file

void CRoom::BookRoom(){ pCurrState->BookRoom();}//Book a room
void CRoom::UnsubscribeRoom(){pCurrState->UnsubscribeRoom();}//Unsubscribe room
void CRoom::CheckInRoom(){pCurrState->CheckInRoom();}//入住
void CRoom::CheckOutRoom(){pCurrState->CheckOutRoom();}//退房
void CRoom::RoomState(){cout << "The state of the room is:" << typeid(*pCurrState).name() << endl;}
void CRoom :: SetFreeState (CAbsState * freestate) {pFreeState = freestate;}
CAbsState* CRoom::GetFreeState(){return pFreeState;}
void CRoom::SetCheckInState(CAbsState* checkinstate){pCheckInState = checkinstate;}
CAbsState* CRoom::GetCheckInState(){return pCheckInState;}
void CRoom::SetBookedState(CAbsState* bookedstate){pBookedState = bookedstate;}
CAbsState* CRoom::GetBookedState(){return pBookedState;}
void CRoom::SetCurrState(CAbsState* currstate){pCurrState = currstate;}
CAbsState* CRoom::GetCurrState(){return pCurrState;}


CFreeState::CFreeState(CRoom* room){pRoom = room;}
void CFreeState::BookRoom(){
	cout << "You have successfully booked..." << endl;
	pRoom->SetCurrState(pRoom->GetBookedState());//The state becomes booked
}
void CFreeState::CheckInRoom(){
	cout << "You have successfully checked in..." << endl;
	pRoom->SetCurrState(pRoom->GetCheckInState());//The state has become checked in
}
void CFreeState::UnsubscribeRoom(){/*No operation required*/}
void CFreeState::CheckOutRoom(){/*No operation required*/}

//Reserved room can be cancelled and checked in

CBookedState::CBookedState(CRoom* room){pRoom = room;}
void CBookedState::BookRoom(){cout << "The room has been booked..." << endl;}
void CBookedState::CheckInRoom(){
	cout << "Check in successfully" << endl;
	pRoom->SetCurrState(pRoom->GetCheckInState());
}
void CBookedState::CheckOutRoom(){/*No operation required*/}
void CBookedState::UnsubscribeRoom(){
	cout << "Unsubscribe successfully, welcome next time" << endl;
	pRoom->SetCurrState(pRoom->GetFreeState());//Into the idle state
}

// check in and check out
CCheckInState::CCheckInState(CRoom* room){pRoom = room;}
void CCheckInState::BookRoom(){
	cout << "The room has been occupied..." << endl;
}
void CCheckInState::CheckInRoom(){
	cout << "The room has been occupied..." << endl;
}
void CCheckInState::CheckOutRoom(){
	cout << "Check out successfully..." << endl;
	pRoom->SetCurrState(pRoom->GetFreeState());//The state becomes free
}
void CCheckInState::UnsubscribeRoom(){/*No operation required*/}



CRoom::CRoom(){//Three states of the room
	pFreeState = new CFreeState(this);
	pCheckInState = new CCheckInState(this);
	pBookedState = new CBookedState(this);
	pCurrState = pFreeState;////The initial state is free
}
CRoom::~CRoom(){
	delete pFreeState;
	delete pCheckInState;
	delete pBookedState;
}

//test client

void main()
{
	CRoom* pRoom1 = new CRoom();
	CRoom* pRoom2 = new CRoom();
	//The first room: reservation--->check in---reservation
	cout << "The first room****************************" << endl;
	pRoom1->BookRoom();
	pRoom1->CheckInRoom();
	pRoom1->BookRoom();//Failed
	pRoom1->RoomState();
	cout << "Second room****************************" << endl;
	pRoom2->CheckInRoom();
	pRoom2->BookRoom();//Failed
	pRoom2->CheckOutRoom();
	pRoom2->BookRoom();
	pRoom2->RoomState();
	delete pRoom1;
	delete pRoom2;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325762879&siteId=291194637