Design pattern - adapter pattern

Keywords: Mobile socket Java

Adapter mode

In life, there are two, three and round charging plugs. If you want to make these plugs work, you need a multi-functional adapter

Basic introduction

Adapter Pattern is a kind of structural pattern. It can 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. There are three types of adapter patterns: class Adapter Pattern, object Adapter Pattern and interface Adapter Pattern.

Working principle

  1. Make classes that are not compatible with the original interface compatible
  2. From the user's point of view, there is no adapter, which is decoupled
  3. The user calls the target interface method transformed by the adapter, and the adapter calls the relevant interface method of the adapter

Class adapter pattern

Realization principle

The Adapter class inherits the src class, implements the dst interface, and completes the adaptation of src to dst.

case

The output voltage of the socket (Voltage220V) is 220V, and the output voltage of the charging plug (Voltage5V) is 5V. In this case, an adapter is needed to convert the voltage to charge the mobile Phone

code implementation

Power output voltage is 220V

public class Voltage220V {
    public int output220V() {
        int src = 220;
        System.out.println("Power output" + src + "V");
        return src;
    }
}

Charger output voltage is 5V

public interface Voltage5V {
    int output5V();
}

Adapter needs to change from 220V to 5V

public class VoltageAdapter extends Voltage220V implements Voltage5V {
    @Override
    public int output5V() {
        int src = super.output220V();
        int dst = src / 44;
        System.out.println("Convert to" + dst + "V");
        return dst;
    }
}

The mobile phone receives 5V voltage and judges whether the voltage is 5V

public class Phone {
    public static void charging(Voltage5V voltage5V){
        int v = voltage5V.output5V();
        if(v == 5){
            System.out.println("Receiving voltage is 5 V,Normal charging");
        }else if(v > 5){
            System.out.println("Voltage above 5 V,Unable to charge");
        }
    }
}

test method

@Test
public void test01(){
    System.out.println("====Class adapter pattern====");
    Phone.charging(new VoltageAdapter());
}

Operation result

====Class adapter pattern====
Power output 220V
 Convert to 5V
 Receiving voltage is 5V, normal charging

Analysis

  • Because Java is a single inheritance mechanism, the class adapter pattern has some limitations
  • Methods of src class will be exposed in Adapter, which increases the cost of use
  • Because it inherits the src class, it can override the method of the parent class, which makes the Adapter more flexible

Object Adapter Pattern

Realization principle

The basic idea is the same as the Adapter pattern of the class, except that the Adapter class is modified and the inheritance relationship is replaced by the aggregation relationship

code implementation

Follow the previous code, create a new Adapter, just replace the original Adapter inherited src class with an aggregate relationship

public class VoltageAdapter2 implements Voltage5V {

    private Voltage220V voltage220V;

    public VoltageAdapter2(){
        this.voltage220V = new Voltage220V();
    }

    @Override
    public int output5V() {
        int src = this.voltage220V.output220V();
        int dst = src / 44;
        return dst;
    }
}

test method

@Test
public void test02(){
    System.out.println("====Object Adapter Pattern ====");
    Phone.charging(new VoltageAdapter2(new Voltage220V()));
}

Operation result

====Object adapter mode====
Power output 220V
 Convert to 5V
 Receiving voltage is 5V, normal charging

Interface adapter mode

The interface adapter pattern can also be called the default adapter pattern. When you do not need to implement all the methods of the interface, you can first design an abstract class to implement the interface, and provide a default implementation for each method of the interface. Then the subclass of the abstract class can selectively cover 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

code implementation

Write an interface that defines some methods

public interface InterfaceMethod {
    void m1();
    void m2();
    void m3();
    void m4();
}

An abstract class that implements the interface

public abstract class AbstractAdapter implements InterfaceMethod {
    @Override
    public void m1() {
    }

    @Override
    public void m2() {
    }

    @Override
    public void m3() {
    }

    @Override
    public void m4() {
    }
}

test method

@Test
public void test(){
    //How to use anonymous inner class
    AbstractAdapter adapter = new AbstractAdapter() {
        @Override
        public void m1() {
            System.out.println("I want to use it. m1 Method");
        }
    };
    adapter.m1();
}

Operation result

I want to use m1 method

summary

  • The three naming methods are based on how src is given to the Adapter (the form in the Adapter).

    • Class Adapter: given as a class. In Adapter, src is treated as a class and inherited

    • Object Adapter: in the Adapter, src is used as an object to hold

    • Interface Adapter: in the Adapter, src is used as an interface to implement

  • The most important function of Adapter mode is to integrate the incompatible interfaces.

Posted by drranch on Fri, 27 Mar 2020 11:04:06 -0700