1、定义
将抽象部分与它的实现部分分离,使它们都可以独立的变化。
2、组成部分
1、抽象类(Abstraction)
2、扩充抽象类(RefinedAbstraction)
3、实现类接口(Implementor)
4、具体实现类(ConcreteImplementor)
3、为什么使用桥接模式
桥接模式将继承关系转换为关联关系,从而降低了类与类之间的耦合,减少了代码编写量。
4、优点
1、分离抽象和实现部分
2、松耦合:两个维度干活
3、单一职责:各个维度干各个维度的活
5、缺点
桥接模式的引用会增加系统的理解与设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计与编程。
6、示例分析
我们都去买过手机,手机按照品牌分可以分为华为、小米、oppo、vivo等品牌,如果这些手机按照内存分又可以分为4G、6G、8G等等。假如我们每一种手机都想要玩一下,至少需要4*3个。这对我们来说这些手机也太多了,竟然有12个,最主要的是手机品牌和内存是放在一起的。现在有这样一种机制,手机牌品商是一个公司,做手机内存的是一个公司,想要做什么手机我们只需要让其两者搭配起来即可。有点类似于全球贸易分工明确的思想,这就是桥接模式,把两个不同维度的东西桥接起来。
1、定义实现类接口(Implementor),这里定义手机内存接口:
/*Implementor:定义手机内存接口*/
public interface Memory {
public void addMemory();
}
2、定义具体实现类(ConcreteImplementor),这里指具体的内存,内存这里定义了两种一种是6G,一种是8G
/*ConcreteImplementor:具体实现类1*/
public class Memory6G implements Memory{
@Override
public void addMemory() {
System.out.println("手机装了6G内存");
}
}
/*ConcreteImplementor:具体实现类2*/
public class Memory8G implements Memory{
@Override
public void addMemory() {
System.out.println("手机装了8G内存");
}
}
3、定义抽象类(Abstraction),这里指手机
/*Abstraction:手机抽象类*/
public abstract class Phone {
public Memory memory;
public void set(Memory memory) {
this.memory = memory;
}
public abstract void buyPhone();
}
4、定义扩充抽象类(Refined Abstraction),这里指具体的手机品牌,以华为和小米为例
public class HuaWei extends Phone{
public void buyPhone() {
memory.addMemory();
System.out.println("购买华为手机");
}
}
public class XiaoMi extends Phone{
public void buyPhone() {
memory.addMemory();
System.out.println("购买小米手机");
}
}
5、测试代码如下:
public class TestMain {
public static void main(String[] args) {
//让华为搭配8G内存
Phone huawei = new HuaWei();
huawei.set(new Memory8G());
huawei.buyPhone();
//让小米搭配6G内存
Phone xiaomi = new XiaoMi();
xiaomi.set(new Memory6G());
xiaomi.buyPhone();
}
}
6、输出结果如下:
从代码就可以看出,购买手机的时候,品牌和内存两个维度是分开的。下面我们分析一下这个桥接模式
7、模式总结
关系图如图所示:
1、定义实现类接口(Implementor)
public interface Implementor {
public void operationImpl();
}
2、定义具体实现类(ConcreteImplementor)A和B
public class ConcreteImplementorA implements Implementor{
@Override
public void operationImpl() {
System.out.println("类型A");
}
}
public class ConcreteImplementorB implements Implementor{
@Override
public void operationImpl() {
System.out.println("类型B");
}
}
3、定义抽象类(Abstraction)
public abstract class Abstraction {
public Implementor implementor;
public void setImplementor(Implementor implementor) {
this.implementor = implementor;
}
public abstract void operation();
}
4、定义扩充抽象类(Refined Abstraction)
public class RefinedAbstraction extends Abstraction{
@Override
public void operation() {
implementor.operationImpl();
}
}
5、测试代码如下:
public class TestMain {
public static void main(String[] args) {
Abstraction a = new RefinedAbstraction();
a.setImplementor(new ConcreteImplementorA());
a.operation();
}
}
输出结果如下:
8、典型应用
JDK提供的JDBC数据库访问接口API正是经典的桥接模式的实现者,接口内部可以通过实现接口来扩展针对不同数据库的具体实现来进行扩展,而对外的仅仅只是一个统一的接口调用,调用方过于抽象,可以将其看做每一个JDBC调用程序(这是真实实物,当然不存在抽象)。