将抽象部分与它的实现部分分离,使它们都可以独立地变化
桥梁模式由以下四种角色组成:
- 抽象(Abstraction)角色:它定义了抽象类的接口而且维护着一个指向实现(Implementor)角色的引用。
- 精确(RefinedAbstraction)角色:实现并扩充由抽象角色定义的接口。
- 实现(Implementor)角色:给出了实现类的接口,这里的接口与抽象角色中的接口可以不一致。
- 具体实现(ConcreteImplememntor)角色:给出了实现角色定义接口的具体实现。
使用环境与优势
环境
- 当你的系统中有多个地方要是用到类似的行为,或是多个类似行为的组合时,可以考虑使用桥梁模式来提高重用,并减少因为行为的差异而产生的的子类。
- 系统中某个类的行为可能会有几种不同的变化趋势,为了有效地将变化封装,可以考虑将类的行为抽取出来。
- 当然上面的情况也可以是这样,行为可能要被不同相似类使用,也可以考虑使用桥梁模式。
优点
桥梁模式使用了低耦合性的组合代替继承,使得它具备了一下优点:
- 将可能变化的部分单独封装起来,使得变化产生的影响最小,不用编译不必要的代码。
- 抽象部分和实现部分可以单独的变动,并且每一部分的扩充都不会破坏桥梁模式搭建起来的架子。
- 对于客户程序来说,你的实现细节是透明的。
示例
public abstract class Bank {
protected Account account;
public Bank(Account account){
this.account = account;
}
abstract Account openAccount();
}
public class ABCBank extends Bank{
public ABCBank(Account account) {
super(account);
}
@Override
Account openAccount() {
System.out.printf("打开ABC银行账户");
return account;
}
}
public class ICBCBank extends Bank{
public ICBCBank(Account account) {
super(account);
}
@Override
Account openAccount() {
System.out.println("打开ICBC银行账户");
account.openAccount();
return account;
}
}
public interface Account {
Account openAccount();
void showAccountType();
}
public class DepositAccount implements Account{
@Override
public Account openAccount() {
System.out.println("打开定期账户");
return new DepositAccount();
}
@Override
public void showAccountType() {
System.out.println("这是一个定期账户");
}
}
public class SavingAccount implements Account{
@Override
public Account openAccount() {
System.out.println("打开活期账号");
return new DepositAccount();
}
@Override
public void showAccountType() {
System.out.println("这是一个活期账号");
}
}
public class Test {
public static void main(String[] args) {
ICBCBank icbcBank = new ICBCBank(new SavingAccount());
Account account = icbcBank.openAccount();
account.showAccountType();
ICBCBank icbcBank2 = new ICBCBank(new DepositAccount());
Account account2 = icbcBank2.openAccount();
account2.showAccountType();
}
}
/*
打开ICBC银行账户
打开活期账号
这是一个活期账号
打开ICBC银行账户
打开定期账户
这是一个定期账户
*/