桥接模式

桥接模式

桥接模式是将抽象部分与它的实现部分分离,使它们都可以独立地变化。它是一种对象结构模型,又称为柄体(Handle and Body)模式或者接口(Interface)模式

1、设想场景:

电脑有不同地类型,并且含有不同地品牌。可以使用继承地方式,新建一个具体品牌的电脑类,然后继承一种电脑类型(台式电脑、台式电脑、掌上电脑)。或者新建一个具体的类型电脑,然后继承一个品牌。具体类的模型如下:

桥接模式_第1张图片

桥接模式_第2张图片

我们不难发现,每新出现一种品牌与电脑类型的组合电脑时电脑,就需要添加一个类,实现起来代码过于冗余。于是引入了我们的主角——桥接模式。

将物体的属性抽象出不同的维度,此处的为品牌和电脑类型。具体模型如下:

桥接模式_第3张图片


2、测试代码

  1. 先完成横坐标。新建一个品牌接口类:Brand

    package pers.mobian.bridge;
    
    //品牌
    public interface Brand {
        void info();
    }
    
  2. 品牌类的具体实现类:HuaWei、Apple、Dell

    package pers.mobian.bridge;
    
    public class HuaWei implements Brand {
        @Override
        public void info() {
            System.out.print("华为");
        }
    }
    
    package pers.mobian.bridge;
    
    public class Apple implements Brand {
        @Override
        public void info() {
            System.out.print("苹果");
        }
    }
    
    package pers.mobian.bridge;
    
    public class Dell implements Brand {
        @Override
        public void info() {
            System.out.print("戴尔");
        }
    }
    
  3. 再完成纵坐标。新建一个电脑类型的抽象类

    package pers.mobian.bridge;
    
    //抽象地电脑类型类
    public class Computer {
        protected Brand brand;
    
        public Computer(Brand brand) {
            this.brand = brand;
        }
    
        public void info(){
            brand.info();
        }
    }
    
  4. 具体电脑类型的实现类

    package pers.mobian.bridge;
    
    public class Desktop extends Computer {
    
    
        public Desktop(Brand brand) {
            super(brand);
        }
    
        @Override
        public void info() {
            super.info();
            System.out.println("台式机");
        }
    }
    
    package pers.mobian.bridge;
    
    public class Palm extends Computer {
        public Palm(Brand brand) {
            super(brand);
        }
    
        @Override
        public void info() {
            super.info();
            System.out.println("掌上电脑");
        }
    }
    
    package pers.mobian.bridge;
    
    public class Notebook extends Computer {
        public Notebook(Brand brand) {
            super(brand);
        }
    
        @Override
        public void info() {
            super.info();
            System.out.println("笔记本");
        }
    }
    
  5. 用户测试类

    package pers.mobian.bridge;
    
    public class Test {
        public static void main(String[] args) {
    
            Palm palm = new Palm(new Dell());
            palm.info();
    
            System.out.println("===");
    
            Notebook notebook = new Notebook(new Apple());
            notebook.info();
    
            System.out.println("===");
    
            Desktop desktop = new Desktop(new HuaWei());
            desktop.info();
    
        }
    }
    
  6. 执行结果

    戴尔掌上电脑
    ===
    苹果笔记本
    ===
    华为台式机
    

补充:

对于两个类的主从关系,需要提前确定,因为这决定了到底是哪个类被组合进哪个类。此处的代码是将品牌类被组合进电脑类。并且java对于组合和继承关系的选择是能选择组合尽量组合。

关系图

桥接模式_第4张图片


3、总结

好处分析:

  • 桥接模式偶尔类似于多继承方案,但是多继承方案违背了类的单一职责原则,复杂性比较差,类的个数也非常多,桥接模式时比多继承方案更好的解决方法,极大的减少了子类的个数,从而较低管理和维护成本。
  • 桥接模式提高了系统的可扩充性,再两个变化维度中任意扩展一个维度,都不需要修改原有系统。符合开闭原则,就像一座桥,可以把两个变化的维度联系起来。

缺点分析:

  • 桥接模式的引入会增加系统的理解与设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计与编程
  • 桥接模式要求正确识别出系统中两个独立变化的维度,因此其使用范围具有一定的局限性

最佳实践:

  • 如果一个系统需要在构建的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。抽象化角色和实现化角色可以继承的方式独立扩展而互不影响,在程序运行时可以动态将一个抽象化子类和对象和一个实现化子类的对象进行组合,即系统需要对抽象化角色和实现化角色进行动态耦合
  • 一个类存在两个独立变化的维度,且这两个维度都需要进行扩展
  • 虽然在系统中使用继承是没有问题的,但是由于抽象化角色和具体化角色需要独立变化,设计要求需要独立管理这两者。对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。

运用场景:

  • Java语言用过Java虚拟机实现了平台的无关性
  • AWT中的Peer架构
  • JDBC驱动程序也是桥接模式的应用之一

桥接模式和适配器模式联系

桥接模式将两个不同的维度进行连接,但并不一定所有的维度都能够直接产生联系。此时就可以使用适配器模式,将两者能够成功的适配,继而达到两个可以联系起来的维度

你可能感兴趣的:(设计模式)