State mode
As we talked about the strategy model, here's a look at the twin brothers of the Strategy model: State mode.
State patterns, which allow changes in the intrinsic state of an object to change its behavior, the object looks like it changes its class.
The first time I read this definition, it was almost a shock, and I didn't know what he was saying, one sentence, and when the internal state of an object changed, it was allowed to change its behavior , because this pattern encapsulated the state as a standalone
Class and delegate the action to the class that represents the current state, so the behavior of the object changes as the internal state changes; The object looks like it changes its class , from the customer's point of view: If the object you are using can
Completely altering its behavior, you will feel that the object is actually instantiated from another class. In fact, however, you know that we are using a combination to create the illusion of a class change by simply referencing different state objects.
Let's look at the class diagram of the state pattern:
Look, the structure of the class diagram with the strategy model is not bad ah, but the two in the intention is different, we look at a state pattern example, and then to explain the state mode and the strategy of the difference between the model.
Task management software We all know that the task has not started, in progress, has been resolved, has been closed, and so on, we can start the task, input work log, propose solutions, close the task and other operations, if we
Task to start the operation, then the task is in different states will produce a different response.
How does the code flow of this operation work? First of all, I did it this way:
Package com.hirain.chc.state; public class Task {//define several states of a task public static final int not_start = 0;//not started public static final int underway = 1; public static final int resolved = 2 in operation; Resolved public static final int CLOSED = 3;
Closed//Specifies the current status public int state = Not_start;
/** * Start operation.
/public void startup () {if (state = = 0) {System.out.println ("started successfully, the task switched to run status");
state = 1;
else if (state = = 1) {System.out.println ("Startup failed, current task is running");
else if (state = = 2) {System.out.println ("failed to start, current task is in resolved)";
else if (state = = 3) {System.out.println ("Startup failed, current task is in shutdown");
}/** * Input work content operation.
*/public void writecontent () {if (state = 0) {System.out.println ("Write failed, task not started");
state = 1;
else if (state = = 1) {System.out.println ("write succeeded");
else if (state = = 2) {System.out.println ("Write failed, task is already resolved");
else if (state = = 3) {System.out.println ("Write failed, task is already closed");
}/** * proposes a solution operation. * * PublIC void Solve () {if (St<span style= "White-space:pre" > </span>ate = 0) {System.out.println ("Operation failed, task has not been restarted
Movement ");
state = 1;
else if (state = = 1) {System.out.println ("The operation is successful, the task has been updated to resolved status");
state = 2;
else if (state = = 2) {System.out.println ("Operation failed, task is already resolved");
else if (state = = 3) {System.out.println ("Operation failed, task is already closed");
}/** * Closes the task operation.
*/public void Close () {if (state = 0) {System.out.println ("Operation failed, task not started");
state = 1;
else if (state = = 1) {System.out.println ("The operation is successful, the task is running, not closed");
state = 2;
else if (state = = 2) {System.out.println ("The operation is successful, the task has been updated to closed status");
state = 3;
else if (state = = 3) {System.out.println ("Operation failed, task is already closed");
}
}
}
Well, initially it seems that this class meets our needs, but if we want to add a new state one day, how can we modify the code to suit our needs.
Suspend state: A running task can switch to a pending state, indicating that the task needs to be temporarily paused.
If based on the above code to change, then we need to add a variable, and then each method to add a judgment condition, the code changes too much, prone to bugs cause the entire system instability.
So, this implementation is not feasible, we use state mode to solve this problem, according to the state pattern of class diagram to design this code:
Package Com.hirain.chc.state.demo;
Import Com.hirain.chc.state.demo.state.ClosedState;
Import Com.hirain.chc.state.demo.state.ITaskState;
Import Com.hirain.chc.state.demo.state.NotStartState;
Import Com.hirain.chc.state.demo.state.ResolvedState;
Import Com.hirain.chc.state.demo.state.UnderwayState;
public class Task {public itaskstate notstartstate;
Public Itaskstate underwaystate;
Public Itaskstate resolvedstate;
Public Itaskstate closedstate;
/** * Current state.
* * Public itaskstate State;
All States are initialized within the/** * construction method.
*/Public Task () {notstartstate = new notstartstate (this);
Underwaystate = new Underwaystate (this);
Resolvedstate = new Resolvedstate (this);
Closedstate = new Closedstate (this);
state = Notstartstate;
/** * Start operation.
*/public void startUp () {state.startup ();
/** * Input work content.
*/public void writecontent () {state.writecontent ();
/** * Propose solution operation.
*/public void Solve () {state.solve ();
/** * Closes the task operation. * * Public void Close () {state.close ();
Public Itaskstate GetState () {return state;
public void SetState (Itaskstate state) {this.state = state;
Public Itaskstate Getnotstartstate () {return notstartstate;
public void Setnotstartstate (Itaskstate notstartstate) {this.notstartstate = notstartstate;
Public Itaskstate Getunderwaystate () {return underwaystate;
public void Setunderwaystate (Itaskstate underwaystate) {this.underwaystate = underwaystate;
Public Itaskstate Getresolvedstate () {return resolvedstate;
public void Setresolvedstate (Itaskstate resolvedstate) {this.resolvedstate = resolvedstate;
Public Itaskstate Getclosedstate () {return closedstate;
public void Setclosedstate (Itaskstate closedstate) {this.closedstate = closedstate;
}
}
Package com.hirain.chc.state.demo.state;
Public interface Itaskstate {public
void startUp ();
public void Writecontent ();
public void Solve ();
public void Close ();
}
Package com.hirain.chc.state.demo.state;
Import Com.hirain.chc.state.demo.Task;
public class Notstartstate implements Itaskstate {
task task;
Public notstartstate (Task Task) {
this.task = task;
}
@Override public
void StartUp () {
task.setstate (task.getunderwaystate ());
System.out.println ("Startup succeeded, task has been updated to run status");
@Override public
void Writecontent () {
System.out.println (write failed, task not started);
}
@Override public
Void Solve () {
System.out.println ("Operation failed, task not started");
}
@Override public
Void Close () {
System.out.println (operation failed, task not started);
}
package com.hirain.chc.state.demo.state;
Import Com.hirain.chc.state.demo.Task;
public class Underwaystate implements Itaskstate {task task;
Public underwaystate (Task Task) {this.task = task;
@Override public void StartUp () {System.out.println ("Operation failed, task already in Run State");
@Override public void Writecontent () {System.out.println ("write succeeded");
@Override public void Solve () {System.out.println ("The operation was successful, the task has been updated to the resolved state");
Task.setstate (Task.getresolvedstate ());
@Override public void Close () {System.out.println ("Operation failed, task is in a running state"); }
}
package com.hirain.chc.state.demo.state;
Import Com.hirain.chc.state.demo.Task;
public class Resolvedstate implements Itaskstate {task task;
Public resolvedstate (Task Task) {this.task = task;
@Override public void StartUp () {System.out.println ("Operation failed, task already in resolved state");
@Override public void Writecontent () {System.out.println ("Operation failed, task already in resolved state");
@Override public void Solve () {System.out.println ("Operation failed, task already in resolved state");
@Override public void Close () {System.out.println ("The operation was successful, the task has been updated to the closed state");
Task.setstate (Task.getclosedstate ()); }
}
Package com.hirain.chc.state.demo.state;
Import Com.hirain.chc.state.demo.Task;
public class Closedstate implements Itaskstate {
task task;
Public closedstate (Task Task) {
this.task = task;
}
@Override public
void StartUp () {
System.out.println ("Operation failed, task is already in shutdown State");
}
@Override public
void Writecontent () {
System.out.println ("Operation failed, task is already in closed state");
}
@Override public
Void Solve () {
System.out.println ("Operation failed, task is already in closed state");
}
@Override public
Void Close () {
System.out.println ("Operation failed, task is already in shutdown State");
}
Test class:
Package Com.hirain.chc.state.demo;
/** *
Client application
* *
* @author * */Public
class Client {
/**
* @param args
*/< C34/>public static void Main (string[] args) {
Task task = new Task ();
Task.close ();
Task.startup ();
Task.close ();
Task.solve ();
Task.close ();
}
This is achieved according to the state pattern, although the class has become more, but reduces the complex if else, while the program is also easier to expand, if we now want to add a "suspend" state, then need to change the place is the task class
Variable and construct the method, and then add a "suspend" state class to it. While the support for closing the principle is not very good, it is relatively easy to accept.
pros and cons Analysis:
Advantages:
The behavior that is related to a particular state is localized and the behavior of different states is separated to conform to the single duty principle of the class.
Eliminates complex if else judgment statements.
Disadvantages:
Increases the number of classes.
Shut off the principle of support is not good, the new state class needs to modify the state-conversion part of the source code.
comparison of State mode and policy mode:
The state pattern separates the behaviors corresponding to each state, that is, for different states, the different subclasses are responsible for the specific operations, and the different state transitions are implemented by subclasses;
The strategy mode is directly dependent on the parameters injected into the context class to select the policy, there is no switching state operation.