概述
- 定义 : 将抽象部分与它的具体实现部分分离, 使它们都可以独立的变化
- 通过组合的方式建立两个类之间的联系, 而不是继承
- 类型 : 结构型
适用场景
- 抽象和具体实现之间增加更多的灵活性
- 一个类存在两个或多个独立变化的维度, 且这两个或多个维度都需要独立进行扩展
- 不希望使用继承, 或因为多层继承导致系统类的个数剧增
优点
- 分离抽象部分及其具体实现部分
- 提高了系统的可扩展性
- 符合开闭原则
- 符合合成复用原则
缺点
- 增加了系统的理解与设计难度
- 需要正确识别出系统中两个独立变化的维度
模式角色
- Abstraction
- 定义抽象类的接口。
- 维护一个指向Implementor类型对象的引用。
- RefinedAbstraction : 扩充由Abstraction定义的接口。
- Implementor : 定义实现类的接口,该接口不一定要与Abstraction的接口完全一致;事实上这两个
接口可以完全不同。一般来讲,Implementor 接口仅提供基本操作,而Abstraction则
定义了基于这些基本操作的较高层次的操作 - ConcreteImplementor : 实现Implementor接口并定义它的具体实现。
代码实现
业务场景
打开银行账户, 显示是哪个银行的,账户类型是什么
- 银行接口对应模式中Abstraction角色
- 具体银行实现对应模式中RefinedAbstraction
- 账户对应模式中Implementor接口
- 账户实现类对应模式中ConcreteImplementor
UML类图
代码实现
这里给Bank增加两个实现类, 一个工商银行, 一个农业银行, 给Account也增加两个实现类, 一个定期存款账户, 一个活期存款账户, 详细代码如下:
Account接口 :
/**
* 账户接口
* @author 七夜雪
* @create 2018-11-23 20:49
*/
public interface Account {
public void openAccount();
}
定期账户实现 :
/**
* 定期账户
*
* @author 七夜雪
* @create 2018-11-23 20:50
*/
public class FixedAccount implements Account {
@Override
public void openAccount() {
System.out.println("这是一个定期账户...");
}
}
活期账户实现 :
/**
* 活期账户
*
* @author 七夜雪
* @create 2018-11-23 20:52
*/
public class CurrentAccount implements Account {
@Override
public void openAccount() {
System.out.println("这是一个活期账户...");
}
}
Bank接口 :
/**
* 银行接口
* @author 七夜雪
* @create 2018-11-23 20:49
*/
public interface Bank {
public void openAccount();
}
工商银行实现 :
/**
* 中国工商银行
*
* @author 七夜雪
* @create 2018-11-23 20:53
*/
public class ICBCBank implements Bank {
private Account account;
public ICBCBank(Account account) {
this.account = account;
}
@Override
public void openAccount() {
System.out.println("中国工商银行账户...");
account.openAccount();
}
}
农业银行实现 :
/**
* 中国农业银行
*
* @author 七夜雪
* @create 2018-11-23 20:52
*/
public class ABCBank implements Bank {
private Account account;
public ABCBank(Account account) {
this.account = account;
}
@Override
public void openAccount() {
System.out.println("中国农业银行账户...");
account.openAccount();
}
}
测试类 :
/**
* 测试类
*
* @author 七夜雪
* @create 2018-11-23 20:56
*/
public class Client {
public static void main(String[] args) {
Account currentAccount = new CurrentAccount();
Account fixedAccount = new FixedAccount();
// 工商银行 + 定期
Bank icbcBank1 = new ICBCBank(fixedAccount);
// 工商银行 + 活期
Bank icbcBank2 = new ICBCBank(currentAccount);
// 农业银行 + 定期
Bank abcBank1 = new ABCBank(fixedAccount);
// 工商银行 + 活期
Bank abcBank2 = new ABCBank(currentAccount);
icbcBank1.openAccount();
icbcBank2.openAccount();
abcBank1.openAccount();
abcBank2.openAccount();
}
}
测试结果:
中国工商银行账户...
这是一个定期账户...
中国工商银行账户...
这是一个活期账户...
中国农业银行账户...
这是一个定期账户...
中国农业银行账户...
这是一个活期账户...
可以看出, 使用桥接模式的话, 可以很灵活的组织各种情况