美文网首页
桥接模式

桥接模式

作者: lj72808up | 来源:发表于2021-04-14 16:15 被阅读0次

    桥接模式

    1. 思想: 组合优于继承

    2. 桥接模式有2种理解角度

      • 将业务的抽象和业务的具体实现分开
      • 当一个类存在2个以上的变化维度时, 通过组合, 让两个维度可以独立进行扩展
    3. jdbc 就是使用桥接模式实现不同数据库的操作的

      • 如下代码, 是 jdbc 的标准使用代码
      Class.forName("com.mysql.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.jdbc.Driver 换成 oracle.jdbc.driver.OracleDriver 就可以了. 为什么可以这样呢? 原因在 com.mysql.jdbc.Driver 这个类
      package com.mysql.jdbc;
      public class Driver extends NonRegisteringDriver implements java.sql.Driver {
        static {
          try {
            java.sql.DriverManager.registerDriver(new Driver());
          } catch (SQLException E) {
            throw new RuntimeException("Can't register driver!");
          }
        }
      
        /**
         * Construct a new driver and register it with DriverManager
         * @throws SQLException if a database error occurs.
         */
        public Driver() throws SQLException {
          // Required for Class.forName().newInstance()
        }
      }
      

      我们可以发现,当执行 Class.forName(“com.mysql.jdbc.Driver”) 这条语句的时候,实际上是做了两件事情。
      * 第一件事情是要求 JVM 查找并加载指定的 Driver 类
      * 第二件事情是执行该类的静态代码块,也就是将自己 mysql.Driver 注册到 DriverManager 类中。

      经过以上分析返现, 各数据库自己的驱动注册到 DriverManager 后, 就能实现不同数据库自己的操作. DriverManager 就是业务的抽象, mysql.Driver
      就是业务的实现. 可以看到, DriverManager.getConnection 组合了 Driver.connect() 方法

      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()));
        }
        //...
      }
      
    1. 假设要实现一个 API 接口监控告警的例子:根据不同的告警规则,触发不同类型的告警。
      • 告警渠道有多个, 包括:邮件、短信、微信、自动语音电话。
      • 告警的紧急程度有个,包括:SEVERE(严重)、URGENCY(紧急)、NORMAL(普通)、TRIVIAL(无关紧要)。
        因为告警这个动作有2个变化维度: 渠道和严重程度. 因此可以把2个维度的协作方式作为业务的抽象, 2个维度各自的执行作为业务的具体实现
    // 业务的具体实现
    interface MsgSender {
        void send(String message);
    }
    
    class TelephoneMsgSender implements MsgSender {
        private List<String> telephones;
        public TelephoneMsgSender(List<String> telephones) {
            this.telephones = telephones;
        }
    
        @Override
        public void send(String message) {
            //...
        }
    }
    
    class EmailMsgSender implements MsgSender {
        // 与TelephoneMsgSender代码结构类似,所以省略...
    }
    
    class WechatMsgSender implements MsgSender {
        // 与TelephoneMsgSender代码结构类似,所以省略...
    }
    
    
    // 业务的抽象
    abstract class Notification {
        protected MsgSender msgSender;
    
        public Notification(MsgSender msgSender) {
            this.msgSender = msgSender;
        }
    
        public abstract void notify(String message);
    }
    
    class SevereNotification extends Notification {
        public SevereNotification(MsgSender msgSender) {
            super(msgSender);
        }
    
        @Override
        public void notify(String message) {
            msgSender.send(message);
        }
    }
    
    class UrgencyNotification extends Notification {
        // 与SevereNotification代码结构类似,所以省略...
    }
    class NormalNotification extends Notification {
        // 与SevereNotification代码结构类似,所以省略...
    }
    class TrivialNotification extends Notification {
        // 与SevereNotification代码结构类似,所以省略...
    }
    

    相关文章

      网友评论

          本文标题:桥接模式

          本文链接:https://www.haomeiwen.com/subject/qnfllltx.html