从开源框架理解设计模式系列#Bridge桥接模式

目录

what什么是桥接模式

why为什么需要桥接模式

how怎么实现桥接模式

开源框架经典案例 

Spring core中BridgeMethodResolver

桥接模式和策略模式

适用场景

优缺点对比

优点

缺点

参考资料


​​​​​​​

what什么是桥接模式

        GOF定义:将抽象部分与它的实现部分分离,使它们都可以独立地变化。
        HeadFirst定义:不止改变你的实现,也改变你的抽象。

        它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interface)模式。
这里先拋个问题,为什么桥接模式看类图怎么和策略模式有点像,下面具体分析?

why为什么需要桥接模式

        当一个类内部具备两种或多种变化维度时,使用桥接模式可以解耦这些变化的维度,使高层代码架构稳定。

        在一个抽象可能有多个实现时,通常用继承来协调它们。抽象类定义对该抽象的接口,而具体子类则有不同的实现。但是这种方法不够灵活,继承机制将抽象部分和它的实现部分固定在一起,使得很难对抽象部分和实现部分独立地进行修改、扩充和重用。


how怎么实现桥接模式

        桥接(Bridge)模式包含以下主要角色。
        抽象化(Abstraction)角色:定义抽象类,并包含一个对实现化对象的引用。
        扩展抽象化(Refined Abstraction)角色:是抽象化角色的子类,实现父类中的业务方法,并通过组合关系调用实现化角色中的业务方法。
        实现化(Implementor)角色:定义实现化角色的接口,供扩展抽象化角色调用。
        具体实现化(Concrete Implementor)角色:给出实现化角色接口的具体实现。

从开源框架理解设计模式系列#Bridge桥接模式_第1张图片

开源框架经典案例 

Spring core中BridgeMethodResolver

        这个桥接解析器的作用是通过桥接方法,找到桥接方法对应的原始方法。当一个子类在继承(或实现)一个父类(或接口)的泛型方法时,在子类中明确指定了泛型类型,那么在编译时编译器会自动生成桥接方法。BridgeMethodResolve 就是通过判断方法名、参数的个数以及泛型类型参数来获取原始的方法。

        首先看一下findBridgedMethod里面的实现。

  1. 如果不是桥接,就直接返回
  2. 先从本地缓存独取,缓存中有则直接返回
  3. 以方法名称和入参格式相等进行筛选
  4. 递归该类及其傅雷所有的方法,符合条件就添加进来
  5. 如果符合条件的方法各位为1,就直接采用,否则,调用searchCandidates方法再次筛选。
  6. 如果找不到实际方法,则返回原来的桥连方法。
  7. 结果放入缓存。
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.
 *
 * 

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}. * *

See * The Java Language Specification 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}. *

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 not 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 candidateMethods = new ArrayList(); 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模式使你可以对不同的抽象接口和实现部分进行组合,并对其进行扩充。
  • 对一个抽象的实现部分和修改应对客户不产生影响,即客户的代码不必重新编译。

优缺点对比

优点

  • 分离抽象和接口,将实现解耦,解除绑定。
  • 抽象和实现可以独立扩展,互不影响。
  • 对于具体的抽象类所作的改变,不会影响到客户。

缺点

  • 适合使用在需要跨越多个平台的图形和窗口。
  • 增加了复杂性。

参考资料

设计模式之禅

Gof设计模式:可复用面向对象软件的基础 典藏版

Head_First设计模式

桥接模式

桥接模式详解

Spring常用工具

Spring杂谈 | 从桥接方法到JVM方法调用

bridgeMethod In Java

你可能感兴趣的:(术以立策,桥接模式,设计模式,BridgeMethod)