Adapter mode

October 17, 2018 08:50:11

adapter pattern

definition

You have everything I like

Do I have the look you like

If not, I'll give you an adapter, okay

Convert the interface of a class into another interface that the customer wants. The adapter pattern allows classes that cannot work together because of interface incompatibility to work together—— Design patterns: the foundation of Reusable Object-Oriented Software

The adapter pattern is an object structured pattern.

The interface here is not only the interface in the java language, but also refers to the set of method features of a type. It is a logical abstraction.

Usage scenario

The client needs a target interface, but the existing adapter class cannot be reused directly. Because its interface is inconsistent with the target interface, the adapter needs to convert the adapter to the target interface. The premise is that the target interface and the existing adapter adaptee class do the same or similar things, but the interfaces are different and are not easy to modify. If at the beginning of the design, it is best not to consider this design pattern. There is an exception to everything, that is, when designing a new system, we consider using third-party components, because we don't need to modify our own design style in order to cater to it. We can try to use the adapter pattern.

This is an example of an adapter usage scenario:

Sun company disclosed the database connection tool JDBC of Java language in 1996. JDBC enables Java language programs to connect with the database and use SQL language to query and operate data. JDBC provides a general abstract interface for the client. The jdbc driver software of each specific database engine (such as SQL Server, Oracle, MySQL, etc.) is an adapter software between JDBC interface and database engine interface. Corresponding adapter software is required between the abstract JDBC interface and each database engine API, which is the driver prepared for each different database engine.

role

Target role: This is the interface expected by the customer. The target can be a concrete or abstract class or an interface

Adapter role: there is an interface, but it is incompatible with the interface expected by the client.

adapter role: converts an existing interface to a target interface.

classification

There are three types of adapter modes:

  • 1. class adapter pattern
  • 2. object adapter pattern
  • 3. Default adapter pattern, also known as default adapter pattern and interface adapter pattern

Class adapter pattern

The class adapter pattern implements the target interface at compile time. This adapter pattern uses multiple polymorphic interfaces that implement expected interfaces or existing interfaces. Typically, the target interface is created as a pure interface. For example, Java does not support multi inheritance languages.

Illustration

Structure diagram of class adapter pattern:

As shown in the figure above, because java does not have multi class inheritance, it can only implement the Target interface, and the Target can only be an interface. The Adapter implements the Target interface, inherits the Adaptee class, and the Target.operation() is implemented as Adaptee. Specificooperation ().

Client call class adapter:

This figure shows the multi inheritance of the Adapter. Referring to Wikipedia, you can see that when the client calls methodA of the Adapter, it actually calls method1 to methodN inherited from the Adapter.

Code example

A diagram illustrates the requirements:

Well, it's the power adapter. There are two lines above:

Input: 100-240V ~ 0.5A 50-60HZ

Output: 5.2V ==== 2.4A

Our demand is to convert the power input 220V (adapter) to 5V output (target).

Target role (PowerTarget.java):

public interface PowerTarget {
	public int output5V();
}

Power target.

Adapter role (PowerAdaptee.java):

public class PowerAdaptee {
	private int output =  220;
	public int output220V() {
		System.out.println("Power output voltage:" + output);
		return output;
	}
}

Power adapter.

Adapter role (PowerAdapter.java):

public class PowerAdapter extends PowerAdaptee implements PowerTarget{
	
	@Override
	public int output5V() {
		int output = output220V();
		System.out.println("When the power adapter starts working, the output voltage is:" + output);
		output = output/44;
		System.out.println("When the power adapter is finished, the output voltage is:" + output);
		return output;
	}
	
}

The power adapter class implements the power target and inherits the adapter. In fact, without the prompts or logs I printed, the output5V method can be written directly as:

public int output5V() {
		return output220V()/44;
	}

This fits.

Class adapter pattern test class (classadapterpatternetest. Java):

public class ClassAdapterPatternTest {
	
	public static void main(String[] args) {
		PowerTarget target = new PowerAdapter();
		target.output5V();
	}
}

Test results:

Object adapter pattern

The object adapter pattern implements the target interface at run time. In this adapter pattern, the adapter wraps a class instance. In this case, the adapter calls the method that wraps the object instance.

Illustration

Structure diagram of object adapter pattern:

As shown in the figure above, different from the class Adapter mode, the Adapter only implements the interface of the Target and does not inherit the Adaptee, but references the Adaptee in an aggregate manner.

Client call object adapter:

When the client calls the object adapter method methodA, it actually calls the method methodB that creates the adapter instance passed in by the object.

Code example

The code example and the class Adapter pattern are different only from the Adapter class. The other completion is the same, and even the test results are the same. Only the Adapter class is pasted below.

Adapter role (Adapter.java):

public class PowerAdapter implements PowerTarget{
	private PowerAdaptee powerAdaptee;

	public PowerAdapter(PowerAdaptee powerAdaptee) {
		super();
		this.powerAdaptee = powerAdaptee;
	}

	@Override
	public int output5V() {
		int output = powerAdaptee.output220V();
		System.out.println("When the power adapter starts working, the output voltage is:" + output);
		output = output/44;
		System.out.println("When the power adapter is finished, the output voltage is:" + output);
		return output;
	}
	
}

PowerTarget (target role) is implemented, and PowerAdaptee (adapter role) is introduced when creating objects.

Comparison between class adapter pattern and object adapter pattern

advantage

class adapter pattern:

Because the adapter class is a subclass of the adapter class, you can replace some adapter methods in the adapter class, that is, Override (Override), making the adapter more flexible.

object adapter pattern:

An object adapter can adapt multiple different adapter adaptee s to a target, that is, the same adapter can adapt the adapter class and its subclasses to the target interface.

shortcoming

Class adapter mode:

Before java8: the interface has no default method, that is, there is no method that implements specific logic, and does not support multi class inheritance, so there can only be one adapter class.

After java8: the interface has a default method, and the methods in the interface have been implemented. Because the interface is multi inherited, the adapter can be multiple interfaces with default methods, but the interface cannot be instantiated, which is meaningless in fact. One solution is that the interface is full of default methods. The class that implements the interface does nothing but provide a class that can be instantiated. In this way, the adapter adapter class in the class adapter pattern can adapt multiple adapter adaptee classes. This solution is just a theoretical demonstration. Please judge and verify whether it is feasible in practice.

Object adapter mode:

The advantage of the class adapter pattern is the disadvantage of the object adapter pattern, which cannot replace the methods of the adapter class. If you want to modify one or more methods of the adapter class, you have to first create a subclass that inherits from the adapter class, replace the methods of the adapter class, and then adapt the subclass of the adapter as a real adapter. The implementation process is more complex.

Default adapter pattern

When it is not necessary to implement all the methods provided by the interface, an adapter abstract class can be designed to implement the interface and provide default methods for each method in the interface. The subclass of the abstract class can selectively override some method implementation requirements of the parent class. It is applicable to the case that an interface does not want to use all the methods. After Java 8, there can be a default method in the interface, so this default adapter mode is not required. The methods in the interface are set to default and the implementation is empty, which can also achieve the same effect as the default adapter mode.

Illustration

Default adapter mode structure diagram:

The Adapter class implements the Target interface, and the method is empty by default.

Code example

Target role (SampleOperation.java):

public interface SampleOperation {
	public abstract void operation1();
	public abstract void operation2();
	public abstract void operation3();
	public abstract void operation4();
	public abstract void operation5();
}

Contains many operations.

Adapter role (DefaultAdapter.java):

public abstract class DefaultAdapter implements SampleOperation{

	@Override
	public void operation1() {
	}

	@Override
	public void operation2() {
	}

	@Override
	public void operation3() {
	}

	@Override
	public void operation4() {
	}

	@Override
	public void operation5() {
	}
}

All operations are implemented by default

This is the class required to test the default adapter mode (Operator.java):

public class Operator {
	private SampleOperation sampleOperation;
	
	public void addOperation(SampleOperation sampleOperation) {
		this.sampleOperation = sampleOperation;
	}

	public void operation1() {
		sampleOperation.operation1();
	}

	public void operation2() {
		sampleOperation.operation2();
	}

	public void operation3() {
		sampleOperation.operation3();
	}

	public void operation4() {
		sampleOperation.operation4();
	}

	public void operation5() {
		sampleOperation.operation5();
	}
}

Default adapter pattern test class (DefaultAdapterTest.java):

public class DefaultAdapterTest {

	public static void main(String[] args) {
		
		// 1. It was originally intended to implement the operations of all operation classes
		Operator operator1 = new Operator();
		operator1.addOperation(new SampleOperation() {

			@Override
			public void operation1() {}

			@Override
			public void operation2() {
				System.out.println("Operation 2");
			}

			@Override
			public void operation3() {}

			@Override
			public void operation4() {}

			@Override
			public void operation5() {}
			
		});
		operator1.operation2();
		
		// 2. Using the default adapter only needs to implement the required interface methods
		Operator operator2 = new Operator();
		operator2.addOperation(new DefaultAdapter() {
			
			@Override
			public void operation2() {
				System.out.println("Operation 2");
			}
		});
		operator2.operation2();
	}
}

The test class needs to perform operation 2. When operator 1 adds a SampleOperation, it needs to implement all methods in the interface. When operator 2 adds a SampleOperation, it only needs to add its own operations through the DefaultAdapter adapter. There is no doubt that the test results are the same.

advantage

1. Reusability: the system needs to use existing classes, and the functions meet the system requirements, but the interface of this class does not meet the system requirements. Solve the incompatibility problem through the adapter mode to reuse these function classes.

2. Scalability: the adapter enables the system to expand the functions of the system in one more way

3. Coupling: decoupling to some extent

shortcoming

Excessive use of adapters increases the difficulty of system understanding.

summary

This paper mainly introduces three adapter modes, which are essentially the conversion of existing incompatible interfaces to required interfaces.

Class adapter pattern to transform by inheriting existing classes.

Object adapter pattern, which is transformed by aggregating object instances.

Interface adapter mode to implement interface conversion.

The adapter pattern is used when the existing classes and systems are not easy to modify. Use the adapter pattern carefully at the beginning of system design.

finish

October 18, 2018 14:53:33

Posted by carmasha on Mon, 29 Nov 2021 04:38:38 -0800