After the proxy mode and then to the adapter mode, want to see the previous also have oh. It is constantly updated. Let’s go for it, guys. Fuck him.

Like a sentence: “eight hours for life, eight hours for development “.

Hello, if you like, please stick to it!!

‘😁

An old photo, trance reminds of the old

Design Mode series:

  • Java Design pattern – singleton pattern
  • Java Design Pattern – Factory Pattern (1) Simple Factory pattern
  • Java Design Pattern – Factory Pattern (2) Factory method pattern
  • Java Design Pattern – Factory Pattern (3) Abstract Factory pattern
  • Java Design pattern – Builder pattern
  • Java Design pattern – Proxy pattern
  • Java Design pattern – Adapter pattern
  • Java Design pattern – Decorator pattern
  • Java Design pattern – Bridge pattern
  • Java Design pattern – Appearance pattern
  • Java Design pattern – Composite pattern
  • Java Design pattern – Share meta pattern
  • Java Design Pattern – Template method pattern
  • Java Design pattern – Policy pattern
  • Java Design pattern – Chain of Responsibility pattern
  • Java Design Pattern – The Mediator pattern
  • Java Design Pattern – Observer Pattern (publish/subscribe pattern)
  • Continuously updated…

One, foreword

1) overview

In real life, there are often instances where two objects cannot work together because of incompatible interfaces, and a third party is needed to adapt. For example, a Chinese speaker needs a translator to talk to an English speaker, a power adapter to connect a dc laptop to AC power, and a card reader to access a camera’s SD memory card from a computer. Or something like this:

It can also occur in software design where components with certain business functions that need to be developed already exist in an existing component library, but they are incompatible with the current system’s interface specifications, and the adapter pattern is a good solution if the cost of redeveloping these components is high.

2) introduction

An Adapter pattern is defined as follows: Converts the interface of one class into another interface that the customer expects, so that classes that would otherwise not work together can work together because of interface incompatibility. Adapter pattern is divided into class structure pattern and object structure pattern, the former class coupling degree is higher than the latter, and requires programmers to understand the internal structure of relevant components in the existing component library, so the application is relatively less.

The purpose of the Adapter pattern is to retain the services provided by existing classes and provide interfaces to customers to meet their expectations.

3) Character structure

Adapter patterns contain the following key roles:

  • Target interface: The interface expected by the current system service. It can be an abstract class or interface.
  • Adaptee class: It is a component interface in an existing component library that is accessed and adapted.
  • Adapter class: It is a converter that converts the Adapter interface into the target interface by inheriting or referencing the Adapter’s object, allowing customers to access the Adapter in the format of the target interface.

4) Usage scenarios

The Adapter pattern (Adapter) typically applies to the following scenarios.

  • The previously developed system has classes that meet the functional requirements of the new system, but their interfaces are inconsistent with those of the new system. (It’s called adding one layer. If one layer doesn’t work, add two) 😁
  • Use a component provided by a third party, but the interface definition of the component is different from the interface definition required by you.

Class adapter

When the customer defines the desired behavior in the interface, we can apply the adapter pattern, provide a class that implements the interface, and extend the existing class to achieve adaptation by creating subclasses.

Implementation: Define an adapter class to implement the business interface of the current system, while inheriting components that already exist in the existing component library.

Let’s take the previous picture as an example: When Chinese people go to Europe, they need to charge their computers, but because their computers have two forks and European computers have three forks, they need a converter in the middle.

2.1, code,

Target interface: the European tri-fork in the figure

public interface EuropeSocket {
    /** European-style trifecta power socket */
    String useEuropesocket(a);
}

// Euclidean trigeminal implementation class
public class EuropeSocketImpl implements EuropeSocket {

    @Override
    public String useEuropesocket(a) {
        String msg ="Use the European three-pronged charge.";
        returnmsg; }}Copy the code

An Adaptee is a Chinese double fork

public interface ChineseSocket {
    /** * Use Chinese dual fork charging *@return* /
    String useChineseSocket(a);
}

// Chinese plug implementation class
public class ChineseSocketImpl implements ChineseSocket {

    @Override
    public String useChineseSocket(a) {
        String msg="Charge with Chinese dual forks.";
        returnmsg; }}Copy the code

Adapter class:

/** * Define adapter class Chinese double fork to European triple fork ** /
public class ChineseAdapterEurope extends EuropeSocketImpl implements ChineseSocket {

    @Override
    public String useChineseSocket(a) {
        System.out.println("Complete the conversion using the converter.");
        returnuseEuropesocket(); }}Copy the code

The computer class

public class Computer {

    public String useChineseSocket(ChineseSocket chineseSocket) {
        if(chineseSocket == null) {
            throw new NullPointerException("sd card null");
        }
        returnchineseSocket.useChineseSocket(); }}Copy the code

Testing:

public class Client {
    public static void main(String[] args) {
        Computer computer = new Computer();
        ChineseSocket chineseSocket = new ChineseSocketImpl();
        System.out.println(computer.useChineseSocket(chineseSocket));
        System.out.println("-- -- -- -- -- -- -- -- -- -- -- --");
        ChineseAdapterEurope adapter = new ChineseAdapterEurope();
        System.out.println(computer.useChineseSocket(adapter));
        / output: * * * * using Chinese double fork charge * -- -- -- -- -- -- -- -- -- -- -- - * use converter conversion complete * with European trigeminal charge * /}}Copy the code

The above code simply demonstrates the use of the adapter.

Note: The class adapter pattern violates the composite reuse principle. Class adapters are available if the client class has an interface specification and not otherwise.

Object adapter

The object adapter reduces bad coupling between code through composition in addition to satisfying “user-expected interfaces.” Object adaptation is recommended at work.

Implementation: The object adapter pattern can be used to introduce components already implemented in an existing component library into an adapter class that also implements the business interface of the current system.

So they’re going to do the same thing. The code actually differs very little

code

Target interface: the European tri-fork in the figure

public interface EuropeSocket {
    /** European-style trifecta power socket */
    String useEuropesocket(a);
}

// Euclidean trigeminal implementation class
public class EuropeSocketImpl implements EuropeSocket {

    @Override
    public String useEuropesocket(a) {
        String msg ="Use the European three-pronged charge.";
        returnmsg; }}Copy the code

An Adaptee is a Chinese double fork

public interface ChineseSocket {
    /** * Use Chinese dual fork charging *@return* /
    String useChineseSocket(a);
}

// Chinese plug implementation class
public class ChineseSocketImpl implements ChineseSocket {

    @Override
    public String useChineseSocket(a) {
        String msg="Charge with Chinese dual forks.";
        returnmsg; }}Copy the code

Adapter class: This is how some changes have been made in this Adapter from inheritance to member variables

public class ChineseAdapterEurope implements ChineseSocket {

    private EuropeSocket europeSocket;

    public ChineseAdapterEurope(EuropeSocket europeSocket) {
        this.europeSocket = europeSocket;
    }

    @Override
    public String useChineseSocket(a) {
        System.out.println("Complete the conversion using the converter.");
        returneuropeSocket.useEuropesocket(); }}Copy the code

The computer class

public class Computer {

    public String useChineseSocket(ChineseSocket chineseSocket) {
        if(chineseSocket == null) {
            throw new NullPointerException("sd card null");
        }
        returnchineseSocket.useChineseSocket(); }}Copy the code

Testing:

public class Client {
    public static void main(String[] args) {
        Computer computer = new Computer();
        ChineseSocket chineseSocket = new ChineseSocketImpl();
        System.out.println(computer.useChineseSocket(chineseSocket));

        System.out.println("-- -- -- -- -- -- -- -- -- -- -- --");
        // This has been changed
        EuropeSocket europeSocket=new EuropeSocketImpl();
        ChineseAdapterEurope adapter = new ChineseAdapterEurope(europeSocket);
        System.out.println(computer.useChineseSocket(adapter));
        / output: * * * * using Chinese double fork charge * -- -- -- -- -- -- -- -- -- -- -- - * use converter conversion complete * with European trigeminal charge * /}}Copy the code

This is the object adapter,

Suitable for solving common problems:

  • The need is there, but it doesn’t work and can’t be modified for a short time. That is, making a feature suitable for different environments.
  • In development, the data and behavior of the system match, but the interface does not match, you can consider the adapter.
  • If you want to reuse some existing classes, but the interface is not consistent with the requirements of the reuse environment, you should consider using the adapter pattern. (Use an existing class, but its interface (that is, methods) is different from what is needed)

extension

The Adapter pattern (Adapter) can be extended to the bidirectional Adapter pattern. The bidirectional Adapter class can convert an Adapter interface into a target interface or a target interface into an Adapter interface.

Four,

Advantages:

  • The client can transparently invoke the target interface through the adapter.
  • By reusing existing classes, programmers can reuse existing adapter classes without modifying the original code. Improved class reuse
  • Decoupling the target class from the adapter class solves the problem of interface inconsistency between the target class and the adapter class. Flexibility is good
  • You can have any two unrelated classes run together
  • It complies with the on/off principle in many business scenarios

Its disadvantages are:

  • The adapter writing process needs to be considered in the context of business scenarios and can increase system complexity.
  • Increase code reading difficulty, reduce code readability, excessive use of adapters will make the system code messy. (Such as: clearly see the call is A interface, in fact, internal adaptation into the implementation of B interface, A system if too much of this situation, is tantamount to A disaster)

Five, talk to yourself

You roll me roll, everyone roll, when this road is the end ah. 😇 (or directly to heaven)

Sometimes I want to stop and have a rest. It’s hard to stick to one thing all the time. 😁

Hi, if you happen to read this article and think it’s good for you, give it a thumbs up and let me feel the joy of sharing, Crab. 🤗

If there is something wrong, please don’t add to it!!

Similarly, if there is any doubt, please leave a message or private message, we will reply to you in the first time.

Ongoing update