• 设计模式-Bridge模式(桥模式)


    两个概念

    1. 类的功能层次结构(增加父类没有的方法)
    2. 类的实现层次结构(实现父类的抽象方法)

    什么意思呢,先来看段简单代码

    // 父类
    public abstract class Father {
        // 父类的普通功能
        public void method1() {
            // doSomething
        }
        
        // 父类的抽象方法
        public abstract void method2();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    // 子类A
    public class SonA extends Father {
        // 实现父类方法
        public void method2() {
            // doSomething
        }
    }
    
    public class SonB extends Father {
        // 实现父类方法
        public void method2() {
            // doSomething
        }
        
        // 增加父类没有的方法
        public void method3() {
            // doSomething
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    在父类中通过声明抽象方法来定义接口(API),子类通过实现具体方法来实现接口(API),这种层次结构被称为类的实现层次结构,比如Father有抽象方法method2(),子类都实现了method2(),那么Father和两个实现类SonA、SonB都具有类的实现层次结构,Father处于最顶层。

    在父类中具有基本功能,在子类中增加新的功能,这种层次结构被称为类的功能层次结构,比如Father具有基本功能方法method1(),而子类SonB除了继承自父类的method1(),还扩展增加了method3(),所以Father和SonB具有类的功能层次结构,同样Father处于最顶层。

    如图:
    在这里插入图片描述

    存在的问题

    当类的层次结构只有一层时,功能层次结构与实现层次结构是混杂在一个层次结构中的。这样很容易使类的层次结构变得复杂, 也难以透彻地理解类的层次结构,因为自己难以确定究竟应该在类的哪个层次结构去增加子类。因此我们需要将“类的功能层次结构”和”类的实现层次结构“分离为两个独立的类层次结构,并在它们之间搭建一座桥梁,Bridge模式的作用就是搭建这座桥梁。

    Bridge模式

    怎么分离呢?先看一下,上面的例子是使用”继承“来扩展类的,但是类之间也形成了一种强关联关系。这时,我们可以使用”委托“来代替“继承”关系。

    再来看个例子,我们需要实现“显示一些东西”这个功能。

    Display类的功能是抽象的,负责“显示一些东西”,该类位于“类的功能层次结构”的最上层。在impl字段中保存的是实现了Display类的具体功能的实例,即是类的两个层次结构的“桥梁”。

    public class Display {
        private DisplayImpl impl;
    
        public Display(DisplayImpl rawDisplay) {
            this.impl = rawDisplay;
        }
    
        public void open() {
            impl.rawOpen();
        }
    
        public void print() {
            impl.rawPrint();
        }
    
        public void close() {
            impl.rawClose();
        }
    
        public void display() {
            open();
            print();
            close();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    CountDisplay类在Display类的基础上增加了一个新功能,所以它也属于“类的功能层次结构”。

    public class CountDisplay extends Display {
        public CountDisplay(DisplayImpl rawDisplay) {
            super(rawDisplay);
        }
    
        public void mutiDisplay(int times) {
            open();
            for (int i = 0; i < times; i++) {
                print();
            }
            close();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    DisplayImpl类位于“类的实现层次结构”的最上层,它是一个抽象类,里面的方法与Display的抽象功能方法一一对应,进行显示前、显示、显示后的处理,但是具体的实现交给子类。

    public abstract class DisplayImpl {
        public abstract void rawOpen();
    
        public abstract void rawPrint();
    
        public abstract void rawClose();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    StringDisplayImpl类是真正的“实现”,继承自DisplayImpl并实现其抽象方法,同样作为”类的实现层次结构“的一员。

    public class StringDisplayImpl extends DisplayImpl {
    
        private String string;
        private int width;
    
        public StringDisplayImpl(String string) {
            this.string = string;
            this.width = string.getBytes().length;
        }
    
        @Override
        public void rawOpen() {
            printLine();
        }
    
        @Override
        public void rawPrint() {
            System.out.println("|" + string + "|");
        }
    
        @Override
        public void rawClose() {
            printLine();
        }
    
        private void printLine() {
            System.out.print("+");
            for (int i = 0; i < width; i++) {
                System.out.print("-");
            }
            System.out.println("+");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    测试方法

    public class Test {
        public static void main(String[] args) {
            Display d1 = new Display(new StringDisplayImpl("Hello, China."));
            Display d2 = new CountDisplay(new StringDisplayImpl("Hello, World."));
            CountDisplay d3 = new CountDisplay(new StringDisplayImpl("Hello, Universe."));
            d1.display();
            d2.display();
            d3.display();
            d3.mutiDisplay(5);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    为什么要用桥模式

    我的理解是,将两种类的层次结构进行分离,弱化类之间的关联关系,这样就可以明确,当我们要增加新功能时,只在”类的功能层次结构“上进行调整,如增加一个类似于CountDisplay的新类继承于Display,然后增加新方法。又或者当我们想要对已有的抽象方法增加新的实现时,只需要增加一个类似于StringDisplay的新类,由它去完成对DisplayImpl中抽象方法的不同实现。

    在这里插入图片描述

  • 相关阅读:
    深分页Scroll
    电脑重装系统后当前安全设置不允许下载该文件
    【JMeter】Beanshell介绍
    centos超详解图文安装mysql数据库
    后台获取不到请求头中token信息的解决方法
    博客系统(完整版)
    英语六级-day6
    【产品经理】深入B端SaaS产品设计核心理念
    记录一次bug
    javascript 数组方法 slice() 的使用说明
  • 原文地址:https://blog.csdn.net/weixin_44030848/article/details/126112381