Daily design mode - adapter mode

definition

Adapter Pattern is a bridge between two incompatible interfaces. This design pattern belongs to structural mode, which combines the functions of two independent interfaces. Converting the interface of a class into another interface desired by the customer is what the adapter needs to do. The adapter mode enables those classes that cannot work together due to incompatible interfaces to work together.

Usage scenario

1. The system needs to use existing classes, but the interface of existing classes does not meet the needs of the system (core requirements).
2. Insert one class into another through interface conversion. (an example is more vivid, such as tigers and birds. Now we need a flying tiger. Without increasing the demand of entities, we need to add an adapter to contain a tiger object and realize the flying interface).

realization

There are usually two adapter modes: class adapter and object adapter. Their core idea is to extend the classes of existing interfaces to achieve the target interface expected by customers.
The function of the adapter is to quickly praise the function of the existing interface rather than replace it. Class adapters can only be used in specific scenarios.
The object adapter holds an instance of an existing interface class, extends its functions, realizes the target interface, and gives priority to combination rather than inheritance, which will make the code easier to maintain. We only need to extend the corresponding functions without paying attention to their specific implementation.

understand

FileInputStream fis = new FileInputStream("qe");
InputStreamReader isrAdapter = new InputStreamReader(fis);
BufferedReader bf = new BufferedReader(isrAdapter);

The BufferedReader here needs to read the file character stream for work. Reading the file character stream is part of the customer's requirements. However, according to the existing interface, you can only read the byte stream if you want to read the file. FileInputStream is a specific implementation of the existing interface, and the InputStreamReader here is an adapter, It is used to read the file byte stream and extend it to the character stream to meet the needs of customers. This is a standard object adapter mode.

code

Taking the general case of power supply adaptation as an example, the goal of charging the existing 110V power supply is to charge at 220V. We need an adapter class to realize the function of 220V charging on the basis of the existing 110V.

Class Adapter

public interface Target220V {
    /**
     * Target interface to realize 220V charging
     */
    void chargeBy220V();
}
public interface Adaptee {
    /**
     * The existing interface can only realize 110V charging
     */
    void chargeBy110V();
}
public class AmericanCharge implements Adaptee{
    /**
     * Existing American electric appliances realize 110V charging
     */
    @Override
    public void chargeBy110V() {
        System.out.println("American Charge By 110V");
    }
}
public class Adapter extends AmericanCharge implements Target220V{
    /**
     * Class adapter, which extends the existing interface by inheriting the existing interface
     */
    @Override
    public void chargeBy220V() {
        super.chargeBy110V();
        System.out.println("110V Adjust to 220 V");
    }
}

test

public class User {
    public static void main(String[] args) {
        new Adapter().chargeBy220V();
    }
}

output

American Charge By 110V
110V Adjust to 220 V

object adapter

The target interface is the same as the existing interface. The differences of adapters are shown here

public class ObjectAdapter implements Target220V{
    Adaptee adaptee; //Holds a reference to an existing concrete implementation object

    public ObjectAdapter(Adaptee adaptee){
        this.adaptee = adaptee;
    }
    @Override
    public void chargeBy220V() {
        this.adaptee.chargeBy110V();
        System.out.println("110V Adjust to 220 V---2");
    }
}

test

public class User1 {
    public static void main(String[] args) {
        // There is a 110V American charging port, but it cannot be used directly
        Adaptee adaptee = new AmericanCharge();

        //This port is provided to the adapter, which is converted to 220V
        ObjectAdapter adapter = new ObjectAdapter(adaptee);
        adapter.chargeBy220V();
    }
}

output

American Charge By 110V
110V Adjust to 220 V---2

Usage analysis

advantage:

  1. You can let any two classes that are not associated run together.
  2. It improves the reuse of classes and can unify multiple different interfaces.
  3. Hide the existing interface implementation class to increase the transparency of the class.
  4. High flexibility and free adaptation.

Disadvantages:

  1. Excessive use of adapters will make the system very messy and difficult to grasp as A whole. For example, it is obvious that the A interface is called, but in fact, it is internally adapted to the implementation of B interface. If there are too many such situations in A system, it is tantamount to A disaster. Therefore, if it is not necessary, you can reconstruct the system directly without using the adapter.
  2. Some adaptation work can be very difficult, such as making the house fly.

When we are motivated to modify the interface of a functioning system, we should consider using the adapter mode.

Keywords: Java Design Pattern

Added by bampot on Wed, 02 Feb 2022 15:19:10 +0200