Adapter mode
Defining an adapter pattern (English: adapter pattern) is sometimes called a packaging style or packaging. Transfer an interface of a class to what the user expects. An adaptation makes classes that cannot work together because of interface incompatibility.
There are two types of adapter modes:
1. Object Adapter Mode - The object adapter meets the user's expectation interface through association, and also reduces bad coupling between codes. It is recommended to use "Object Adaptation" in your work.
2. Class Adapter Mode - In this adapter mode, the adapter inherits its implemented classes (usually multiple inheritance). There is no multiple inheritance in Java, so I will not introduce it here.
accomplish
1. Target - defines the method that the Client needs to use.
2. Adapter - Inherit or implement Target and adapt to Adaptee methods to Target.
3. Adaptee - Define an existing method.
4. Client - Calling methods in Target.
public class Adaptee { public void specificRequest(){ System.out.println("Hello, I am from Adaptee!"); } } public interface Target { public void request(); } public class Adapter implements Target { Adaptee adaptee; public Adapter(){ adaptee = new Adaptee(); } public void request(){ adaptee.specificRequest(); } } public class Client { public static void main(String[] args) { Target target = new Adapter(); target.request(); } }To implement the class adapter pattern, we need Adapter to inherit Adaptee.
Applicable scenarios
1. If you want to use an old class and its interface does not meet your needs, you can use the Adapter class as the mediation class.
2. You want to create a general-purpose class that can call some unrelated classes' interfaces for you to use.
Bridge mode
Motivation Sometimes an abstract should have different implementations. For example, there are two ways to save data, one is the file method and the other is the database method. The usual practice is to inherit the class that saves data and then implement different ways to save data. The problem with this is that it is difficult to modify and extend the save method, and the save method cannot be switched at runtime.
Defining a bridge pattern is one of the most complex patterns in a software design pattern, which separates the abstract parts of things from its implementation parts so that they can all change independently.
For example, "circle" and "triangle" are classified under the abstract "shape", while "drawing circle" and "drawing triangle" are classified under the "drawing" category that realizes the behavior, and then "drawing" is called by "shape".
1. Abstract - Define abstract methods.
2. AbstractImpl - Use implementation interface to implement abstract methods.
3. Implementor - Defines interfaces for specific implementation behaviors.
4. ConcreteImplementor1, ConcreteImplementor2 - Implement the Implementor interface.
/** "Implementor" */ interface DrawingAPI { public void drawCircle(double x, double y, double radius); } /** "ConcreteImplementor" 1/2 */ class DrawingAPI1 implements DrawingAPI { public void drawCircle(double x, double y, double radius) { System.out.printf("API1.circle at %f:%f radius %f/n", x, y, radius); } } /** "ConcreteImplementor" 2/2 */ class DrawingAPI2 implements DrawingAPI { public void drawCircle(double x, double y, double radius) { System.out.printf("API2.circle at %f:%f radius %f/n", x, y, radius); } } /** "Abstraction" */ interface Shape { public void draw(); // low-level public void resizeByPercentage(double pct); // high-level } /** "Refined Abstraction" */ class CircleShape implements Shape { private double x, y, radius; private DrawingAPI drawingAPI; public CircleShape(double x, double y, double radius, DrawingAPI drawingAPI) { this.x = x; this.y = y; this.radius = radius; this.drawingAPI = drawingAPI; } // low-level ie Implementation specific public void draw() { drawingAPI.drawCircle(x, y, radius); } // high-level ie Abstract specific public void resizeByPercentage(double pct) { radius *= pct; } } /** "Client" */ class BridgePattern { public static void main(String[] args) { Shape[] shapes = new Shape[2]; shapes[0] = new CircleShape(1, 2, 3, new DrawingAPI1()); shapes[1] = new CircleShape(5, 7, 11, new DrawingAPI2()); for (Shape shape : shapes) { shape.resizeByPercentage(2.5); shape.draw(); } } } Example
1. Save the data mentioned in the motivation.
2. Drawing frame of the graphics. Similar to the implementation in the above code.
Applicable scenarios
1. You do not want the abstraction and implementation to have a fixed relationship, but you hope that the implementation can be modified at runtime.
2. Both abstract and implementation parts can be expanded independently without affecting each other.