I. Introduction to state mode

1. What is state mode

State Pattern is a kind of behavioral design Pattern, which is defined as: Allow an object to alter its behavior when its internal state changes . The object will appear to change its class Allowing an object to change its behavior when its internal state changes makes the object look like it has changed its class. The core idea of state mode is encapsulation. The change of state causes the change of behavior, which looks like the change of the corresponding class of the object from the outside.

2. Service scenarios

In our daily work, we will inevitably use many functions related to approval, such as overtime approval, approval for going out, approval for asking for leave and so on. It is not hard to find that these types of approvals have a common feature: as the approval process progresses, the status of the approvals we submit changes. If we want to simulate this scenario, using the state pattern we’ll be studying today is a good choice.

Our programmer Xiao Ming got up today and found that the PM2.5 level in his city was seriously off the charts. Although Xiao Ming is a dedicated worker, it is obviously not the right choice to run for drugs under such circumstances. Therefore, Xiao Ming wanted to ask for an hour’s leave and work late.

But because xiaoming’s company does not have OA software for office use, xiaoming needs to call his leaders one by one to apply for it. Although the approval of leave was finally passed, Xiao Ming, who loves his work, was still immersed in meditation. Obviously, Xiao Ming has realized how important it is to have a functional leave application APP, so he began to design a leave OA system for the company.

Since we want to design a leave system, the first thing Xiao Ming needs to do is to sort out a complete process of leave approval. So Xiaoming drew the first flowchart for asking for leave:

Second, the realization of state mode

1. Design idea

When we have a design flow, all we need to do is convert the flow into a class diagram. First of all, we simply designed the first version of class diagram without considering performance and workload:

Here, Xiaoming’s design idea is to create a sendApproval method on the client for submitting leave approval, and then control the change of approval status by creating different approval objects. Although this method is simple to implement, due to the lack of centralized management of approval status, it may not be able to control permissions well, so there is the possibility of cross-level approval. Knowing the problem, Xiao Ming continued to optimize the class diagram:

In the class diagram, a ApprovalIterface interface is defined and a protected object Context variable is declared, which is an encapsulated class that concatenates states. Wrap it is clear that the purpose of the approval paper is the internal state of protected classes know not be invoked, abide by the law of Demeter, and according to the examination and approval department of the different implementation classes, bear the state and state change of excessive, summary, there are three roles involved in the examination and approval:

  1. Abstract State roles (States) : Typically interfaces or abstract classes that are responsible for object State definition and encapsulate environment roles to enable State switching.
  2. ConcreteState roles: each ConcreteState must fulfill two responsibilities. The behavior management of this state and the handling of trending state are what the current state does and transitions to other states.

2. Code implementation

After the preparation of the theory, Xiao Ming began to write the relevant code. 1. The first is the design of state interface

public interface ApprovalInterface {

	void checkAdopt(Context context);

	void checkUnAdopt(Context context);
}
Copy the code

2. What we need to do next is to write three implementation classes

// Group leader approval
public class GroupApproval implements ApprovalInterface {

	@Override
	public void checkAdopt(Context context) {
		System.out.println("Approved by the group leader");
		context.setApproval(Context.DEPARTMENT_APPROVAL);
	}

	@Override
	public void checkUnAdopt(Context context) {
		System.out.println("If the leader fails to pass the approval, the approval process is over"); }}Copy the code
// Department approval
public class DepartmentApproval  implements ApprovalInterface{

	@Override
	public void checkAdopt(Context context) {
			System.out.println("Approved by the department");
			context.setApproval(Context.CEO_APPROVAL);
	}

	@Override
	public void checkUnAdopt(Context context) {
		System.out.println("If the department fails to pass the approval, the approval process is over."); }}Copy the code
/ / the CEO for approval
public class CEOApproval implements ApprovalInterface {

	@Override
	public void checkAdopt(Context context) {
		System.out.println("CEO approval is approved, the approval is over.");
	}

	@Override
	public void checkUnAdopt(Context context) {
		System.out.println("CEO approval is not approved, the approval is ended."); }}Copy the code

3. Step 3 we need to create the approval single object (environment object)

public class Context {

	private ApprovalInterface approval;
	public final static ApprovalInterface GROUP_APPROVAL = new GroupApproval();
	public final static ApprovalInterface DEPARTMENT_APPROVAL = new DepartmentApproval();
	public final static ApprovalInterface CEO_APPROVAL = new CEOApproval();

	public Context(a) {
		super(a); approval = GROUP_APPROVAL; }public void checkAdopt(a) {
		approval.checkAdopt(this);
	}

	public void checkUnAdopt(a) {
		approval.checkUnAdopt(this);
	}

	public ApprovalInterface getApproval(a) {
		return approval;
	}

	public void setApproval(ApprovalInterface approval) {
		this.approval = approval; }}Copy the code

4. Finally, provide the test code

public class Client {

	public static void main(String[] args) {
		sendApproval();
	}

	private static void sendApproval(a) {
		Context context = newContext(); context.checkAdopt(); context.checkAdopt(); context.checkAdopt(); }}Copy the code

Test results: Well, a simple leave approval OA has been achieved, of course, there are still a lot of permission control in this code can be optimized, interested students can submit homework in the comments section oh ~

3. Summary of state mode

1. Characteristics of the state mode

Advantages:

  1. Encapsulates conversion rules for easier conversion and adding new rules.
  2. Too much conditional judgment is avoided
  3. Follow design principles
  4. Good encapsulation type

disadvantages

  1. It causes the class to swell

2. Application scenarios of the state mode

  1. Scenarios where behavior changes with state, such as order payment systems, approval flows, permission controls, and so on.
  2. Refactor code that has too many judgment statements.

Four, conclusion

Today’s proxy mode explanation is all over, the related code of the design mode has been included in Gitee, you can take it directly if you need it:

Gitee.com/xiaolong-ob…

If you have any questions, you are welcome to leave a message in the comment section or send a private message to the blogger, who will answer them for you in the first time. The code word is not easy, feel the harvest of friends remember to pay attention to the blogger, do not be white whoring monster oh ~ blogger here wish you can be promoted in the New Year, to the peak of life!