This is the 14th day of my participation in the August Text Challenge.More challenges in August

Adapter mode

Translate the interface of a class into another interface that the customer wants. The adapter pattern makes it possible for classes to work together that would otherwise not work because of interface incompatibilities.

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.
  • Decoupling the target class from the adapter class solves the problem of interface inconsistency between the target class and the adapter class.
  • It complies with the on/off principle in many business scenarios.

disadvantages

  • 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

structure

  1. Target interface: The interface expected by the current system service. It can be an abstract class or interface.
  2. Adaptee class: It is a component interface in an existing component library that is accessed and adapted.
  3. 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.

  • Conflict: Target expects to call the Request method, while Adaptee does not (this is called incompatibility).

  • Solution: To enable Target to use the SpecificRequest method in the Adaptee class, we provide an intermediate Adapter class (inheriting the Target interface from the Adaptee) to connect the Adaptee API to the Target API.

demo

The class adapter

1. Define the target interface

public interface TypeCChargerTarget {
    void useTypeCCharger(a);
}
Copy the code

2. Define the target interface implementation class

public class TypeCChargerTargetImpl implements TypeCChargerTarget{
    @Override
    public void useTypeCCharger(a) {
        System.out.println("Charge with the Type-C cable!"); }}Copy the code

3. Define the adapter interface

public interface TraditionChargerAdaptee {
    void useTraditionCharger(a);
}
Copy the code

4. Define the adapter interface implementation class

public class TraditionChargerAdapteeImpl implements TraditionChargerAdaptee {
    @Override
    public void useTraditionCharger(a) {
        System.out.println("Use a traditional charging cable!"); }}Copy the code

5. Define the adapter

public class Adapter extends TraditionChargerAdapteeImpl implements TypeCChargerTarget {
    @Override
    public void useTypeCCharger(a) {
        System.out.println("Change charge cable");
        super.useTraditionCharger(); }}Copy the code

6. Client

public class Client {
    public static void main(String[] args) {
        TypeCChargerTargetImpl typeCChargerTargetImpl = new TypeCChargerTargetImpl();
        typeCChargerTargetImpl.useTypeCCharger();
        Adapter adapter = new Adapter();
        adapter.useTypeCCharger();
        // Use the type-c cable to charge!
        // Change the charging cable
        // Use a traditional charging cable!}}Copy the code

This is the class adapter: by defining the adapter to implement the current business interface, while inheriting the existing interface for transformation;

Object adapter

In contrast, there are object adapters; Look at the code differences and then compare them

1. Modify the adapter

public class Adapter  implements TypeCChargerTarget {
    private TraditionChargerAdapteeImpl traditionChargerAdapteeImpl;
    public Adapter(TraditionChargerAdapteeImpl traditionChargerAdapteeImpl) {
        this.traditionChargerAdapteeImpl = traditionChargerAdapteeImpl;
    }
    @Override
    public void useTypeCCharger(a) {
        System.out.println("Change charge cable"); traditionChargerAdapteeImpl.useTraditionCharger(); }}Copy the code

2. Modify the client

public class Client {
    public static void main(String[] args) {
        TypeCChargerTargetImpl typeCChargerTargetImpl = new TypeCChargerTargetImpl();
        typeCChargerTargetImpl.useTypeCCharger();
        Adapter adapter = new Adapter(new TraditionChargerAdapteeImpl());
        adapter.useTypeCCharger();
        // Use the type-c cable to charge!
        // Change the charging cable
        // Use a traditional charging cable!}}Copy the code

There are two changes

  1. Adapter classes do not need to inherit from existing implementation interfaces
  2. The client explicitly specifies the existing implementation interface that needs to be transformed

Therefore, two differences can be summarized:

1, class Adapter Adapter and Adaptee is the inheritance relationship, but Java is a class can only inherit a class, so each class Adapter can only be adapted to one. An object adapter defines an implementation interface class as a member variable that can be adapted for multiple purposes

Class adapters use inheritance, resulting in high coupling and insufficient flexibility; 3. The adaptor of an object needs to introduce an object instance. Therefore, the object to be adapted must be specified before adaptation, which is relatively complicated.

conclusion

The purpose of the adapter is to provide the expected service to the customer without changing the original interface, so no matter what kind of adapter, it can be satisfied, of course, I personally recommend the object of the adapter, relatively flexible, suitable for not limited to one implementation.