1. Basic Concepts

Adapter mode mainly solves the problem that some “existing objects” are often put into a new environment in a software system, and the interface required by the new environment is not satisfied by the existing objects.

Adapter Pattern is a kind of structural design Pattern. The definition of Adapter Pattern is to transform the interface of one class into another interface that the customer wants, so that those classes that cannot work together due to incompatible interfaces can work together.

Second, model introduction

  • Target: indicates the Target interface, the expected interface, and the interface expected by the current system service. It can be an abstract class or interface.
  • Adaptee: Component interfaces in existing component libraries that are accessed and adapted.
  • Adapter: The core role of the Adapter pattern. The other two roles are existing roles. The Adapter role needs to be newly established. Adaptee and Target interfaces are adapted.

Iii. Structure and implementation of the pattern

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.

Class 3.1 Structural pattern

package adapter; // Target interface Target {public void request(); } class Adaptee {public void specificRequest(){system.out.println (" The business code in the adapter is called! ); Class class Adapter extends Adaptee implements Target {public void Request() {specificRequest(); }} public class ClassAdapterTest {public static void main(String[] args) {system.out.println (" ClassAdapterTest: "); Target target = new ClassAdapter(); target.request(); }}Copy the code

The running results of the program are as follows:

Class adapter pattern test: the business code in the adapter is called!Copy the code

Advantages: easy to use, simplified code, no need to introduce object instances

Disadvantages: High coupling, low flexibility. Using object inheritance is statically defined

3.2 Object adapter pattern

package adapter; // Target interface Target {public void request(); } class Adaptee {public void specificRequest() {system.out.println (" The business code in the adapter is called! ); Class class Adapter extends Adaptee implements Target {public void Request() {specificRequest(); }} public class ClassAdapterTest {public static void main(String[] args) {system.out.println (" ClassAdapterTest: "); Target target = new ClassAdapter(); target.request(); }}Copy the code

The running results of the program are as follows:

Object adapter pattern test: business code in adapter is invoked!Copy the code

Advantages: high flexibility, low coupling, using the “object combination” way, is a dynamic combination

Disadvantages: Complex use, need to introduce object instances

Note: In the object adapter pattern, the code for the “target interface” and “adapter class” is the same as in the adapter pattern. You only need to modify the adapter class and the client code.

4. Application examples of the pattern

【 Example 1】 Use Adapter mode to simulate the engine of new energy vehicle.

Analysis: The engines of new energy vehicles include Electric Motor and Optical Motor, and various engines have different driving methods. For example, the driving method of Electric engine electricDrive() is driven by Electric energy. The opticalDrive method opticalDrive() is driven by light energy, and they are the adapters that are accessed in the adapter mode.

The client wants to use a unified engine drive method drive() to access the two engines, so it must define a unified target interface Motor, and then define an Electric Adapter and an Optical Adapter to accommodate the two engines.

We put the name of the adapter for the new energy engine that the client wants to access in an XML configuration file (download the XML file here) that the client can read through the object generator class ReadXML. In this way, the client can use any new energy engine to drive the car through the Motor interface. The following figure shows its structure.

package adapter; Interface Motor {public void drive(); } // adapter 1: ElectricMotor class ElectricMotor {public void electricDrive() {system.out.println (" electricDrive "); ); Class OpticalMotor {public void opticalDrive() {system.out.println (" opticalDrive "); ); ElectricAdapter implements Motor {private ElectricMotor emotor; public ElectricAdapter() { emotor=new ElectricMotor(); } public void drive() { emotor.electricDrive(); Class OpticalAdapter implements Motor {private OpticalMotor omotor; public OpticalAdapter() { omotor=new OpticalMotor(); } public void drive() { omotor.opticalDrive(); Public class MotorAdapterTest {public static void main(String[] args) {system.out.println (" adapter mode test: "); Motor motor=(Motor)ReadXML.getObject(); motor.drive(); }}Copy the code
package adapter; import javax.xml.parsers.*; import org.w3c.dom.*; import java.io.*; class ReadXML { public static Object getObject() { try { DocumentBuilderFactory dFactory=DocumentBuilderFactory.newInstance(); DocumentBuilder builder=dFactory.newDocumentBuilder(); Document doc; doc=builder.parse(new File("src/adapter/config.xml")); NodeList nl=doc.getElementsByTagName("className"); Node classNode=nl.item(0).getFirstChild(); String cName="adapter."+classNode.getNodeValue(); Class<? > c=Class.forName(cName); Object obj=c.newInstance(); return obj; } catch(Exception e) { e.printStackTrace(); return null; }}}Copy the code

The running results of the program are as follows:

Adapter mode test: Electric engine drives car!Copy the code

Note: If you change ElectricAdapter to OpticalAdapter in the configuration file, the result is as follows:

Adapter mode test: Light engine driving car!Copy the code

5. Pattern extension

Adapter mode (Adapter) can be extended to bidirectional Adapter mode. The bidirectional Adapter class can convert the Adapter interface to the target interface or the target interface to the Adapter interface. The structure diagram is as follows:

package adapter; Interface TwoWayTarget {public void request(); } // interface TwoWayAdaptee {public void specificRequest(); } // Implements TwoWayTarget class TargetRealize implements TwoWayTarget {public void Request () {system.out.println (" implements TwoWayTarget! ); }} class AdapteeRealize implements TwoWayAdaptee {public void specificRequest() { System.out.println(" Adapter code called!" ); }} / / two-way adapter class TwoWayAdapter implements TwoWayTarget, TwoWayAdaptee {private TwoWayTarget target; private TwoWayAdaptee adaptee; public TwoWayAdapter(TwoWayTarget target) { this.target=target; } public TwoWayAdapter(TwoWayAdaptee adaptee) { this.adaptee=adaptee; } public void request() { adaptee.specificRequest(); } public void specificRequest() { target.request(); Public class TwoWayAdapterTest {public static void main(String[] args) { System.out.println(" Target access adapter via bidirectional adapter: "); TwoWayAdaptee adaptee=new AdapteeRealize(); TwoWayTarget target=new TwoWayAdapter(adaptee); target.request(); System.out.println("-------------------"); System.out.println(" adapter accesses target via bidirectional adapter: "); target=new TargetRealize(); adaptee=new TwoWayAdapter(target); adaptee.specificRequest(); }}Copy the code

The running results of the program are as follows:

The target accesses the adapter through the bidirectional adapter: the adapter code is invoked! ------------------- adapter access target via bidirectional adapter: object code is invoked!Copy the code

In this paper, the vast majority of content reproduced from: c.biancheng.net/view/1361.h…