The state mode of the design pattern is to separate the state into a class, replacing the traditional complex if-else.
There are many introductions to the status mode on the Internet, but many of them are just clicked and I don’t understand the examples very clearly. Design patterns are just a way of thinking. Just master this idea well, and there are many ways to implement it.
Next I have a classic project problem - the approval process, and use the status mode.
The basic approval process is as follows: Submit the form -> First-level approval -> Second-level approval -> End
I've set it up as wellFour states: Submit form status, first-level approval status, second-level approval status, and end status.
The status is definedThree actions: Agree and enter the next link (agreeToNext), reject the previous link (backToBefore), end (finish)
Next I define the parent class of the state first. Here I use abstract classes instead of interfaces, because I think states have many general properties. Many online examples will put these properties into the Context context and modify these properties by changing the state. I think they are OK.
This parent class declares many state properties and defines three actions, but I implemented the end action method because I think the receiving action code is the same.
/**
* Submission status 0->First-level approval 1->Second-level approval 2->Approval completion 3
* state
*/
public abstract class Status {
/**
* Agree and go to the next stage
* @param task
* @param msg comments
* @param nextUser Processor for the next link
*/
public abstract boolean agreeToNext(ApproveTask task, String msg, String nextUser);
/**
* Go back to the previous session
* @param task
* @param msg comments
* @return
*/
public abstract boolean backToBefore(ApproveTask task, String msg);
//property
String statusName;//State name
String user;//Operate user
String suggest;//Opinion information
String request;//Application information
boolean operationFlag;//Whether the operation was performed
int statusId = -1;
boolean agreeFlag;//Agree
boolean isFinish;// Whether to terminate the status
int nextStatusId = -1;//Next link Status id
/**
* Constructing method
*/
public Status(String user,String request) {
= user;
= request;
}
/**
* Finish
* @param task
* @param msg comments
*/
public boolean finish(ApproveTask task,String msg,boolean agreeFlag){
("End of the session, is it abnormal:"+agreeFlag);
().add(this);//Put it into the approval chain
= msg;
= agreeFlag;
= 3;
= true;
//Exception termination
FinishStatus finishStatus = new FinishStatus(,msg,agreeFlag);
(finishStatus);
().add(finishStatus);
return true;
}
@Override
public String toString() {
return "StatusName +" Status id:"+statusId+" Next link id:"+
nextStatusId+" operation user:"+user
+" Whether the operation was performed:"+operationFlag
+" AgreeFlag
+" Application Information:"+request
+" Comments:"+ suggest;
}
}
Next is the specific status class:
Submit status class
/**
* Submission status 0->First-level approval 1->Second-level approval 2->Approval completion 3
*
* This is the commit status
*
*/
public class SubmitStatus extends Status{
public SubmitStatus(String user,String request) {
super(user,request);
= "Commit Status";
= 0;
}
@Override
public boolean agreeToNext(ApproveTask task,String msg,String nextUser){
("Agreement in the submission process");
= true;
= true;//
= msg;
= statusId + 1;//Sub-level status
().add(this);//Put into the approval path
(new FirstApproveStatus(nextUser, suggest));//Set up subordinate approval, and the current opinion becomes the application information of the next approver
return true;
}
@Override
public boolean backToBefore(ApproveTask task,String msg){
("Submission stage cannot be returned");
return false;
}
}
Level 1 approval status category:
/**
* Submission status 0->First-level approval 1->Second-level approval 2->Approval completion 3
* Level 1 approval
*/
public class FirstApproveStatus extends Status{
/**
* Constructing method
*
* @param user
*/
public FirstApproveStatus(String user,String request) {
super(user,request);
= "First-level approval";
= 1;
}
@Override
public boolean agreeToNext(ApproveTask task, String msg, String nextUser) {
("First Level Approval Agree");
= true;//
= true;
= msg;
= statusId + 1;//Sub-level status
().add(this);//Put into the approval path
(new SecondApproveStatus(nextUser,));//Set down-level approval
return true;
}
@Override
public boolean backToBefore(ApproveTask task, String msg) {
("First-level approval rollback");
= false;
= true;
= msg;
= statusId -1;
String beforeUserId = ().get(().size() - 1).user;
().add(this);
(new SubmitStatus(beforeUserId,));
return true;
}
}
Secondary approval status category:
public class SecondApproveStatus extends Status {
/**
* Constructing method
*
* @param user
*/
public SecondApproveStatus(String user,String request) {
super(user,request);
= "Second Level Approval";
= 2;
}
@Override
public boolean agreeToNext(ApproveTask task, String msg, String nextUser) {
("Second Level Approval Agree");
/* = true;//
= msg;
= statusId + 1;//Sub-level status
().add(this);//Put into the approval path
Status finishStatus = new FinishStatus(,,true);
(finishStatus);//Set down-level approval
().add(finishStatus);//Put in the approval path
*/
(task,msg,true);
return true;
}
@Override
public boolean backToBefore(ApproveTask task, String msg) {
("Second Level Approval Reversal");
= false;
= msg;
= statusId -1;
= true;
String beforeUserId = ().get(().size() - 1).user;
().add(this);
(new FirstApproveStatus(beforeUserId,));
return true;
}
}
End status class:
/**
* Submission status 0->First-level approval 1->Second-level approval 2->Approval completion 3
* Level 1 approval
*/
public class FirstApproveStatus extends Status{
/**
* Constructing method
*
* @param user
*/
public FirstApproveStatus(String user,String request) {
super(user,request);
= "First-level approval";
= 1;
}
@Override
public boolean agreeToNext(ApproveTask task, String msg, String nextUser) {
("First Level Approval Agree");
= true;//
= true;
= msg;
= statusId + 1;//Sub-level status
().add(this);//Put into the approval path
(new SecondApproveStatus(nextUser,));//Set down-level approval
return true;
}
@Override
public boolean backToBefore(ApproveTask task, String msg) {
("First-level approval rollback");
= false;
= true;
= msg;
= statusId -1;
String beforeUserId = ().get(().size() - 1).user;
().add(this);
(new SubmitStatus(beforeUserId,));
return true;
}
}
Next is the task class, which is the Context context or environment of many network examples.
This class has the current status and the attributes of the entire approval status flow, as well as providing external consent, rejection, rejection and other operations.Just do this。
import ;
import ;
/**
* Approval tasks Context environment equivalent to status mode
*
*/
public class ApproveTask {
private Status status;//current status
private List<Status> approveStatusList = new ArrayList<>();//Approval Operator can be extended here
/**
* Task Constructor
*/
public ApproveTask(String user){
= new SubmitStatus(user,null);
}
/**
* Agree to write a consent
* @param msg Agree
*/
public void agree(String msg,String nextUser){
(this,msg,nextUser);
}
/**
* turn down
* @param msg
*/
public void back(String msg){
(this,msg);
}
public void refund(String msg){
(this,msg,false);
}
/**
* Print the approval path
*/
public void showApprovePath(){
().forEach(::println);
}
//getter and setter
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
= status;
}
public List<Status> getApproveStatusList() {
return approveStatusList;
}
public void setApproveStatusList(List<Status> approveStatusList) {
= approveStatusList;
}
}
Test method 1 (normal secondary approval process):
public static void normal(){
("-------------------------------------------------------);
ApproveTask approveTask = new ApproveTask("Xiaohong");//Xiaohong creates a new approval task
("According to work needs, apply for use of the engineering machine for 3 days", "Xiao Ming");//Xiao Hong wrote the application form and submitted it to Xiao Ming
("Xiaohong needs to use the engineer, the preliminary decision can be made", "Xiaoliang");//Xiao Ming first-level approval and send it to Xiaoliang
("The situation is true, can be approved", null);//Xiaoliang approved the approval and approval
();
("-----The overall approval path is as follows----");
();
}
Running results:
--------------------------------
Consent during the submission
First-level approval approval
Secondary approval approval
End of the session: Is it abnormal?
----The overall approval path is as follows---
Status name: Submit status Status id:0 Next link id:1 Operation user: Xiaohong Whether the operation was performed: true Whether to agree: true Application information: null Comment information: Due to work needs, apply for use of the engineering machine for 3 days
Status name: First-level approval Status id:1 Next link id:2 Operation user: Xiao Ming Whether the operation was performed: true Whether you agree: true Application information: Due to work needs, you can apply for use of the engineering machine for 3 days Opinion information: Xiao Hong needs to use the engineer, and a preliminary decision can be made
Status name: Level 2 approval Status id:2 Next link id:3 Operation user: Xiaoliang Whether the operation was performed: true Whether it is agreed: true Application information: Xiaohong needs to use the engineer, and a preliminary decision can be made. Opinion information: The situation is true and can be approved.
Status name: End environment Status id:-1 Next link id:-1 Operation user: Xiaoliang Whether the operation was performed: true Whether to agree: true Application information: The situation is true, can be approved Opinion information: null
Test Method 2 (Rejected Example):
public static void back(){
("----------------------------------------------);
("New Task");
ApproveTask approveTask = new ApproveTask("Xiaohong");//Xiaohong creates a new approval task
("Current task status:"+());
("According to work needs, apply for use of the engineering machine for 3 days", "Xiao Ming");//Xiao Hong wrote the application form and submitted it to Xiao Ming
("Current task status:"+());
("Xiaohong needs to use the engineer, the preliminary decision can be made", "Xiaoliang");//Xiao Ming first-level approval and send it to Xiaoliang
("Current task status:"+());
("No, please check again");//Xiao Liang disagrees with the second-level approval
("Current task status:"+());
("The inventory has been checked, confirm that it is OK", "Xiaoliang");//Xiao Ming's first-level approval agrees again
("Current task status:"+());
("The situation is true, can be approved", null);//Xiaoliang approved the approval and approval
();
("-----The overall approval path is as follows----");
();
}
Running results:
--------------------------------------------------------------------------------------------------------------------------------
Create a new task
Current task status: Status name: Submit status Status id:0 Next link id:-1 Operation user: Xiaohong Whether the operation was performed: false Whether to agree: false Application information: null Comment information: null
Consent during the submission
Current task status: Status name: First-level approval Status id:1 Next link id:-1 Operation user: Xiao Ming Whether the operation was performed: false Whether to agree: false Application information: Due to work needs, apply for use of the engineering machine for 3 days Opinion information: null
First-level approval approval
Current task status: Status name: Secondary approval Status id:2 Next link id:-1 Operation user: Xiaoliang Whether the operation was performed: false Whether to agree: false Application information: Xiaohong needs to use the engineer, a preliminary decision can be made. Comment information: null
Secondary approval and return
Current task status: Status name: First-level approval Status id:1 Next link id:-1 Operation user: Xiao Ming Whether the operation has been performed: false Do you agree: false Application information: No, please check again Comment information: null
First-level approval approval
Current task status: Status name: Secondary approval Status id:2 Next link id:-1 Operation user: Xiaoliang Whether the operation has been performed: false Whether to agree: false Application information: The inventory has been checked, confirm that it is OK Opinion information: null
Secondary approval approval
End of the session: Is it abnormal?
----The overall approval path is as follows---
Status name: Submit status Status id:0 Next link id:1 Operation user: Xiaohong Whether the operation was performed: true Whether to agree: true Application information: null Comment information: Due to work needs, apply for use of the engineering machine for 3 days
Status name: First-level approval Status id:1 Next link id:2 Operation user: Xiao Ming Whether the operation was performed: true Whether you agree: true Application information: Due to work needs, you can apply for use of the engineering machine for 3 days Opinion information: Xiao Hong needs to use the engineer, and a preliminary decision can be made
Status name: Level 2 approval Status id:2 Next link id:1 Operation user: Xiaoliang Whether the operation was performed: true Whether you agree: false Application information: Xiaohong needs to use the engineer, a preliminary decision can be made. Opinion information: No, please check again
Status name: First-level approval Status id:1 Next stage id:2 Operation user: Xiao Ming Whether the operation has been performed: true Do you agree: true Application information: No, please check again Opinion information: The inventory has been checked, be sure it is OK
Status name: Level 2 approval Status id:2 Next link id:3 Operation user: Xiaoliang Whether the operation has been performed: true Whether to agree: true Application information: The inventory has been checked, confirm that it is OK Opinion information: The situation is true, and it can be approved
Status name: End environment Status id:-1 Next link id:-1 Operation user: Xiaoliang Whether the operation was performed: true Whether to agree: true Application information: The situation is true, can be approved Opinion information: null
summary:
The above is a simple example of the status mode simulation approval process.
Of course, there are many optimizations, such as rejection, and the task class needs to be serialized and deserialized, the task results can be saved into the database, and the value stored in the database can be restored to the task class and other operations.