Preceding text
Analysis of spring MVC common annotations
Article directory
Adapter mode
Basic introduction
- Adapter pattern is to transform the interface of a class into another interface representation expected by the client. Its main purpose is compatibility, so that two classes that cannot work together due to interface mismatch can work together. Its alias is Wrapper
- Adapter mode belongs to structural mode
- There are three types: type adapter mode, object adapter mode and interface adapter mode
How adapter mode works
- Adapter mode: convert the interface of one class to another, so that the classes that are not compatible with the original interface can be compatible
- From the user's point of view, there is no adapter, which is decoupled
- The user calls the target interface method transformed by the adapter, and the adapter calls the relevant interface of the adapter
- The user receives the feedback result and feels that it only interacts with the target interface
Class adapter pattern implementation
package com.java.springtest.classadapter; // Adapted class public class Voltage { // Output voltage of 220V public int outPut220V() { int src = 220; System.out.println("Voltage=" + src + "V"); return src; } }
package com.java.springtest.classadapter; /** * @author Woo_home * @create by 2020/2/17 */ // Adapter interface public interface IVoltage { int outPut(); }
package com.java.springtest.classadapter; public class VoltageAdapter extends Voltage implements IVoltage { @Override public int outPut() { // Obtain 220V voltage int srcV = outPut220V(); int dstV = srcV / 44; return dstV; } }
package com.java.springtest.classadapter; public class Phone { // Charge public void changing(IVoltage iVoltage) { if (iVoltage.outPut() == 5) { System.out.println("Voltage 5 V,Can charge"); } else if (iVoltage.outPut() > 5) { System.out.println("Voltage greater than 5 V,Can not charge"); } } }
package com.java.springtest.classadapter; public class Client { public static void main(String[] args) { System.out.println("----------- Class adapter pattern ------------"); Phone phone = new Phone(); phone.changing(new VoltageAdapter()); } }
Output:
Considerations and details of class adapter pattern
- Java is a single inheritance mechanism, so class adapter needs to inherit src class, which is a disadvantage, because it requires that dst must be an interface, which has certain limitations
- The methods of src class will be exposed in the Adapter, which also increases the cost of use
- Because it inherits the src class, it can rewrite the methods of the src class according to the requirements, which makes the Adapter more flexible
Object adapter pattern implementation
package com.java.springtest.classadapter; // Adapted class public class Voltage { // Output voltage of 220V public int outPut220V() { int src = 220; System.out.println("Voltage=" + src + "V"); return src; } }
package com.java.springtest.classadapter; // Adapter interface public interface IVoltage { int outPut(); }
package com.java.springtest.classadapter; public class VoltageAdapter implements IVoltage { private Voltage voltage; public VoltageAdapter(Voltage voltage) { this.voltage = voltage; } @Override public int outPut() { int dst = 0; if (null != voltage) { int src = voltage.outPut220V();// Obtain 220V voltage dst = src / 44; } return dst; } }
package com.java.springtest.classadapter; public class Phone { // Charge public void changing(IVoltage iVoltage) { if (iVoltage.outPut() == 5) { System.out.println("Voltage 5 V,Can charge"); } else if (iVoltage.outPut() > 5) { System.out.println("Voltage greater than 5 V,Can not charge"); } } }
package com.java.springtest.classadapter; public class Client { public static void main(String[] args) { System.out.println("----------- Object Adapter Pattern ------------"); Phone phone = new Phone(); phone.changing(new VoltageAdapter(new Voltage())); } }
Considerations and details of the object adapter pattern
- Object adapter and class adapter are the same idea, but they are implemented in different ways. According to the principle of composite reuse, we use combination instead of inheritance, so it solves the limitation that class adapter must inherit src, and it no longer requires dst to be interface
- Lower cost and more flexibility
Interface adapter mode
Basic introduction
- Some books are called: adapter mode or default adapter mode
- When not all the methods provided by the interface need to be implemented, an abstract class can be designed to implement the interface first, and a default implementation (empty method) can be provided 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
- It is applicable to the situation that an interface does not want to use all its methods
Application and source code analysis of adapter pattern in spring MVC framework
- The HandlerAdapter in spring MVC just uses the adapter pattern
- Spring MVC's process of processing requests
- Analysis of the reasons for using HandlerAdapter: you can see that there are different types of processors and multiple implementation methods, so the calling method is uncertain. If you need to call the Controller method directly, you need to use if else constantly to determine which seed class is to be executed. If you later extend the Controller, you need to modify the later code, which violates the OCP principle
The introduction and use of spring MVC can be seen in the previous section
The following code is located in the doDispatch() method in the DispatchServlet, which maps the Controller through HandlerMapping
After the controller is defined, you need to get the controller, that is, the mappedHandler.getHandler(), getHandlerAdapter() method in the following code returns an adapter. Why return an adapter? Because different handlers use different adapters to call corresponding methods for processing
Let's take a look at how the getHandlerAdapter() method works
From the code, we can see that getHandlerAdapter() returns a HandlerAdapter. Let's see what HandlerAdapter is
Let's see which classes implement this interface
Let's continue to see how the getHandlerAdapter() method returns a HandlerAdapter
private List<HandlerAdapter> handlerAdapters; protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException { // Determine whether handlerAdapters are empty if (this.handlerAdapters != null) { // If not empty, traverse handlerAdapters Iterator var2 = this.handlerAdapters.iterator(); while(var2.hasNext()) { HandlerAdapter adapter = (HandlerAdapter)var2.next(); // After reading the source code of HandlerAdapter, you will find that there is a method in HandlerAdapter // It's supports, and the method here is in HandlerAdapter // This is to determine whether the adapter processor supports this processor if (adapter.supports(handler)) { // If supported, return this adapter processor return adapter; } } } throw new ServletException("No adapter for handler [" + handler + "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler"); }
In fact, this handle is our Controller, which calls the Controller's method by calling the adapter and returns a ModelAndView (the handle() method defined in the HandlerAdapter interface), that is, mv in the above code
summary
The implementation subclass of HandlerAdapter enables each Controller to have a corresponding adapter implementation class, and each Controller has different implementation methods
Do it yourself to implement spring MVC to obtain the source code of the corresponding Controller through the adapter design pattern
Explain:
- Spring defines an adapter interface so that each Controller has a corresponding adapter implementation class
- The adapter replaces the Controller to perform the corresponding method
- When extending the Controller, you only need to add an adapter class to complete the extension of spring MVC
The code has been uploaded to the code cloud. You can visit it if you need, Do it yourself to implement spring MVC