桥接模式

定义和特点

将抽象与实现分离,使他们可以独立变化。用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度

优点:

  • 抽象与实现分离,扩展能力增强
  • 符合开闭原则
  • 符合合成复用原则
  • 实现细节对客户透明

缺点:

由于聚合关系建立在抽象层,要求开发者针对抽象化进行设计与编码 ,能正确的识别出系统中两个独立变化的维度,增加了系统的理解与设计难度。

结构与实现

  • 抽象化(Abstraction): 定义抽象类,并包含了一个对实现化对象的引用
  • 扩展抽象化(Refined Abstraction): 抽象化角色的子类,实现父类中的业务方法,并通过组合关系调用实现化角色中的业务方法
  • 实现化(Implementor):定义实现化角色接口,供扩展抽象化角色调用
  • 具体实现化(Concrete Implenentor):给出实现化角色接口的具体实现。

样例代码

在应用中,是将变化的维度分离出来,实现化角色和抽象化角色可能区别不会很大。

因为不管是实现化角色还是抽象化角色,两者都是处于变化维度中的。有点类似于mysql中的join,将两张表join在一起,A表的一条数据,可以和B的任何一条数据组成新的数据行。就会形成A.size*B.size条数据。

实现化接口代码

  1. public interface Implementor {
  2. public void OperationImple();
  3. }

具体实现化

  1. public class ConcretelmpIementorA implements Implementor{
  2. @Override
  3. public void OperationImple() {
  4. System.out.println("具体实现化角色");
  5. }
  6. }
  7. public class ConcretelmpIementorB implements Implementor{
  8. @Override
  9. public void OperationImple() {
  10. System.out.println("具体实现化的B类");
  11. }
  12. }

抽象化角色

  1. public abstract class Abstranaction {
  2. protected Implementor imple;
  3. protected Abstranaction(Implementor imple){
  4. this.imple = imple;
  5. }
  6. public abstract void Operation();
  7. }

扩展抽象化角色

  1. public class RefinedAbstraction extends Abstranaction{
  2. protected RefinedAbstraction(Implementor imple) {
  3. super(imple);
  4. }
  5. @Override
  6. public void Operation() {
  7. System.out.println("扩展抽象化角色");
  8. imple.OperationImple();
  9. }
  10. }
  11. public class RefinedAbstractionB extends Abstranaction{
  12. protected RefinedAbstractionB(Implementor imple) {
  13. super(imple);
  14. }
  15. @Override
  16. public void Operation() {
  17. System.out.println("扩展抽象化角色B类");
  18. imple.OperationImple();
  19. }
  20. }

调用

  1. public class AbstranactionMain {
  2. public static void main(String[] args) {
  3. // Implementor impl = new ConcretelmpIementorA();
  4. Implementor impl = new ConcretelmpIementorB();
  5. // Abstranaction abs = new RefinedAbstraction(impl);
  6. Abstranaction abs = new RefinedAbstractionB(impl);
  7. abs.Operation();
  8. }
  9. }

应用场景

  • 当一个类存在两个独立变化的维度,并且两个类都需要进行扩展时。
  • 当一个系统不希望使用继承或者因为多层次继承导致系统类的个数急剧增加时。
  • 当一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性时。

  • 桥接模式其中一个常见的使用场景就是替换继承。

    • 继承虽然拥有:抽象、封装、多态等诸多优点。做到代码的复用。
    • 但是这也是她的缺点,父类拥有的方法,子类也会集成到,导致子类的臃肿。