1. Adapter mode
Adapter pattern is a structural design pattern that enables objects with incompatible interfaces to cooperate with each other. The adapter can act as a wrapper between two objects. It will receive calls to one object and convert it to a format and interface recognized by another object.
2. The adapter mode is suitable for application scenarios
1) When you want to use a class, but its interface is incompatible with other code, you can use the adapter class.
2) If you need to reuse such a class, they are in the same inheritance system, and they have additional common methods, but these common methods are not common to all subclasses in this inheritance system.
3. Implementation mode
1) Ensure that at least two classes have incompatible interfaces:
- A functional service class that cannot be modified.
- One or more client classes that will benefit from using service classes.
2) Declare the client interface and describe how the client interacts with the service.
3) Create an adaptation class that follows the client interface. All methods are temporarily empty.
4) Add a member variable in the adapter class to save the reference of the user service object. Usually, the member variable is initialized through the constructor, but sometimes it is more convenient to call its method to pass the variable to the adapter.
5) Implement all methods of the adapter class client interface in turn. The adapter will delegate the actual work to the service object and is only responsible for the conversion of interface or data format.
6) The client must use the adapter through the client interface, so that the adapter can be modified or extended without affecting the client code.
4. Advantages and disadvantages
1) Under the principle of single responsibility, you can separate the interface or data conversion code from the main business logic of the program.
2) Opening and closing principle. As long as the client code interacts with the adapter through the client interface, you can add a new type of adapter to the program without modifying the existing client code.
3) The overall complexity of the code increases because you need to add a series of interfaces and classes. Sometimes it is easier to change the service class directly to make it compatible with other code.
5. Java code example
Fit the square nail to the round nail
This simple example shows how the adapter enables incompatible objects to cooperate with each other.
Round hole java
public class RoundHole { private double radius; public RoundHole(double radius) { this.radius = radius; } public double getRadius() { return radius; } //Judge whether the nail can enter the hole public boolean fits(RoundPeg peg) { boolean result; result = (this.getRadius() >= peg.getRadius()); return result; } }
Round peg java
public class RoundPeg { private double radius; public RoundPeg() {} public RoundPeg(double radius) { this.radius = radius; } public double getRadius() { return radius; } }
Square peg java
public class SquarePeg { private double width; public SquarePeg(double width) { this.width = width; } public double getWidth() { return width; } public double getSquare() { double result; result = Math.pow(this.width, 2); return result; } }
Square peg to round hole adapter class squarepegadapter java
//The adapter inherits the round nail public class SquarePegAdapter extends RoundPeg { private SquarePeg peg; public SquarePegAdapter(SquarePeg peg) { this.peg = peg; } @Override public double getRadius() { double result; // Calculate a minimum circle radius, which can fit this peg. result = (Math.sqrt(Math.pow((peg.getWidth() / 2), 2) * 2)); return result; } }
Client demo java
public class Demo { public static void main(String[] args) { // Round fits round, no surprise. RoundHole hole = new RoundHole(5); RoundPeg rpeg = new RoundPeg(5); if (hole.fits(rpeg)) { System.out.println("Round peg r5 fits round hole r5."); } SquarePeg smallSqPeg = new SquarePeg(2); SquarePeg largeSqPeg = new SquarePeg(20); // hole.fits(smallSqPeg); // Won't compile. // Adapter solves the problem. SquarePegAdapter smallSqPegAdapter = new SquarePegAdapter(smallSqPeg); SquarePegAdapter largeSqPegAdapter = new SquarePegAdapter(largeSqPeg); if (hole.fits(smallSqPegAdapter)) { System.out.println("Square peg w2 fits round hole r5."); } if (!hole.fits(largeSqPegAdapter)) { System.out.println("Square peg w20 does not fit into round hole r5."); } } }