0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

桥接模式应用场景

科技绿洲 来源:Java技术指北 作者:Java技术指北 2023-10-09 14:30 次阅读

1、什么是桥接模式?

Decouple an abstraction from its implementation so that the two can vary independently.

桥接模式(Bridge Pattern):将抽象和实现解耦, 使得两者可以独立地变化。

另外一种解释是:一个类存在两个(或多个)独立变化的维度,我们通过组合的方式,让这两个(或多个)维度可以独立进行扩展。

听起来可能还是很深奥,没关系,下面通过例子讲解。

2、桥接模式定义

图片

①、Abstraction

抽象化角色:它的主要职责是定义出该角色的行为, 同时保存一个对实现化角色的引用, 该角色一般是抽象类。

②、Implementor

实现化角色:它是接口或者抽象类, 定义角色必需的行为和属性。

③、RefinedAbstraction

修正抽象化角色:它引用实现化角色对抽象化角色进行修正。

④、ConcreteImplementor

具体实现化角色:它实现接口或抽象类定义的方法和属性。

3、桥接模式通用代码实现

实现化类:

public interface Implementor {

    void doSomething();
}

具体实现化类:

public class ConcreteImplementor1 implements Implementor{
    @Override
    public void doSomething() {
        // 具体业务逻辑处理
    }
}
public class ConcreteImplementor2 implements Implementor{
    @Override
    public void doSomething() {
        // 具体业务逻辑
    }
}

这里定义了两个,可能有多个。

抽象化角色:

public abstract class Abstraction {
    // 定义对实现化角色的引用
    private Implementor implementor;

    public Abstraction(Implementor implementor){
        this.implementor = implementor;
    }

    // 自身的行为和属性
    public void request(){
        this.implementor.doSomething();
    }

    // 获取实现化角色
    public Implementor getImplementor(){
        return implementor;
    }
}

修正抽象化角色:

public class RefinedAbstraction extends  Abstraction{
    // 覆写构造函数
    public RefinedAbstraction(Implementor implementor){
        super(implementor);
    }

    // 修正父类的行为
    @Override
    public void request() {
        super.request();
    }
}

测试:

public class BridgeClient {
    public static void main(String[] args) {
        // 定义一个实现化角色
        Implementor implementor = new ConcreteImplementor1();
        // 定义一个抽象化角色
        Abstraction abstraction = new RefinedAbstraction(implementor);
        // 执行方法
        abstraction.request();

    }
}

如果我们的实现化角色有很多的子接口, 然后是一堆的子实现。在构造函数中传递一个明确的实现者, 代码也是很清晰的。

4、桥接模式经典例子—JDBC

我们在刚开始用 JDBC 直连数据库的时候,会有这样一段代码:

Class.forName("com.mysql.cj.jdbc.Driver");//加载及注册JDBC驱动程序
String url = "jdbc:mysql://localhost:3306/sample_db?user=root&password=your_password";
Connection con = DriverManager.getConnection(url);
Statement stmt = con.createStatement();
String query = "select * from test";
ResultSet rs=stmt.executeQuery(query);
while(rs.next()) {
  rs.getString(1);
  rs.getInt(2);
}

如果我们想要把 MySQL 数据库换成 Oracle 数据库,只需要把第一行代码中的 com.mysql.cj.jdbc.Driver 换成oracle.jdbc.driver.OracleDriver 就可以了。

这种优雅的实现数据库切换方式就是利用了桥接模式。

我们首先看 Driver 类:

package com.mysql.cj.jdbc;

import java.sql.DriverManager;
import java.sql.SQLException;

public class Driver extends NonRegisteringDriver implements java.sql.Driver {
    public Driver() throws SQLException {
    }

    static {
        try {
            DriverManager.registerDriver(new Driver());
        } catch (SQLException var1) {
            throw new RuntimeException("Can't register driver!");
        }
    }
}

这段代码 Class.forName("com.mysql.cj.jdbc.Driver") 作用有两个:

①、要求 JVM 查找并加载指定的 Driver 类。

②、执行该类的静态代码,也就是将 MySQL Driver 注册到 DriverManager 类中。

接着我们看 DriverManager 类:

public class DriverManager {
  private final static CopyOnWriteArrayList< DriverInfo > registeredDrivers = new CopyOnWriteArrayList< DriverInfo >();

  //...
  static {
    loadInitialDrivers();
    println("JDBC DriverManager initialized");
  }
  //...

  public static synchronized void registerDriver(java.sql.Driver driver) throws SQLException {
    if (driver != null) {
      registeredDrivers.addIfAbsent(new DriverInfo(driver));
    } else {
      throw new NullPointerException();
    }
  }

  public static Connection getConnection(String url, String user, String password) throws SQLException {
    java.util.Properties info = new java.util.Properties();
    if (user != null) {
      info.put("user", user);
    }
    if (password != null) {
      info.put("password", password);
    }
    return (getConnection(url, info, Reflection.getCallerClass()));
  }
  //...
}

当我们把具体的 Driver 实现类(比如,com.mysql.cj.jdbc.Driver)注册到 DriverManager 之后,后续所有对 JDBC 接口的调用,都会委派到对具体的 Driver 实现类来执行。而 Driver 实现类都实现了相同的接口(java.sql.Driver ),这也是可以灵活切换 Driver 的原因。

图片

5、桥接模式优点

①、抽象和实现分离

这也是桥梁模式的主要特点, 它完全是为了解决继承的缺点而提出的设计模式。在该模式下, 实现可以不受抽象的约束, 不用再绑定在一个固定的抽象层次上。

②、优秀的扩充能力

看看我们的例子, 想增加实现?没问题!想增加抽象, 也没有问题!只要对外暴露的接口层允许这样的变化, 我们已经把变化的可能性减到最小。

③、实现细节对客户透明

客户不用关心细节的实现, 它已经由抽象层通过聚合关系完成了封装。

6、桥接模式应用场景

①、如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。

②、对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。

③、一个类存在两个独立变化的维度,且这两个维度都需要进行扩展。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 接口
    +关注

    关注

    33

    文章

    8728

    浏览量

    152104
  • 数据库
    +关注

    关注

    7

    文章

    3855

    浏览量

    64796
  • 函数
    +关注

    关注

    3

    文章

    4350

    浏览量

    63051
  • 代码
    +关注

    关注

    30

    文章

    4841

    浏览量

    69194
  • JDBC
    +关注

    关注

    0

    文章

    25

    浏览量

    13440
收藏 人收藏

    评论

    相关推荐

    AG32VF-MIPI应用场景

    to 1.2Gbps MIPI D-PHY以及DSI硬核 AG32VF-MIPI的应用场景,包括了基本的MIPI屏幕驱动,以及各种显示场合,如下图所示。 AG32VF-MIPI系列产品即将正式发布。
    发表于 01-22 08:56

    STM32待机模式适合用于那些应用场景

    对于查看STM32低功耗模式,共有三种,其中最省电的为待机模式,但是待机模式唤醒后相当于软件复位了,ram及寄存器中的值都复位了,仅仅是备份域的寄存器除外,因此有个疑问,待机模式适合用
    发表于 05-07 07:46

    关于模式遇到的问题

    VMware使用模式,已经手动设置ip地址和主机ip同一网段,但是ifconfig显示的ip地址却和vmnet8(NAT)同一网段?怎么解决?
    发表于 10-16 15:06

    特斯拉电动汽车不下电,除了哨兵模式和宠物模式外还有哪些应用场景

    如题。特斯拉推出哨兵和宠物模式后,想讨论下在不下电的情况下,还能有哪些应用场景
    发表于 06-09 11:27

    COM和CORBA的与应用

    根据CORBA规范,阐述了组件的体系结构和六种模型,并引申出八种方式,比较了各种
    发表于 02-27 16:07 29次下载
    COM和CORBA的<b class='flag-5'>桥</b><b class='flag-5'>接</b>与应用

    网桥和,网桥和是什么意思

    网桥和,网桥和是什么意思 网桥(Bridge)也称桥接器,是连接两个局域网的存储转发设备,用它可以完成具有相同或相似体系
    发表于 03-20 16:03 1.3w次阅读

    模式的目标与设计

    模式的目标是使对象的抽象部分与实现部分分离,使之可以分别独立变化,以尽量避免产生耦合。
    的头像 发表于 06-01 14:29 594次阅读
    <b class='flag-5'>桥</b><b class='flag-5'>接</b><b class='flag-5'>模式</b>的目标与设计

    设计模式结构性:模式

    模式不是将两个不相干的类链接,而是将一个需要多维度变化的类拆分成抽象部分和实现部分,并且在抽象层对两者做组合关联,是用组合的方式来解决继承的问题。
    的头像 发表于 06-08 10:49 893次阅读
    设计<b class='flag-5'>模式</b>结构性:<b class='flag-5'>桥</b><b class='flag-5'>接</b><b class='flag-5'>模式</b>

    php设计模式和应用场景

    ,从小型的网站到大型的企业级应用程序。 下面将介绍一些常见的PHP设计模式及其应用场景。 单例模式(Singleton Pattern): 单例模式用于限制类的实例化,确保一个类只有一
    的头像 发表于 12-04 14:54 952次阅读

    无线和mesh组网哪个好?

    无线和Mesh组网都是用于扩展无线网络覆盖范围的技术,但它们的工作原理和应用场景有所不同。 无线接通常是一对一的连接,相对较容易设置和维护。它的优点在于简单性,适用于需要建立点对
    的头像 发表于 01-19 16:12 8598次阅读

    应变片1/4、半、全的区别及其应用场景

    应变片1/4、半、全的区别及其应用场景 应变片是一种利用应变效应制造电场的器件,可将机械变形转化为电信号。它广泛应用于传感器、开关、位移检测等领域。根据应变片的电桥结构和应
    的头像 发表于 02-04 14:48 1.7w次阅读

    路由器路由器怎样 路由器接好还是中继好

    路由器和中继是常用的网络扩展方式,用于扩大网络覆盖范围,提供更好的网络连接。这两种方式在不同的场景下有着各自的优势,下面将详细介绍如何
    的头像 发表于 02-20 14:26 6302次阅读

    网络模式是什么? 网络模式和路由模式的区别

    网络模式是一种网络连接方式,它可以将多个设备连接在一起,使它们可以相互通信。在网络模式
    的头像 发表于 05-10 13:48 4842次阅读

    电阻应变片不同方法有什么优缺点?

    电阻应变片的方法通常有三种基本形式:四分之一(1/4)、半(1/2)和全
    的头像 发表于 05-16 17:14 5371次阅读

    与VPN的比较分析

    在现代网络通信中,和VPN是两种常见的技术,它们各自有着独特的应用场景和优势。主要用于连接同一局域网内的设备,而VPN则用于在不同网
    的头像 发表于 01-10 11:08 272次阅读