jdk和mysql源码中的桥接模式

当一件事情有多个维度的变化的可能性时,桥接模式就派上用场了。如下图,一个消息系统中,发送消息的方式 和消息的类型都是可以独立变化的,两个维度的变化互不影响,比如消息可以通过邮件发送,而消息类型可以使普通消息,加急消息, 还可以通过短信来发送普通消息或者加急消息,这样的系统就很适合桥接模式来实现。
在这里插入图片描述
每个独立变化的维度分别抽象出一个独立的接口,然后通过一个“桥”来持有这两个维度的顶层接口,来实现自己的业务逻辑:

消息发送接口:

package com.lchtest.pattern.birdge.message;

public interface IMessage {
    // 发送消息:消息内容和接收者
    void send(String msg, String reciever);
}

消息发送方式:

package com.lchtest.pattern.birdge.message;

/**
 * 消息发送方式1 邮件消息
 */
public class EmailMessage implements IMessage {
    @Override
    public void send(String msg, String reciever) {
        System.out.println(String.format("使用邮件发送消息 %s 给 %s ", msg, reciever));
    }
}

package com.lchtest.pattern.birdge.message;
/**
 * 消息发送方式2-系统消息
 */
public class SystemMessage implements IMessage {
    @Override
    public void send(String msg, String reciever) {
        System.out.println(String.format("使用内部消息系统发送消息 %s 给 %s ", msg, reciever));
    }
}

建立桥接:

package com.lchtest.pattern.birdge.message;

public abstract class AbstractMessage {
    private IMessage message;

    public AbstractMessage(IMessage message) {
        this.message = message;
    }

    void send(String msg, String reciever){
        this.message.send(msg, reciever);
    }
}

消息级别:

package com.lchtest.pattern.birdge.message;

/**
 * 消息紧急程度- 普通消息
 */
public class NormalMessage extends AbstractMessage {
    public NormalMessage(IMessage message) {
        super(message);
    }

    @Override
    void send(String msg, String reciever) {
        // 普通消息,直接调用父类方法发送消息
        super.send(msg, reciever);
    }
}
package com.lchtest.pattern.birdge.message;
/**
 * 消息紧急程度- 紧急消息
 */
public class UrgencyMessage extends AbstractMessage {

    public UrgencyMessage(IMessage message) {
        super(message);
    }

    @Override
    void send(String msg, String reciever) {
        // 加急消息特殊处理
        String urgencyMessage  = "【加急】" + msg;
        super.send(urgencyMessage, reciever);
    }
}

测试类:

package com.lchtest.pattern.birdge.message;
public class Test {
    public static void main(String[] args) {
        IMessage message = new EmailMessage();
        AbstractMessage abstractMessage = new NormalMessage(message);
        AbstractMessage urgencyMessage = new UrgencyMessage(message);
        abstractMessage.send("便携式测温仪采购申请","采购经理");
        urgencyMessage.send("紧急事务处理款项申请","老板");

        message = new SystemMessage();
        abstractMessage = new UrgencyMessage(message);
        abstractMessage.send("便携式测温仪采购申请","公司老板");
    }
}

以JDBC API的抽象维度和实现维度 为例,来说明源码中的桥接是怎么使用的
在这里插入图片描述

package com.lchtest.pattern.birdge;

import lombok.Data;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class JDBCBridge {

    public static void main(String[] args) {
        try {
            // Driver类没有实现,只是一个抽象
            Class.forName("com.mysql.jdbc.Driver");
            // DriverManager就是这个桥,把目标数据库的driver进行了实现
            Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "root", "lchadmin");
            String sql = "select * from user where id= ?";
            PreparedStatement pstmt = connection.prepareStatement(sql); // 预编译sql
            pstmt.setInt(1, 1);  // 参数下标1,参数值1
            pstmt.execute(); // 执行查询
            ResultSet rs = pstmt.getResultSet(); // 获取结果集
            while (rs.next()){
                User user = new User();
                user.setId(rs.getInt("id"));
                user.setAge(rs.getInt("age"));
                user.setUsername(rs.getString("username"));
                user.setPassword(rs.getString("password"));
                System.out.println(user.toString()); //User(id=1, username=lisi, password=12345, age=19)
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

@Data
class User {
    private  int id;
    private String username;
    private  String password;
    private int age;

}
/*CREATE TABLE `user` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `username` varchar(50) DEFAULT NULL,
  `password` varchar(50) NOT NULL,
  `age` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4*/

Class.forName代码的作用

Class.forName(“com.mysql.jdbc.Driver”) 加载Driver类的时候就会执行如下的静态代码块
在这里插入图片描述
最终调用了下面的方法:
在这里插入图片描述

 // List of registered JDBC drivers
    private final static CopyOnWriteArrayList<DriverInfo> registeredDrivers = new CopyOnWriteArrayList<>();

代码的核心就是把Driver的实例放到了registeredDrivers 这个list里面去了,而不管是哪种数据库的Driver实例,都给封装成了DriverInfo对象,

DriverManager.getConnection的底层逻辑

getConnection核心逻辑如下,遍历那个registeredDrivers ,调用driver自己的connect方法,而这个driver就是之前的com.mysql.jdbc.Driver 的实例,
在这里插入图片描述
调用的connect是 driver的父类NonRegisteringDriver中的connect方法,返回的Connection对象也是实现了java.sql.Connection接口的实例。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1) 优秀的程序应该是这样的:阅读时,感觉很优雅;新增功能时,感觉很轻松;运行时,感觉很快速,这就需要设计模式支撑。2) 设计模式包含了大量的编程思想,讲授和真正掌握并不容易,网上的设计模式课程不少,大多讲解的比较晦涩,没有真实的应用场景和框架源码支撑,学习后,只知其形,不知其神。就会造成这样结果: 知道各种设计模式,但是不知道怎么使用到真实项目。本课程针对上述问题,有针对性的进行了升级 (1) 授课方式采用 图解+框架源码分析的方式,让课程生动有趣好理解 (2) 系统全面的讲解了设计模式,包括 设计模式七大原则、UML类图-类的六大关系、23种设计模式及其分类,比如 单例模式的8种实现方式、工厂模式的3种实现方式、适配器模式的3种实现、代理模式的3种方式、深拷贝等3) 如果你想写出规范、漂亮的程序,就花时间来学习下设计模式吧课程内容和目标本课程是使用Java来讲解设计模式,考虑到设计模式比较抽象,授课采用 图解+框架源码分析的方式1) 内容包括: 设计模式七大原则(单一职责、接口隔离、依赖倒转、里氏替换、开闭原则、迪米特法则、合成复用)、UML类图(类的依赖、泛化和实现、类的关联、聚合和组合) 23种设计模式包括:创建型模式:单例模式(8种实现)、抽象工厂模式、原型模式、建造者模式、工厂模式。结构型模式:适配器模式(3种实现)、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式(3种实现)。行为型模式:模版方法模式、命令模式、访问者模式、迭代器模式、观察者模式、介者模式、备忘录模式、解释器模式(Interpreter模式)、状态模式、策略模式、职责链模式(责任链模式)2) 学习目标:通过学习,学员能掌握主流设计模式,规范编程风格,提高优化程序结构和效率的能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值