18

【设计模式】第七篇:和我一起简单认识桥接模式

 4 years ago
source link: https://segmentfault.com/a/1190000038254067
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

jUVrYnq.png!mobile

一 引言

桥接模式理解起来也是非常简单,我们仍然从生活中的问题出发,如果一些事物的分类可以从两个或者多个维度来划分,就比如不同品牌和不同排量的汽车,他们可以有 M x N 种结果(例如:奥迪A8 2.0排量,奥迪A6 2.0排量,奔驰S350L 3.0排量,等等)

这种情况下如果选择继承的方式,就会出现一种多层继承的关系,子类就会非常多,同时扩展也很麻烦

3EbIfmA.png!mobile

像这样的例子还有很多,比如品牌和产品类型之间,或者不同颜色和字体的图形或者文字,等等

二 桥接模式引入

还是老规矩,直接用实际的代码例子引入

背景:相机品牌(索尼,佳能等)和相机类型(单反,微单,卡片机等)两种维族的组合结果

我们想要做的就是取消他们的继承关系,而使用组合

  • 先创建一个抽象的相机品牌类
/**
 * 相机品牌类
 */
public interface CameraBrand {
    void showInfo();
}
  • 接着就是两个具体的实现类,这里举了索尼和佳能两个品牌
/**
 * 索尼品牌
 */
public class Sony implements CameraBrand {
    @Override
    public void showInfo() {
        System.out.print("【索尼】");
    }
}
/**
 * 佳能品牌
 */
public class Canon implements CameraBrand {
    @Override
    public void showInfo() {
        System.out.print("【佳能】");
    }
}
  • 下面再将相机产品类抽象出来,为了实现组合,引入相机品牌成员,为了能让在子类中也能访问到,我用了 protected
/**
 * 抽象相机类
 */
public abstract class Camera {
    // 将品牌组合进来
    protected CameraBrand cameraBrand;

    public Camera(CameraBrand cameraBrand) {
        this.cameraBrand = cameraBrand;
    }

    public void showInfo(){
        cameraBrand.showInfo();
    }
}
  • 下面就是两个相机的产品具体类型
/**
 * 单反相机
 */
public class SlrCameras extends Camera {

    public SlrCameras(CameraBrand cameraBrand) {
        super(cameraBrand);
    }

    @Override
    public void showInfo() {
        super.showInfo();
        System.out.println("单反相机");
    }
}
/**
 * 卡片相机(数字相机)
 */
public class DigitalCamera extends Camera {

    public DigitalCamera(CameraBrand cameraBrand) {
        super(cameraBrand);
    }

    @Override
    public void showInfo() {
        super.showInfo();
        System.out.println("卡片相机(数字相机)");
    }
}

测试一下

public class Test {
    public static void main(String[] args) {
        // 索尼单反相机
        Camera camera = new SlrCameras(new Sony());
        camera.showInfo();
        // 佳能卡片相机
        Camera camera2 = new DigitalCamera(new Canon());
        camera2.showInfo();
    }
}

运行结果:

【索尼】单反相机

【佳能】卡片相机(数字相机)

从上述代码中可以看出,我们现在已经可以对不同类型和不同产品的相机进行任意的组合了,例如索尼单反相机,或者佳能单反相机都是可以的,如果想要增加一个品牌或者产品只需要增加具体的实现类就可以了

三 桥接模式理论

(一) 定义和特点

定义:将抽象与实现分离,使它们可以独立变化

实现的意思并不是指抽象的派生类,而是指通过组合来代替继承关系,从而降低抽象和具体实现产品两个可变换维度之间的耦合,就像我们的相机品牌和相机产品类型之间的分离

(二) 结构

RRbARfV.png!mobile

简单说明一下其中的角色

  • 实现化角色(Implementor):定义实现化角色的接口,供扩展抽象化角色使用

    • 例如抽象出相机的品牌,可以扩展出例如佳能索尼等各种品牌
  • 具体实现化角色(ConcreteImplementor):实现化角色的具体实现

    • 例如各种品牌
  • 抽象化(Abstraction)角色:定义一个抽象类,其中引用了实现化角色(想要组合)

    • 例如相机产品
  • 扩展抽象化(RefinedAbstraction)角色:抽象化角色子类,实现父类方法,且通过组合关系调用实现化角色中的业务方法

    • 例如具体相机产品,单反相机,卡片相机等等

( 三) 优点和缺点

优点:

经常遇到一些可以通过两个或多个维度划分的事物,第一种解决方式就是多层继承,但是复用性比较差,同时类的个数也会很多,桥接模式是改进其的更好办法

桥接模式增强了系统的扩展性,在两个维度中扩展任意一个维度都不需要修改原有代码,符合开闭原则

缺点:

桥接模式增加了系统的理解与设计难度:因为聚合关系建立在抽象层,要求开发者针对抽象化进行设计与编程,能正确地识别出系统中两个独立变化的维度

(四) 使用场景

  • 一个系统需要在构建的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。

    • 抽象化角色和实现化角色可以以继承的方式独立扩展而互不影响,在程序运行时可以动态将一个抽象化子类的对象和一个实现化子类的对象进行组合,即系统需要对抽象化角色和实现化角色进行动态耦合
  • 一个类存在两个独立变化的维度,且这两个维度都需要进行扩展
  • 虽然在系统中使用继承是没有问题的,但是由于抽象化角色和具体化角色需要独立变化,设计要求需要独立管理这两者
  • 不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统

Recommend

  • 78

    Scala 与设计模式(六):Bridge 桥接模式 1月8日 | by Prefert...

  • 60
    • www.sunnyang.com 6 years ago
    • Cache

    Java设计模式-桥接模式

    桥接模式也是23种设计模式中比较常用的模式之一,在创建型模式、结构性模式和行为型模式分类中,桥接模式归类为创建型模式。 在正式介绍桥接模式之前,先简单的看一个例子,通过例子我们再介绍引入桥接模式。 假设要设...

  • 58
    • www.woshipm.com 6 years ago
    • Cache

    Axure教程:和我一起设计简书App

    本文通过还原简书App原型的过程,进行了大量的交互设计。本文也将会分享实现这些交互效果的设计思路与方法,希望能够帮助到有需要的同学,在原型设计的道路上更上一层楼。 本文通过还原简书App原型的过程,进行了大量的交互设计。在原型制作过程中,几乎实现了最常...

  • 54
    • coderlengary.github.io 6 years ago
    • Cache

    设计模式之桥接模式

    桥接模式,顾名思义就是把两部分桥接起来。桥接模式的作用就是把被分离的抽象部分和实现部分搭桥。在生活中,有很多这样的例子,比如F1赛车有很多种,法拉利,雷诺等。而它们搭配的轮胎也不同,在雨天要换雨胎,在晴天就是硬胎。

  • 51
    • www.hi-roy.com 5 years ago
    • Cache

    设计模式-桥接模式

    桥接模式核心原理是将抽象部分和实现部分分析,使二者可以独立的变化。再具体一点,当某个类型由于自身逻辑可以有两个或多个维度的变化,使用桥接模式可以令这些维度变化时不影响其他维度。再举个例子,手机——可以按照品牌来分类,比如苹...

  • 13

    BILIBILI-HELPER 这是一个利用 Linux Crontab ,云函数, Docker 等方式实现哔哩哔哩(Bilibili)每日任务投币,点赞,分享视频,直播签到,银瓜子兑换硬币,漫画每日签到,简单配置即可每日轻松获取 65 经验值,快来和我一起成为 Lv6...

  • 8

    「和我一起学 XXX」是我 2023 年的一个新企划,目的是向读者(也包括未来的自己)介绍我正在学习的某项新技术。文章会通过长期反复迭代的方式保持其内容的新鲜度。文章有较大内容更新时,会在文章开头进行更新时间说明(由于时间精力...

  • 2

    欢迎关注「前端乱步」公众号,我会在此分享 Web 开发技术,前沿科技与互联网资讯。 0. 系列文章合集 本系列第 6,7 章节支持微信公众号内付费观看,将在全系列文章点...

  • 6

    1.3万字丨Notion AI和我一起拆解了小红书 廖尔摩斯丨设计大侦探 2023-04-11 2 评论...

  • 10

    极客早知道8min read刘强东:希望还在,兄弟和我一起不要躺平;传华为首家工厂落地法国,年产 10 亿设备;国内首次实现火箭「复用飞行」2023/12/11

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK