大聪明教你学Java设计模式 | 第九篇:桥接模式

3,710 阅读7分钟

前言

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第13天,点击查看活动详情

🍊作者简介: 不肯过江东丶,一个来自二线城市的程序员,致力于用“猥琐”办法解决繁琐问题,让复杂的问题变得通俗易懂。

🍊支持作者: 点赞👍、关注💖、留言💌~

大聪明在写代码的过程中发现设计模式的影子是无处不在,设计模式也是软件开发人员在软件开发过程中面临的一般问题的解决方案。大聪明本着“独乐乐不如众乐乐”的宗旨与大家分享一下设计模式的学习心得。

桥接模式

生活中,我们离不开笔,笔的种类也有很多,毛笔、铅笔、蜡笔等等,我们就拿毛笔和蜡笔来举个例子~

假如我们需要大中小3种型号的画笔,并且要求每支画笔都可以绘制12种不同的颜色,如果使用蜡笔,我们就需要准备36(3×12)支蜡笔,但如果使用毛笔的话,只需要准备大中小3种型号的毛笔,外加12个颜料盒以及1个洗笔桶即可,此时涉及到的对象个数仅为15( 3 + 12 + 1)个,但是却能实现与36支蜡笔同样的功能。如果此时来了新的需求,要求我们增加一支超大号的画笔,并且也需要具有12种颜色,那么对应的蜡笔则需要再增加12支,而毛笔只需增加一支。

通过上面的例子我们可以看出,在选择蜡笔的情况下,颜色和型号两个不同的维度是融合在一起的,无论是对颜色进行扩展还是对型号进行扩展都一定会影响另一个维度;但在毛笔中,颜色和型号这两个维度实现了分离,增加新的颜色或者型号对另一方都没有任何影响。如果使用软件工程中的术语来说,在蜡笔中颜色和型号之间存在较强的耦合性,而毛笔很好地将二者解耦,使用起来非常灵活,扩展起来也是十分的方便。在软件开发中,我们就可以使用桥接模式来处理与画笔类似的具有多变化维度的情况。

🍓🍓什么是桥接模式🍓🍓

在讲解桥接模式之前,我们先来看一下它的定义👇

桥接(Bridge)是用于把抽象化与实现化解耦,使得二者可以独立变化。 这种类型的设计模式属于结构型模式,它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦。这种模式涉及到一个作为桥接的接口,使得实体类的功能独立于接口实现类。这两种类型的类可被结构化改变而互不影响。

在定义中我们可以提取出来三个关键词,分别是抽象化、实现化、解耦,我们对这三个词分别解释一下(理解这三个关键词是理解桥接模式的关键):

  1. 🍎抽象化: 抽象化的意思就是从众多的事物中抽取出共同的、本质性的特征,而舍弃其非本质的特征。例如毛笔、铅笔、钢笔、 圆珠笔等,它们共同的特性就是笔,我们得出“笔”这个概念的过程,就是一个抽象化的过程。要抽象,就必须进行比较,没有比较就无法找到在本质上共同的部分。通常情况下,一组对象如果具有相同的特征,那么它们就可以通过一个共同的类来描述。如果一些类具有相同的特征,往往可以通过一个共同的抽象类来描述。
  2. 🍎实现化: 抽象化给出的具体实现,就是实现化。比如我们用“笔”的抽象类实现了一个具体的“毛笔类”,这个过程就是实现化。
  3. 🍎解耦: 所谓耦合,就是两个实体的行为存在某种强关联。而将它们的强关联去掉的过程,就是解耦。在桥接模式中,脱耦就是将抽象化和实现化之间的耦合解脱开,或者说是将它们之间的强关联改换成弱关联(在 Java 中,继承关系是强关联,而聚合关系是弱关联),也就是将抽象化和实现化之间的继承关系变为聚合关系,从而实现两者可以相对独立地变化,这就是桥梁模式的用意。

看到这我们应该就明白了桥接模式的本质和用途,当我们在开发过程中遇到了有多种可能会变化的情况时,用继承会造成类的爆炸,那么我们就可以选择使用桥接模式,通过桥接模式将抽象部分与实现部分分离,使它们都可以独立的变化,拥有更好的可扩展性。

🍓🍓桥接模式的实现🍓🍓

我们桥接模式简单的实现一下“画笔画圆”👇

🍒 ① 创建桥接实现接口

/**
 * 创建桥接实现接口
 * @description: DrawAPI
 * @author: 庄霸.liziye
 * @create: 2022-04-08 10:11
 **/
public interface DrawAPI {

    public void drawCircle(int radius);

}

🍒 ② 实现 DrawAPI 接口

/**
 * 具体实现类
 * @description: RedCircle
 * @author: 庄霸.liziye
 * @create: 2022-04-08 10:14
 **/
class RedCircle implements DrawAPI{
    @Override
    public void drawCircle(int radius) {
        System.out.println("画了一个红色的圆,圆的半径是" + radius);
    }
}

/**
 * 具体实现类
 * @description: GreenCircle 
 * @author: 庄霸.liziye
 * @create: 2022-04-08 10:15
 **/
class GreenCircle implements DrawAPI {
    @Override
    public void drawCircle(int radius) {
        System.out.println("画了一个绿色的圆,圆的半径是" + radius);
    }
}

🍒 ③ 创建形状的抽象类 Shape

/**
 * 形状抽象类
 * @description: Shape
 * @author: 庄霸.liziye
 * @create: 2022-04-08 10:17
 **/
public abstract class Shape {

    protected DrawAPI drawAPI;

    protected Shape(DrawAPI drawAPI){
        this.drawAPI = drawAPI;
    }

    public abstract void draw();
}

🍒 ④ 创建形状抽象类的具体实现类

/**
 * 抽象类的具体实现类
 * @description: Circle
 * @author: 庄霸.liziye
 * @create: 2022-04-08 10:18
 **/
public class Circle extends Shape {
    private int radius;

    public Circle(int radius, DrawAPI drawAPI) {
        super(drawAPI);
        this.radius = radius;
    }

    @Override
    public void draw() {
        drawAPI.drawCircle(radius);
    }
}

🍒 ⑤ 运行代码及结果

/**
 * @description: Test
 * @author: 庄霸.liziye
 * @create: 2022-04-08 10:23
 **/
public class Test {
    public static void main(String[] args) {
        Shape redCircle = new Circle(10, new RedCircle());
        Shape greenCircle = new Circle(20, new GreenCircle());
        redCircle.draw();
        greenCircle.draw();
    }
}

在这里插入图片描述

🍓🍓桥接模式的优、缺点🍓🍓

最后我们总结一下桥接模式的优点与缺点👇

🍌🍌优点🍌🍌

桥接模式实现了抽象和实现的分离,为应用软件提供了优秀的扩展能力,同时保证了细节对客户透明。

🍌🍌缺点🍌🍌

桥接模式的引入会增加系统的理解与设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计与编程,这也就意味着开发者需要深入理解抽象关系。

小结

本人经验有限,有些地方可能讲的没有特别到位,如果您在阅读的时候想到了什么问题,欢迎在评论区留言,我们后续再一一探讨🙇‍

希望各位小伙伴动动自己可爱的小手,来一波点赞+关注 (✿◡‿◡) 让更多小伙伴看到这篇文章~ 蟹蟹呦(●'◡'●)

如果文章中有错误,欢迎大家留言指正;若您有更好、更独到的理解,欢迎您在留言区留下您的宝贵想法。

爱你所爱 行你所行 听从你心 无问东西