java design pattern -- adapter pattern, handwritten spring MVC adapter design pattern

Main article (directory of all java design patterns)
https://blog.csdn.net/grd_java/article/details/122252696
Source location
Code cloud: https://gitee.com/yin_zhipeng/design_mode.git
GitHub:
What you must know before learning design patterns
  1. When looking at design patterns, we should comprehensively consider them from a larger perspective (code reusability, readability, scalability, reliability, high cohesion and low coupling of programs), rather than from the perspective of function realization. Don't think it's unnecessary to realize a function
  1. The design pattern class diagrams given in this article are all standard implementation methods, and do not necessarily comply with the standards. Therefore, as long as the design idea is consistent, a design pattern has multiple implementation methods, especially when looking at other people's source code, do not use the standard class diagram

1. Adapter Pattern

  1. Also known as default adapter mode, it converts the interface of a class into another interface desired by the client. The main purpose is compatibility, so that two classes whose original interfaces do not match and cannot work together can work together. Alias Wrapper
  2. The adapter mode is a structural mode
  3. There are three types: class adapter, object adapter and interface adapter mode
  4. Generally speaking, an object is converted into different objects through different adapters, such as 220V mains power and different DC power through various transformers
working principle
  1. Adapter mode: convert the interface of one class to another, so that classes with incompatible interfaces can be compatible
  2. From the user's point of view, the Adaptee is decoupled
  3. The user calls the target interface method transformed by the adapter, and the adapter then calls the relevant interface method of the Adaptee
  4. After receiving the feedback result, the user feels that he is only interacting with the target interface

1. Class adapter

  1. Adapter class (adapter), inherits src class (source class), implements dst class interface (target), and completes the adaptation of src - > dst
  2. Suppose src is a wall socket, 220v AC. dst is the target, such as mobile phones. We need 5v DC
  3. Then the Adapter is the charger, which adapts 220v AC to 5v DC for mobile phones
matters needing attention
  1. java is a single inheritance mechanism, and the class adapter needs to inherit the source class, which is a disadvantage (if we abstract the adapter into an interface, and then pass in the specific implementation class, is it feasible to specify the adapter? OK)
  2. The source class will be exposed in the class adapter, increasing the use cost
  3. However, by inheriting the source class and rewriting the source class method according to the requirements, the flexibility is enhanced
Class diagram: com/yzpnb/design_mode/adapter_pattern/class_adapter/uml/Phone.puml

Code: COM / yzpnb / design_ mode/adapter_ pattern/class_ Under adapter / phone package
  1. 220V mains power, source object, many products can not use it directly
  2. 5V DC, target object, object that can be used when charging the mobile phone (no specific implementation, the adapter converts it)
  3. The adapter inherits the 220V class. We can directly obtain it and implement the 5V interface. The interface specifies what we want to adapt 220V to
  4. With the adapter, you can charge your mobile phone
  5. Users, we need to select the charger first, and then charge the mobile phone

2. Object adapter (common)

  1. It is basically the same as the adapter class, and some modifications have been made to the adapter class
  2. The adapter class no longer inherits the source class, but holds an instance of the source class to solve the compatibility problem
  3. That is, the src class is held to implement the dst class interface to complete the adaptation of src - > dst
  4. According to the "composite Reuse Principle", the system tries to use association relationship to replace inheritance relationship, so most structural patterns are object structural patterns
Class diagram: com/yzpnb/design_mode/adapter_pattern/object_adapter/uml/Phone.puml

Code: COM / yzpnb / design_ mode/adapter_ pattern/object_ Under adapter / phone package
  1. Modify adapter class
  2. Nothing else needs to be changed

3. Interface adapter

  1. When you do not need to implement all the methods provided by the interface, you can first design an abstract class to implement the interface and provide a default implementation (empty method) for each method in the interface. Then the subclass of the abstract class can selectively override some methods of the parent class to implement the requirements
  2. Applies when an interface does not want to use all its methods
  3. More abstract concepts, not even adapter classes
Program: COM / yzpnb / design_ mode/adapter_ pattern/interface_ Under adapter / phone package
  1. Suppose I add two methods to the 5V interface, leakage and power failure
  2. Abstract classes, inheritance, empty implementation methods, so that other classes can selectively use these methods
  3. Classes that need to use certain methods, directly inherit the implementation, or use anonymous inner classes

2. Source code using adapter mode

The HandlerAdapter of Spring MVC uses the adapter mode
  1. The reason for using HandlerAdapter is that there are different processor types and multiple implementation methods, and the calling method is uncertain. If you directly call the Controller method, you have to constantly use if else to judge which subclass it is. If you want to extend the Controller later, you have to modify the original code, which violates the OCP (open close) principle
  2. Let's take a look at the spring MVC request Controller process. Class diagram: COM / atguigu / spring / UML / spring MVC request process puml
  3. How to use adapter mode? (I really don't want to draw this class diagram. It's too troublesome)
  1. Enter DispatcherServlet
  1. MVC uses the doDispatch method to process the incoming request, and then obtains the requested Handler through the getHandler method to get the Controller (mappedHandler mapping Controller)
  1. After obtaining the Controller (Controller mapping), obtain the corresponding adapter through the getHandlerAdapter method (different handlers need different adapters to call relevant methods)
  1. First see how getHandlerAdapter returns, and finally see what it returns
  1. It is found that it is a for loop, which traverses all adapters in turn, and then judges whether it is a type through the supports() method. If so, it returns the adapter

  1. HandlerAdapter interface to see which adapters are available
  1. What did you do when you got the adapter? Originally, the handle method is called through the adapter to return ModelAndView (the controller method is called through the adapter).

3. Write the spring MVC adapter design pattern and obtain the corresponding Controller

  1. Spring defines an adaptation interface so that each Controller has a corresponding adapter implementation class
  2. The adapter executes the corresponding method instead of the controller
  3. When extending the Controller, you only need to add an adapter class to complete the extension of spring MVC
Class diagram: COM / atguigu / spring / springmvc / UML / springmvc puml

  1. Benefits: if we add a Controller type and a corresponding adapter type, it will have no impact on the DispatchServlet we use
Code: under com/atguigu/spring/springmvc package
  1. First, raise the Controller that needs to be adapted (the Controller is 5V DC, and we want to adapt it like this)
//Multiple Controller implementations  
public interface Controller {

}
//Different adaptation types
class HttpController implements Controller {
	public void doHttpHandler() {
		System.out.println("http...");
	}
}

class SimpleController implements Controller {
	public void doSimplerHandler() {
		System.out.println("simple...");
	}
}

class AnnotationController implements Controller {
	public void doAnnotationHandler() {
		System.out.println("annotation...");
	}
}

  1. Get the adapter out (that is, the charger). There are many kinds of adapters
///Define an Adapter interface 
public interface HandlerAdapter {
	public boolean supports(Object handler);

	public void handle(Object handler);
}

// Multiple adapter classes
class SimpleHandlerAdapter implements HandlerAdapter {

	public void handle(Object handler) {
		((SimpleController) handler).doSimplerHandler();
	}

	public boolean supports(Object handler) {
		return (handler instanceof SimpleController);
	}

}

class HttpHandlerAdapter implements HandlerAdapter {

	public void handle(Object handler) {
		((HttpController) handler).doHttpHandler();
	}

	public boolean supports(Object handler) {
		return (handler instanceof HttpController);
	}

}

class AnnotationHandlerAdapter implements HandlerAdapter {

	public void handle(Object handler) {
		((AnnotationController) handler).doAnnotationHandler();
	}

	public boolean supports(Object handler) {

		return (handler instanceof AnnotationController);
	}

}
  1. DispatchServlet


import java.util.ArrayList;
import java.util.List;

public class DispatchServlet {

	//Saved all adapters
	public static List<HandlerAdapter> handlerAdapters = new ArrayList<HandlerAdapter>();

	//Put the adapter in
	public DispatchServlet() {
		handlerAdapters.add(new AnnotationHandlerAdapter());
		handlerAdapters.add(new HttpHandlerAdapter());
		handlerAdapters.add(new SimpleHandlerAdapter());
	}

	//The first call is the doDispatch method
	public void doDispatch() {

		// This simulates spring MVC fetching the handler object from the request,
		// The adapter can get the desired Controller
		 HttpController controller = new HttpController();
		// AnnotationController controller = new AnnotationController();
		//SimpleController controller = new SimpleController();
		// Get the corresponding adapter
		HandlerAdapter adapter = getHandler(controller);
		// Execute the corresponding controller method through the adapter
		adapter.handle(controller);

	}

	//According to the Controller to obtain the adapter, the mapping object mappedHandler is in spring MVC
	public HandlerAdapter getHandler(Controller controller) {
		//Traversal: return the corresponding adapter according to the obtained controller(handler)
		for (HandlerAdapter adapter : this.handlerAdapters) {
			if (adapter.supports(controller)) {
				return adapter;
			}
		}
		return null;
	}

	//Here we call doDispatch() directly
	public static void main(String[] args) {
		new DispatchServlet().doDispatch(); // http...
	}
}

Keywords: Java Design Pattern Spring MVC

Added by theresandy on Thu, 06 Jan 2022 10:44:33 +0200