Detailed state mode and usages in C + + design pattern programming _c language

Source: Internet
Author: User
Tags ticket

Each person and thing in a different state will have a different performance (action), and a state will be in different manifestations to the next different states (state). One of the simplest examples of life is this: the subway entrance, if you put the right subway ticket, the door will open for you to pass. At the exit is also a ticket, if the correct you can OK, otherwise you will not let you through (if you act brutal, there may be alarm (Alarm),:)).

A finite state automaton (FSM) is also a typical state, with different responses to input (state transitions).

Usually we implement this type of system will use a lot of switch/case statements, case of a certain state, what happens, the case of another state, then occur in another state. But there are at least two problems with this approach:
When the number of States is not much, switch/case may be able to handle it. But when the number of States is large (as is the case in the actual system), maintaining a large set of switch/case statements will be an exceptionally difficult and error-prone affair.
There is no separation between the state logic and the action implementation. In many system implementations, the implementation code of the action is written directly in the logic of the state. The consequence of this is that the scalability and maintenance of the system are not guaranteed.

The state pattern is used to solve the two problems listed above, in which we separate the state logic from the action implementation. When you want to maintain a large number of case branch statements in an operation, these branches depend on the state of the object. The state mode encapsulates each branch into a separate class.

The typical structure of a state pattern is:

Implementation of State mode
Code Snippets 1:state.h

State.h
#ifndef _state_h_
#define _STATE_H_
class context;//forward Declaration
class state{public
  :
  State ();
  Virtual ~state ();
  virtual void Operationinterface (context*) = 0;
  virtual void operationchangestate (context*) = 0;
  Protected:
  bool Changestate (context* con,state* st);
  Private:
  //bool changestate (context* con,state* st);
Class Concretestatea:public state{public
  :
  Concretestatea ();
  Virtual ~concretestatea ();
  virtual void Operationinterface (context*);
  virtual void operationchangestate (context*);
  Protected:
  private:
};
Class Concretestateb:public state{public
  :
  concretestateb ();
  Virtual ~concretestateb ();
  virtual void Operationinterface (context*);
  virtual void operationchangestate (context*);
  Protected:
  private:
};
#endif//~_state_h_

Code Snippets 2:state.cpp

State.cpp #include "State.h" #include "Context.h" #include <iostream> using namespace std; State::state () {} state::~state () {} void State::operationinterface (context* con) {cout<< "state:: ..."
<<endl;
  } bool State::changestate (context* con,state* St) {con->changestate (ST);
return true; } void State::operationchangestate (context* con) {}///Concretestatea::concretestatea () {} concretestatea::~ Concretestatea () {} void Concretestatea::operationinterface (context* con) {cout<< "Concretestatea::o
Perationinterface ... "<<endl;
  } void Concretestatea::operationchangestate (context* con) {operationinterface (con);
This->changestate (Con,new concretestateb ()); }///Concretestateb::concretestateb () {} concretestateb::~concretestateb () {} void Concretestateb::o Perationinterface (context* con) {cout<< "Concretestateb::operationinterface ..." <<endl;} void
  Concretestateb::operationchangestate (context* con) {operationinterface (con);This->changestate (Con,new Concretestatea ());
 }

Code Snippets 3:context.h

Context.h
#ifndef _context_h_
#define _CONTEXT_H_
class state;
/**
*
**/
class context{public
  : Context
  ();
  Context (state* state);
  ~context ();
  void Oprationinterface ();
  void Operationchangstate ();
  Protected:
  Private:
  friend class State;//indicates that the private field of the context class can be accessed in the State Class
  bool Changestate (state* s Tate);
  Private:
  state* _state;
#endif//~_context_h_

Code Snippets 4:context.cpp

Context.cpp
#include "Context.h"
#include "State.h"
Context::context () {
}
Context::context (state* State) {
  this->_state = state;
}
Context::~context () {
  delete _state;
}
void Context::oprationinterface () {
  _state->operationinterface (this);
}
BOOL Context::changestate (state* State) {
  ///_state->changestate (this,state);
  This->_state = State;
  return true;
}
void Context::operationchangstate () {
  _state->operationchangestate (this);
}

Code Snippets 5:main.cpp

Main.cpp
#include "Context.h"
#include "State.h"
#include <iostream>
using namespace STD;
int main (int argc,char* argv[]) {
  state* st = new Concretestatea ();
  context* con = new context (ST);
  Con->operationchangstate ();
  Con->operationchangstate ();
  Con->operationchangstate ();
  if (Con!= NULL)
    Delete con;
  if (St!= null)
    st = null;
  return 0;
}

Code Description: State mode in implementation, there are two key points:
1. The state is declared as a friend Class (friend Class) of the context, and its function is to let the state mode access the protected interface Changesate () of the context.
The actions in the State and its subclasses all pass context* as arguments, the primary purpose of which is that the State class can invoke the method in the context through this pointer (which is not reflected in this example code). This is also the biggest difference between state and strategy patterns.

2. After running the sample code, you can get the following results: the Oprationinterface () of the context is called 3 times in a row because the state changes after each call (A-B-A), so the action gets a different result as the state of the context changes.


Some of the things to note about state mode
This pattern allows the software to present a completely different feature under different state

Different theme make the same elements appear in different characteristics
The same operations under different state have different effects
Different states have different processing for the same information
This pattern makes the state logic of the operation clearer and eliminates countless state judgments, while the state's extensibility and maintainability and execution efficiency are greatly increased. As for state, there are several points to note:

1. All state should be managed by a class (state manager Class):

The jumps and conversions between state are very complex, and sometimes some state may want to jump to the target state there are dozens of, this time we need a management class (state Manager) to unify the management of these state switches, For example, the initialization of the target State and the end processing of the request jump State, as well as the storage and processing of shared data between the state. Instead of calling this manager a management class, it's an intermediate class that implements the Zhei between state so that each state is no more specific than the target State, as long as you apply to the manager for a jump. Makes the modularity of each state better and more flexible

2. All state should inherit from a state base class:

Since state is going to teach a manager to manage, naturally, these state should inherit from a parent class, so that the manager does not need to know a lot of subclass information, and one of the most simple managers can just manage a pointer to such a base class. In addition, we can also unify some of the state's common attributes here

3.state should be implemented as a singleton:

State does not need to be always applied, which may result in administrative confusion, and the application of state resources should not be arbitrary, in fact, the state's request permission should only be manager only, and there is only one. In such cases, the state's constructor should seem to be declared as protected or private, and the manager should be declared as a friend of state, but the friend is seen as a way of destroying the encapsulation of the class, which I am conflicted about, So in this article I can only take a disregard of the attitude.

4. Should I do a state? This is a problem:

State can be said to be a substitute for if-else, and in extreme cases, it can make your program if-else the program block disappear, but this is not silver bullets. State is very effective in situations where States are predictable, but not in terms that are unpredictable or similar in number. Too much state will cause class granularity, the program is not concise. In such cases, you should consider using the IF-ELSE program block instead of state.

For example:

There is such a program, it can generate arbitrary shape of the polygon, and the various nodes of the polygon can be moved, the problem comes.

I don't know how many nodes the user will be using the polygon, so I can't create so many corresponding state to make such a program work properly. State is mostly certain, and there seems to be nothing for state to be unsure of, such as this example

One solution is for me to use the manager to pass a state parameter to the state, which gives the state the opportunity to know what the user is doing, in this case the state knows that the user is going to be working on a node, and state handles the user's actions according to the state parameter. For example, state gets the index of a point in the user's operation, and state simply writes

Points[index].moveto (Points[index].getx () +offset_x, points[index].gety () +offset_y);

To avoid the problem of excessive state.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.