preface

In the previous article we learned about the share and proxy patterns of structural patterns. This paper will study two behavioral patterns, Chain of Responsibility Pattern and Command Pattern.

Chain of Responsibility model

Introduction to the

The chain of responsibility pattern, as the name suggests, creates a chain of recipient objects for the request. This pattern decouples the sender and receiver of the request by giving the type of request. This type of design pattern is behavioral. In this pattern, each receiver typically contains a reference to the other receiver. If an object cannot handle the request, it passes the same request to the next recipient, and so on.

The simple way to think about it is hierarchy. Applications for leave, business trips, pay raises, etc., are common in life, while interceptors and filters are common in work. If the application for leave is used in the previous way, the initiator needs to apply with each person in charge, which will be troublesome, but now it is generally through the OA process, and only one OA application can be initiated. This is also a typical chain of responsibility pattern, where the originator just sends the request to the chain of responsibility and doesn’t care about the processing details and the delivery of the request.

The Chain of responsibility pattern mainly consists of three roles: request receiver interface (Handler), request implementor class (ConcreteHandler), and request sender (Client).

  • Request receiver interface: Defines an interface that can handle client requests, including object references that can be linked to next requests that can also handle requests.
  • Request implementer class: implements the request processing interface and determines whether the object itself can handle the request, and if it cannot complete the request, hands it over to a successor.
  • Request sender: Sends the request to the first recipient object and waits for a reply to the request.

Here we use a simple example to illustrate for ease of understanding. In a certain department of a company, in order to activate the atmosphere of the department, the supervisor asked for the opinions of the members of the department, so the members of the department actively put forward suggestions. Finally, the supervisor adopted the suggestion proposed by Xuwujing and reported it to apply for activity funds. So we can according to the example here USES the chain of responsibility pattern for development, first of all, to speed up the three leaders, they have a common characteristic, is something we can handle each level, then we can define a leadership of abstract classes, and defines an abstract method can deal with things, and set the parameters of a level, then the abstract class code is as follows:


abstract class Learder{

   protected Learder learder;
   
   protected void setLearder(Learder learder){
   	this.learder=learder;
   }
   
   protected Learder getLearder() {return learder;
   }
   
   abstract void handler(int  level);
}

Copy the code

After defining the abstract class, we need to design different leaders for different processing, but these leaders need to have the ability to process, and according to their different permissions to process, if they can process, the process ends, otherwise it can not be processed to the superior for processing. The code is as follows:

class Supervisor extends Learder{ private String name; private String something; public Supervisor(String name,String something) { this.name=name; this.something=something; } @override void handler(int level) {// If the level is within its scopeif(level>1){
   		System.out.println("The director agreed."+name+"Said <"+something+"> things!");
   	}else{
   		System.out.println("Failure by supervisor to handle"+name+"Said <"+something+"> things! Hand it over!");
   		getLearder().handler(level);
   	}
   }
}


class BranchManager extends Learder{
    private String name;
    private String something;
    public BranchManager(String name,String something) {
   	this.name=name;
   	this.something=something;
   }
   
   @Override
   void handler(int level) {
   	boolean flag=true; // If the level is within its own processing scopeif(level>0)if(flag){
   			System.out.println("The department manager agreed."+name+"Said <"+something+"> things!");
   		}else{
   			System.out.println("The department manager didn't agree."+name+"Said <"+something+"> things!"); }}else{
   		System.out.println("Department manager failed to deal with it."+name+"Said <"+something+"> things! Hand it over!");
   		getLearder().handler(level);
   	}
   }
}


class GeneralManager extends Learder{
    private String name;
    private String something;
    public GeneralManager(String name,String something) {
   	this.name=name;
   	this.something=something;
   }
   
   @Override
   void handler(int level) {
   	boolean flag=false; // If the level is within its own processing scopeif(level>-1){// Set the value of this command to a different levelif(flag){
   			System.out.println("The general manager agreed."+name+"Said <"+something+"> things!");
   		}else{
   			System.out.println("General manager does not agree."+name+"Said <"+something+"> things!"); }}else{
   		System.out.println("General manager failed to deal with"+name+"Said <"+something+"> things! Hand it over!"); getLearder().handler(level); }}}Copy the code

Finally, we will test the code according to the process we need to follow. Since we did not specify who is superior to whom when we wrote the request class, we need to specify a superior relationship here to keep the process going. After specifying a superior, we set the level at which the event will be handled, and finally run it. The test code is as follows:


public static void main(String[] args) {
   	String name = "xuwujing";
   	String something = "Go to dinner.";
   	String something2 = "Take a trip";
   	Learder learder1 =new Supervisor(name, something);
   	Learder learder2 =new BranchManager(name, something);
   	Learder learder3 =new GeneralManager(name, something);
   	learder1.setLearder(learder2);
   	learder2.setLearder(learder3);
   	learder1.handler(1);
   	
   	Learder learder4 =new Supervisor(name, something2);
   	Learder learder5 =new BranchManager(name, something2);
   	Learder learder6 =new GeneralManager(name, something2);
   	learder4.setLearder(learder5);
   	learder5.setLearder(learder6);
   	learder4.handler(0);

}

Copy the code

Output result:

The supervisor failed to deal with xuwujing's "go to dinner party"! Hand it over! The department manager agreed to xuwujing's "go to dinner party"! The supervisor failed to deal with xuwujing's "go traveling"! Hand it over! The department manager failed to deal with xuwujing's "go traveling"! Hand it over! The general manager does not agree with xuwujing about "going on a trip"!Copy the code

Advantages of responsibility chain mode:

The coupling degree is low, requester and executor are not necessarily related; High degree of flexibility, through internal members to change the order of their execution; Good scalability, Handler subclass extension is very convenient.

Disadvantages of chain of responsibility mode:

Can degrade the performance of the program to some extent, if set improperly may appear circular calls. When chains are too long, the code becomes less readable and more complex.

Usage Scenarios:

When you need to dynamically specify the processing of a set of requests and send requests to multiple objects without determining the recipients.

Matters needing attention:

Although the chain of responsibility mode is flexible, it sacrifices certain performance. Because the chain of responsibility mode is hierarchical processing, it is not recommended to use the chain of responsibility mode when low latency is required for data processing.

Command mode

Introduction to the

As the name implies, the command pattern is a data-driven design pattern, which belongs to the behavior pattern. The request is wrapped in the object as a command and passed to the calling object. The calling object looks for a suitable object that can handle the command and passes the command to the corresponding object, which executes the command. This is to encapsulate a request into an object that can be parameterized with different requests for the client.

The command pattern consists of three roles, command object (Command), command execution object (received), and command request object (Invoker).

  • Command object: a method that declares implementation through an interface or abstract class.
  • Command execution object: a method that implements a command object and binds a receiver to an action, invoking the corresponding action of the receiver.
  • Command request object: used to execute the request and can control the command dynamically.

Here we will use a simple example to illustrate. In a certain school, students need to follow the teacher’s orders, such as the teacher can ask students to clean the classroom, to finish the unfinished homework and other orders, but the students have limited time, they can only finish a certain thing within a certain period of time. At this time, two teachers just told students Xuwujing the order. Miss Li let Xuwujing clean the classroom after school, Miss Wang let Xuwujing finish the unfinished homework and give him before going home, but the school entrance guard time is limited, so Xuwujing just cleaned the classroom, and then fled… So based on this example, we can use command mode to do this. First, define a student class and specify what the student can do. The code is as follows:


class Student{
	void cleanClassRoom(String name){
		System.out.println(name+"Start cleaning the classroom...");
	}
	void doHomeWork(String name){
		System.out.println(name+"Do your homework..."); }}Copy the code

You then define a command abstraction class and set the method to execute.


abstract class Command{
	protected Student student;
	public Command(Student student){
		this.student = student;
	}
	abstract void execute(String name);
}
Copy the code

Then two command execution objects are defined to set the commands to be executed.

class LiTeacher extends Command{ public LiTeacher(Student student) { super(student); } @Override void execute(String name) { student.cleanClassRoom(name); } } class WangTeacher extends Command{ public WangTeacher(Student student) { super(student); } @Override void execute(String name) { student.doHomeWork(name); }}Copy the code

Finally, we define a command request object that executes the request and controls commands, such as new commands, undo commands, execute commands, and so on. The code is as follows:


class Invoker {
	private List<Command> commands = new ArrayList<Command>();
	
	public void setCommand(Command command) {
		if(commands.size()>0) {
			System.out.println("Do not carry out WangTeacher's orders!");
		}else {
			commands.add(command);
		}
	}
	
	public void executeCommand(String name) {
		commands.forEach(command->{
			command.execute(name);
		});
	}
	
	public void undoCommand(Command command) {
		commands.remove(command);
		System.out.println("Revoke the order!"); }}Copy the code

Finally, test the code. The test code is as follows:


public static void main(String[] args) {
		String name = "xuwujing";
		Student student = new  Student();
		Command command1 = new LiTeacher(student);
		Command command2 = new WangTeacher(student);
		Invoker invoker =new Invoker();
		invoker.setCommand(command1);
		invoker.setCommand(command2);
		invoker.executeCommand(name);
	}
Copy the code

Output result:

Do not execute WangTeacher's command! Xuwujing began to clean the classroom...Copy the code

Advantages of the command mode:

The coupling degree is low, requester and executor are not necessarily related; Well extensible, subclasses of Command can be easily extended.

Disadvantages of command mode:

Too many commands will increase the complexity of the system.

Usage Scenarios:

If you need to specify similar commands, you can use command mode, such as logging, undo command, and so on.

other

Music to recommend

Share a very light music!

Project code

Java-study is some code that I have documented during my Java learning process, including the code used in previous posts. If the feeling is good, I hope to give a start, of course, if there is any deficiency, I also hope to propose. Github address: github.com/xuwujing/ja…

Original is not easy, if you feel good, I hope to give a recommendation! Your support is the biggest motivation for my writing! Copyright: www.cnblogs.com/xuwujing CSDN blog.csdn.net/qazwsxpcm Personal blog: www.panchengming.com