java设计模式——桥接模式

一. 定义与类型

定义:将抽象部分与他的具体实现部分分离,使它们都可以独立的变化,通过组合的方式建立两个类之间的联系,而不是继承

类型:结构性。

二. 使用场景

(1) 抽象和具体实现之间增加更多的灵活性

(2) 一个类存在两个(或多个)独立变化的维度,且这两个(或多个)维度都需要独立进行扩展

(3) 不希望使用继承,或因为多层继承导致系统类的个数剧增

三. 优缺点

优点:

  (1) 分离抽象部分及其具体实现部分,解耦抽象与实现的绑定关系

  (2) 提高了系统的可扩展性

  (3) 符合开闭原则

  (4) 符合合成复用原则

缺点:

  (1) 增加了系统的理解与设计难度

  (2) 需要正确的识别出系统中两个独立变化的维度

四. 相关设计模式

桥接模式和组合模式:

  桥接模式强调的是平行级别上不同类的组合,组合模式更强调的是整体与部分间组合

桥接模式和适配器模式:

  它们的共同点都是为了让两个东西配合工作,但是它们的目的不一样。适配器模式是改变已有的接口,让它们之间可以相互配合,可以把功能上相似,但是接口不同的类适配起来;桥接模式是分离抽象和具体的实现,它的目的就是分离,在此基础上使这些层次结构结合起来。

五. Coding

桥接模式是将抽象与实现分离,例如银行与账号。银行有中国农业银行(ABC)和中国工商银行(ICBC)等,账号有活期账号,定期账号。

如果把它们都联系在一起,有很多的银行再加上大量的账号类型,会导致类的剧增,类爆炸。所以采用桥接模式将银行与账号的抽象类与具体的实现进行分离,降低了耦合性并提高了扩展性。

创建账号接口Account:

/**
 * @program: designModel
 * @description: 账号接口
 * @author: YuKai Fan
 * @create: 2019-02-12 15:15
 **/
public interface Account {
    Account openAccount();
    void showAccountType();
}

在创建两个具体的账号类实现接口:

/**
 * @program: designModel
 * @description: 活期账号
 * @author: YuKai Fan
 * @create: 2019-02-12 15:17
 **/
public class SavingAccount implements Account {
    public Account openAccount() {
        System.out.println("打开活期账号");
        return new SavingAccount();
    }

    public void showAccountType() {
        System.out.println("这是一个活期账号");
    }
}
/**
 * @program: designModel
 * @description: 定期账号
 * @author: YuKai Fan
 * @create: 2019-02-12 15:17
 **/
public class DepositAccount implements Account {
    public Account openAccount() {
        System.out.println("打开定期账号");
        return new DepositAccount();
    }

    public void showAccountType() {
        System.out.println("这是一个定期账号");
    }
}

在创建银行抽象类:在类中声明openAccount()与接口中的方法名可以不一样,只是更好的理解,因为Bank中的openAccount()是需要委托给Account接口中的openAccount()方法。因为桥接模式是抽象与实现的分离,那实现就是Account的两个实现类,所以将Bank中的openAccount委托给Account接口,从而实现抽象与实现分离

/**
 * @program: designModel
 * @description: 银行抽象类
 * @author: YuKai Fan
 * @create: 2019-02-12 15:19
 **/
public abstract class Bank {
    protected Account account;
    public Bank(Account account) {
        this.account = account;
    }
    abstract Account openAccount();
}

在创建两个具体的银行:这两个类中实现的openAccount中其实调用的是Account中两个实现类中的openAccount方法,从而实现了委托。要把具体的行为委托给抽象父类注入的account,这样Account中的openAccount如何扩展都不需要去改变,Bank中的openAccount

/**
 * @program: designModel
 * @description:
 * @author: YuKai Fan
 * @create: 2019-02-12 15:23
 **/
public class ABCBank extends Bank {
    public ABCBank(Account account) {
        super(account);
    }

    Account openAccount() {
        System.out.println("打开中国农业银行账号");
        account.openAccount();
        return account;
    }
}
/**
 * @program: designModel
 * @description:
 * @author: YuKai Fan
 * @create: 2019-02-12 15:24
 **/
public class ICBCBank extends Bank {
    public ICBCBank(Account account) {
        super(account);
    }

    Account openAccount() {
        System.out.println("打开工商银行账号");
        account.openAccount();
        return account;
    }
}

结果:

UML类图:

可以看出,如果现在再添加一个账号,只需要,在实现Account接口在创建一个账号类即可。将银行与账号进行组合,而在每个单独的对象中又进行桥接,从而无限的排列组合。

六. 源码分析

(1) jdk中JDBC对Driver封装

 

posted @ 2019-02-12 16:29  MichaelKai  阅读(156)  评论(0编辑  收藏  举报