Adapter mode of design mode

1 Overview

Adapter mode: convert the interface of a class into another interface desired by the requirements, so that those classes that cannot work together due to interface incompatibility can work together

classification

  • The class adapter pattern class has a high degree of coupling
  • Object Adapter Pattern

2 Structure

The Adapter pattern contains the following main roles:

  • Target interface: the interface expected by the current system business. It can be an abstract class or interface.
  • Adapter class: it is the component interface in the existing component library accessed and adapted.
  • Adapter class: it is a converter that converts the adapter interface into the target interface by inheriting or referencing the adapter object, so that customers can access the adapter according to the format of the target interface.

Type 3 adapter mode

Demand objectives:

Define an adapter class to implement the business interface of the current system and inherit the existing components in the existing component library

This mode can be used if you want to read the new TF Card in order to read the SD card by the computer

Computer

public class Computer {

    public String readSD(SDCard sdCard) {
        if(sdCard == null) {
            throw new NullPointerException("sd card null");
        }
        return sdCard.readSD();
    }
}

SD card interface

public interface SDCard {
    // Method of reading SD card
    String readSD();
    // Write SD card function
    void writeSD(String msg);
}

SD card implementation class

public class SDCardImpl implements SDCard {
    public String readSD() {
        String msg = "read SDCard";
        return msg;
    }

    public void writeSD(String msg) {
        System.out.println("write msg : " + msg);
    }
}

TF card interface

public interface TFCard {
    // Method of reading TF Card
    String readTF();
    // Write TF card function
    void writeTF(String msg);
}

TF implementation class

public class TFCardImpl implements TFCard {

    public String readTF() {
        String msg ="read TFCard";
        return msg;
    }

    public void writeTF(String msg) {
        System.out.println("write msg : " + msg);
    }
}

adapter class

public class SDAdapterTF extends TFCardImpl implements SDCard {

    public String readSD() {
        System.out.println("adapter read tf card ");
        return readTF();
    }

    public void writeSD(String msg) {
        System.out.println("adapter write tf card");
        writeTF(msg);
    }
}

Test class

public class Client {
    public static void main(String[] args) {
        Computer computer = new Computer();
        SDCard sdCard = new SDCardImpl();
        System.out.println(computer.readSD(sdCard));

        System.out.println("------------");

        SDAdapterTF adapter = new SDAdapterTF();
        System.out.println(computer.readSD(adapter));
    }
}

/*
Operation results:
read SDCard
------------
adapter read tf card 
read TFCard
*/

As mentioned above, the class adapter pattern violates the principle of composite reuse. Class adapter is available when the client class has an interface specification, otherwise it is not available

4 object adapter mode

Demand objectives:

The object adapter mode can introduce the implemented components in the existing component library into the adapter class, which implements the business interface of the current system at the same time

Retrofit adapter class

adapter class

public class SDAdapterTF  implements SDCard {

    private TFCard tfCard;

    public SDAdapterTF(TFCard tfCard) {
        this.tfCard = tfCard;
    }

    public String readSD() {
        System.out.println("adapter read tf card ");
        return tfCard.readTF();
    }

    public void writeSD(String msg) {
        System.out.println("adapter write tf card");
        tfCard.writeTF(msg);
    }
}

Test class

public class Client {
    public static void main(String[] args) {
        Computer computer = new Computer();
        SDCard sdCard = new SDCardImpl();
        System.out.println(computer.readSD(sdCard));

        System.out.println("------------");

        TFCard tfCard = new TFCardImpl();
        SDAdapterTF adapter = new SDAdapterTF(tfCard);
        System.out.println(computer.readSD(adapter));
    }
}

/*
Operation results:
read SDCard
------------
adapter read tf card 
read TFCard

*/

In addition, another Adapter mode is the interface Adapter mode. When you don't want to implement all the methods in an interface, you can create an abstract class Adapter to implement all the methods. At this time, we only need to inherit the abstract class

Interface adapter mode

A interface

public interface A {
    
    String read();
    
    void write();
    
    String listen();
}

Abstract class B

public abstract class B implements A {

    @Override
    public String read() {
        System.out.println("Read data");
        return null;
    }

    @Override
    public void write() {

    }

    @Override
    public String listen() {
        return null;
    }
}

Implementation class C

public class C extends B {
    @Override
    public String read() {
        return super.read();
    }
}

5 usage scenarios

  • The previously developed system has classes that meet the functional requirements of the new system, but its interface is inconsistent with that of the new system.
  • Use the components provided by the third party, but the component interface definition is different from that required by yourself.

6 JDK source code analysis

The adaptation of Reader (character stream) and InputStream (byte stream) uses inputstreamreader, which inherits from Java The reader in the IO package gives the implementation of the abstract and unimplemented methods

From the code:

  • InputStreamReader encapsulates the StreamDecoder that also implements the Reader.
  • StreamDecoder is not the content of Java SE API, but its own implementation given by Sun JDK. But we know that they encapsulate the InputStream class in the construction method, and decode and convert between byte stream and character stream through this class

InputStreamReader converts InputStream byte stream class to Reader character stream. As can be seen from the implementation class relationship structure in Sun JDK above, the design and implementation of StreamDecoder actually adopts the adapter mode

Tags: Java Design Pattern

Posted by MG-WebDesigns on Mon, 16 May 2022 22:58:25 +0300