桥接模式的核心是将事物和其具体实现分开,这句话乍看上去和策略模式很像,但其立意包含策略模式,同时又高于策略模式。其实桥接模式,通过定义规范的方式,完成了使用者和被使用者实现方式的解耦,使得两者可以独立实现。

1 上代码

假设我们这里有一个需求,我们有一个 windows 系统,同时有一个 Linux 系统,同时,我们又有一个 mysql 和一个 redis 数据库,现在我们需要使系统连接上数据库,同时操作数据库。

首先我们来定义两个接口

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
public interface Driver {
    void select();

    void delete();
}
public interface MockSystem {
    void selectData(Driver driver);

    void deleteData(Driver driver);
}

然后我们分解根据接口实现系统和驱动

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// 首先是两个驱动
public class MysqlDriver implements Driver {
    @Override
    public void select() {
        System.out.println("Mysql select data.");
    }

    @Override
    public void delete() {
        System.out.println("Mysql delete data.");
    }
}
public class RedisDriver implements Driver {
    @Override
    public void select() {
        System.out.println("Redis select data.");
    }

    @Override
    public void delete() {
        System.out.println("Redis delete data.");
    }
}
// 然后是两个系统
public class WindowsMockSystem implements MockSystem {
    @Override
    public void selectData(Driver driver) {
        System.out.println("Windows select data.");
        driver.select();
    }

    @Override
    public void deleteData(Driver driver) {
        System.out.println("Windows delete data.");
        driver.delete();
    }
}
public class LinuxMockSystem implements MockSystem {
    @Override
    public void selectData(Driver driver) {
        System.out.println("Linux select data.");
        driver.select();
    }

    @Override
    public void deleteData(Driver driver) {
        System.out.println("Linux delete data.");
        driver.delete();
    }
}

编写测试类试试效果

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class Main {
    public static void main(String[] args) {
        // 初始化驱动
        System.out.println("---------- 初始化驱动 ----------");
        MysqlDriver mysqlDriver = new MysqlDriver();
        RedisDriver redisDriver = new RedisDriver();

        // 初始化系统
        System.out.println("---------- 初始化系统 ----------");
        LinuxMockSystem linuxMockSystem = new LinuxMockSystem();
        WindowsMockSystem windowsMockSystem = new WindowsMockSystem();

        // 使用驱动访问数据
        System.out.println("---------- 使用驱动访问数据 ----------");
        linuxMockSystem.selectData(mysqlDriver);
        linuxMockSystem.selectData(redisDriver);
        windowsMockSystem.selectData(mysqlDriver);
        windowsMockSystem.selectData(redisDriver);

        // 使用驱动删除数据
        System.out.println("---------- 使用驱动删除数据 ----------");
        linuxMockSystem.deleteData(mysqlDriver);
        linuxMockSystem.deleteData(redisDriver);
        windowsMockSystem.deleteData(mysqlDriver);
        windowsMockSystem.deleteData(mysqlDriver);
    }
}

打印结果

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
---------- 初始化驱动 ----------
---------- 初始化系统 ----------
---------- 使用驱动访问数据 ----------
Linux select data.
Mysql select data.
Linux select data.
Redis select data.
Windows select data.
Mysql select data.
Windows select data.
Redis select data.
---------- 使用驱动删除数据 ----------
Linux delete data.
Mysql delete data.
Linux delete data.
Redis delete data.
Windows delete data.
Mysql delete data.
Windows delete data.
Mysql delete data.

2 总结

通过这种设计模式,我们就将操作系统与数据库驱动两者实现了解耦,如果现在新增了 macOS 系统,我们只需要重新实现一个 MacOSMockSystem 即可,驱动可以重复使用,如果新增了数据库也是同理。

参考资料

  1. (十七) 桥接模式建模与实现