what is bridging mode
GOF Definition: Separate the abstract from its implementation so that they can all change independently.
HeadFirst definition: not only changes your implementation, but also your abstraction.
It is an object structured mode, also known as the Handle and Body mode or the Interface mode.
Let's start by asking a question. Why does bridging look a little like strategy?
Why why needs bridging mode
When there are two or more changing dimensions within a class, bridging mode can be used to decouple these changing dimensions and stabilize the high-level code architecture.
When there may be multiple implementations of an abstract, inheritance is often used to reconcile them.An abstract class defines the interface to that abstraction, while a specific subclass has different implementations.However, this method is not flexible enough, and the inheritance mechanism holds the abstract part together with its implementation part, making it difficult to modify, extend and reuse the abstract part and the implementation part independently.
how to implement bridge mode
Bridge mode contains the following main roles.
Abstraction role: Defines an abstract class and contains a reference to the implementing object.
Extended Refined Abstraction roles: are subclasses of abstracted roles, implement business methods in parent classes, and invoke business methods in realized roles through composite relationships.
Implementor role: Defines the interface to implement the role for extended abstraction role calls.
Concrete Implementor role: Gives a concrete implementation of the interface for implementing roles.
Open Source Framework Classic Case
BridgeMethodResolver in Spring core
The purpose of this bridge parser is to find the original method for the bridge method by bridging it.When a subclass inherits (or implements) a generic method of a parent class (or interface), a generic type is explicitly specified in the subclass, and the compiler automatically generates the bridging method at compile time.BridgeMethodResolve is the original method obtained by determining the method name, number of parameters, and generic type parameters.
First, look at the implementation inside findBridgedMethod.
- Return directly if it is not a bridge
- Exclusive from local cache first, returned directly from cache
- Filter by equal method name and input format
- Recursive methods of this class and all of its Fourier methods are added when they meet the criteria
- If each of the eligible methods is 1, it will be used directly, otherwise, call the searchCandidates method to filter again.
- If no actual method is found, the original bridging method is returned.
- The results are cached.
import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.springframework.util.ClassUtils; import org.springframework.util.ReflectionUtils; /** * Helper for resolving synthetic {@link Method#isBridge bridge Methods} to the * {@link Method} being bridged. * * <p>Given a synthetic {@link Method#isBridge bridge Method} returns the {@link Method} * being bridged. A bridge method may be created by the compiler when extending a * parameterized type whose methods have parameterized arguments. During runtime * invocation the bridge {@link Method} may be invoked and/or used via reflection. * When attempting to locate annotations on {@link Method Methods}, it is wise to check * for bridge {@link Method Methods} as appropriate and find the bridged {@link Method}. * * <p>See <a href="http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.12.4.5"> * The Java Language Specification</a> for more details on the use of bridge methods. * * @author Rob Harrop * @author Juergen Hoeller * @author Phillip Webb * @since 2.0 */ public abstract class BridgeMethodResolver { /** * Find the original method for the supplied {@link Method bridge Method}. * <p>It is safe to call this method passing in a non-bridge {@link Method} instance. * In such a case, the supplied {@link Method} instance is returned directly to the caller. * Callers are <strong>not</strong> required to check for bridging before calling this method. * @param bridgeMethod the method to introspect * @return the original method (either the bridged method or the passed-in method * if no more specific one could be found) */ public static Method findBridgedMethod(Method bridgeMethod) { if (bridgeMethod == null || !bridgeMethod.isBridge()) { return bridgeMethod; } // Gather all methods with matching name and parameter size. List<Method> candidateMethods = new ArrayList<Method>(); Method[] methods = ReflectionUtils.getAllDeclaredMethods(bridgeMethod.getDeclaringClass()); for (Method candidateMethod : methods) { if (isBridgedCandidateFor(candidateMethod, bridgeMethod)) { candidateMethods.add(candidateMethod); } } // Now perform simple quick check. if (candidateMethods.size() == 1) { return candidateMethods.get(0); } // Search for candidate match. Method bridgedMethod = searchCandidates(candidateMethods, bridgeMethod); if (bridgedMethod != null) { // Bridged method found... return bridgedMethod; } else { // A bridge method was passed in but we couldn't find the bridged method. // Let's proceed with the passed-in method and hope for the best... return bridgeMethod; } }
Bridge Mode and Policy Mode
Some people say it doesn't matter, others say it does. Add your own understanding here.There is a case where one object references the abstract interface of another object using aggregation, and the implementation of the abstract interface can be varied and replaceable.It can be said that both of them are visually decoupling between the caller and the callee, as well as the abstract interface and the separation of implementation.
Structurally, bridging patterns, such as strategy patterns, are used, but there is still a big difference in their roles, which can be clearly understood by definition.
Bridge mode emphasizes the separation of abstraction from implementation, while strategy mode emphasizes the encapsulation and substitution of algorithms, the former is structural mode, and the latter is behavioral mode.
Scenarios applicable
- You don't want a fixed binding between abstraction and dissatisfaction with its implementation. This may be a quotation, and the implementation part should be selectable or switched when the program is running.
- The abstraction of a class and its implementation should be augmented by the generation of subclasses.Bridge mode allows you to combine and extend different abstract interfaces and implementations.
- An Abstract implementation and modification should have no impact on the client, that is, the client's code does not have to be recompiled.
Advantages and disadvantages
Advantage
- Separating abstraction from interface will decouple and unbind.
- Abstraction and implementation can be extended independently without interacting with each other.
- Changes made to specific abstract classes do not affect the customer.
shortcoming
- Suitable for graphics and windows that need to span multiple platforms.
- Adding complexity.
Reference material
Gof Design Patterns: Basic Collection of Reusable Object-Oriented Software