The adapter pattern, which converts the interface of one class into another so that incompatible classes can work together, is a structural design pattern. It can be said that the adapter pattern primarily addresses functional compatibility issues.

As we all know, in daily life, our power sockets are 220V AC, so charging a mobile phone requires a power adapter for conversion, and the power adapter of this mobile phone (i.e. the charger) is playing a role of conversion.

Let’s simulate this scenario in code.

1. Create 220V AC (original function)

Create 220V AC as follows:

package fun.swsk33site.adapter.model;

/** * 220V AC */
public class AC220V {

   /** * Connect ac power and obtain **@return220V ac */ is obtained
   public int output(a) {
      return 220; }}Copy the code

This class can get 220V current! But this can’t be used directly, so it needs to be transformed.

2. Create the adapter interface and implement the individual adapters (adapters for converting the original functionality)

There is not only one kind of power adapter, for example, Huawei 40W quick charge and Apple charger are not the same, so we need to abstract the adapter as an interface first, and then to achieve each adapter:

package fun.swsk33site.adapter.adapter;

/** * Power adapter interface */
public interface PowerAdapter {

   /** * Convert the input power **@returnCurrent after conversion */
   int doConvert(a);

}
Copy the code

Huawei 40W quick charging adapter:

package fun.swsk33site.adapter.adapter.impl;

import fun.swsk33site.adapter.adapter.PowerAdapter;
import fun.swsk33site.adapter.model.AC220V;

/** * Huawei 40W quick charge adapter */
public class HuaweiFastCharge implements PowerAdapter {

   private AC220V ac220V;

   /** * Constructor dependency injection (analog Huawei charger connected to 220V AC) **@paramAc power of ac220V */
   public HuaweiFastCharge(AC220V ac220V) {
      this.ac220V = ac220V;
   }

   @Override
   public int doConvert(a) {
      // Convert to 10V current
      int output = ac220V.output() / 22;
      returnoutput; }}Copy the code

Implement apple 5W mobile phone charger:

package fun.swsk33site.adapter.adapter.impl;

import fun.swsk33site.adapter.adapter.PowerAdapter;
import fun.swsk33site.adapter.model.AC220V;

/** * Apple 5V phone charger */
public class AppleCharge implements PowerAdapter {

   private AC220V ac220V;

   /** * Constructor dependency injection (analog Apple charger connected to 220V power supply) **@param ac220V
    */
   public AppleCharge(AC220V ac220V) {
      this.ac220V = ac220V;
   }

   @Override
   public int doConvert(a) {
      int output = ac220V.output() / 44;
      returnoutput; }}Copy the code

As you can see, different adapters have transformed the original functionality, but in different ways.

3. Use adapters

Let’s try one in the main method:

PowerAdapter huaweiAdapter = new HuaweiFastCharge(new AC220V());
System.out.println("Huawei charger, get voltage:" + huaweiAdapter.doConvert());
PowerAdapter appleAdapter = new AppleCharge(new AC220V());
System.out.println("Apple charger, get voltage:" + appleAdapter.doConvert());
Copy the code

Results:

4,

The visible adapter pattern is primarily a matter of transformation and compatibility. The input of the adapter is the original function (220V AC), and the output is compatible after the conversion function (10V or 5V DC), as for the conversion logic, of course, is put in the adapter class! It’s actually pretty simple.

Generally applicable to the following scenarios:

  • An existing class does not match the requirement
  • After the software system is upgraded, different functions cause incompatibility problems

In fact, many of our websites have login functions, in addition to password login, but also QQ or wechat login. How are so many login methods organized? Use the adapter pattern + policy pattern to do this. This login form is rich, but the processing logic of the background almost need not change, in line with the open and closed principle.

The class diagram for the above example is as follows:

Sample repository address