22 桥接模式

1 定义

将抽象部分和它的实现部分分离,使它们都可以独立的变化。也就是说:实现系统可能会有多角度分类,每一种分类都有可能变化,那么就把这种多角度分离出来让他们独立变化,减少它们之间的耦合。

2 组合/聚合复用原则

2.1 组合和聚合的定义

  • 组合(合成):强拥有关系,比如大雁和翅膀的关系,大雁拥有2只翅膀,翅膀是大雁的一部分,2者的声明周期是一样的。
  • 聚合:弱拥有关系,比如雁群和大雁的关系,雁群由大雁组成,每个大雁都属于一个雁群。

2.2 合成/聚合复用原则

  • 定义:尽量使用合成/聚合,尽量不要使用类继承。
  • 好处:
    • 保持每个类被封装
    • 保持每个类集中在单个任务上。
    • 这样类和类继承层次会保持较小的规模,并且不太可能增长为不可控制的庞然大物。用对象的职责,而不是结构考虑问题。

3 举个例子(手机的实现的方式)

  • 可以通过先按照品牌分类,然后在品牌下再按照功能分类;
  • 也可以先按照功能分类,然后每个功能下面再按照手机品牌分类;

关于手机的例子,通过继承实现的两种方式如下图:
22 桥接模式22 桥接模式
因为手机品牌和有哪些功能都是经常变化的东西。所以在实现一个手机时,将手机品牌和手机功能独立实现,而不是通过继承实现强耦合。这样在增加一个手机品牌or增加一个手机功能时,只需要添加一个类即可,曾经的代码并不需要改动,符合开放-封闭原则;且实现了手机品牌和手机功能的解耦

由于实现的方式有多种,桥接模式的核心就是把这些实现独立出来,让它们各自变化。这就使得每种实现的变化不会影响其他实现,从而达到应对变化的目的。
22 桥接模式

4 UML图22 桥接模式# 5 例子

5.1 场景

手机分品牌和功能,且品牌和功能经常发生变化。每个手机都有自己的品牌和功能。如何实现多个手机的构建过程?

5.2 UML图22 桥接模式

5.3 code

Main

public class Main {
    public static void main(String[] args) {
        PhoneBrand brand;

        //手机品牌1
        System.out.println("----手机品牌A1----");
        brand=new Brand1();
        //软件:通讯录
        brand.setSoftWare(new SoftWare1());
        brand.run();
        //软件:游戏
        brand.setSoftWare(new SoftWare2());
        brand.run();

        //手机品牌2
        System.out.println("----手机品牌A2----");
        brand=new Brand2();
        brand.setSoftWare(new SoftWare1());
        brand.run();
        brand.setSoftWare(new SoftWare2());
        brand.run();
    }
}

PhoneBrand

public abstract class PhoneBrand {
    //持有软件的引用
    protected PhoneSoftWare softWare;

    public void setSoftWare(PhoneSoftWare softWare) {
        this.softWare = softWare;
    }

    //调用软件功能方法
    public abstract void run();
}

Brand1

public class Brand1 extends PhoneBrand {
    @Override
    public void run() {
        super.softWare.run();
    }
}

Brand2

public class Brand2 extends PhoneBrand {
    @Override
    public void run() {
        super.softWare.run();
    }
}

PhoneSoftWare

public abstract class PhoneSoftWare {
    public abstract void run();
}

SoftWare1

public class SoftWare1 extends PhoneSoftWare {
    @Override
    public void run() {
        System.out.println("手机通信录功能运行");
    }
}

SoftWare2

public class SoftWare2 extends PhoneSoftWare {
    @Override
    public void run() {
        System.out.println("手机游戏功能运行");
    }
}

参考
https://blog.csdn.net/caoxiaohong1005/article/details/79167671