Adapter pattern and its application in spring MVC

Keywords: Spring Java

Preceding text

Introduction to spring MVC

SpringMVC (Advanced parameter, List type binding, @ RequestMapping, qualified request method, and Controller method return value)

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

196 original articles published, 961 praised, 190000 visitors+
Private letter follow

Posted by Integra_grrl on Tue, 10 Mar 2020 19:10:46 -0700