• 6、设计模式之桥接模式


    开始之前

    本章节是一个系列,里面用的的代码实例都是连贯的。在实现某一种设计模式时,为了减少代码篇幅,前面博客出现model类(仅限公用的model类,比如compute、CPU、Mem、Disk等纯对象类)不会重复出现,读者在阅读某一篇博客时,如果发现突然出现了一个新的model类,在本片博客中没有其定义,可以往前面的博客翻一下!

    最后,当本系列更新完成后,我会整个的代码完整贴出来,提供下载链接!

    一、桥接模式简介

    桥接模式 :

    分离抽象实现 : 将 抽象部分 与它的 具体实现部分 分离,使它们都可以 独立的变化 ; 独立的变化 就是 在一定程度上 进行解耦 ;

    组合方式 : 通过 组合 的方式建立两个类之间的联系, 而不是 继承 ;

    桥接模式类型 : 结构型 ;

    桥接模式 相当于 使用桥梁 将两侧连接起来 , 这里指的是 使用桥梁 连接两个类 , 在两个类之间建立某种联系 , 可以通过继承 , 也可以通过组合 , 桥接模式 是采用 组合的方式 , 建立两个类之间的关系 ; 合成复用原则 , 推荐优先使用组合 , 不是继承 ; 桥接模式 可以防止子类过多 , 造成系统复杂的情况 ;

    桥接模式的重点是理解类的 抽象部分具体的实现部分

    抽象过程 : 抽象部分 , 经过抽象化,忽略某些信息 , 将不同的实体当做同一个对待 ; 面向对象中 , 将对象的共同性质抽取出来 , 形成类的过程 , 就是抽象化过程 ;

    实现过程 : 对于具体实现的部分 , 也要进行实现化 , 针对抽象化 , 给出具体实现 ; 这个过程就是实现过程 , 过程的产出就是具体实现部分 , 具体实现部分产生的对象 , 比抽象产生的更具体 , 是对抽象化事物的具体化产物 ;

    如 : 开发跨平台的视频播放器 , 平台有 Android , iOS , Windows , Linux , Mac , 播放器支持的格式有 MP4 , AVI , RMVB , FLV 格式 ; 这种情况下 , 适合使用桥接模式 ;

    二、桥接模式适用场景

    桥接模式适用场景 :

    抽象实现灵活 : 抽象 和 具体实现 之间 , 需要 增加更多灵活性 的情况下 , 适合使用桥接模式 ;
    使用 桥接模式 , 可以 避免在这两个层次之间 , 建立静态的继承关系 , 通过 桥接模式 在二者之间建立 关联关系 ;
    抽象 和 实现 都可以 各自 以继承的方式扩展 , 互不影响 ;
    可以动态的 将 抽象 的子类对象 和 实现 的子类对象 进行组合 , 在系统中 , 抽象 和 实现 之间进行了解耦 ;

    独立变化维度 : 一个类存在 2 个或更多的 独立变化维度 , 并且这些维度都需要 独立扩展 ;
    抽象部分可以 独立扩展 , 具体实现的部分 , 也可以独立扩展 ;

    不使用继承 : 不希望使用继承 , 或 因多层继承导致系统类的个数增加 ;

    三、桥接模式优缺点

    桥接模式优点 :

    1. 分离抽象与实现 : 分离 抽象部分 和 具体实现部分 ;
      桥接模式 使用 组合关系 解耦了 抽象 和 实现 之间的继承关系 ;
      抽象 和 实现 可以格子 沿着自己的维度进行扩展 ;
      抽象 和 实现 不在同一个继承层次中 , 通过进行组合 , 可以获得多维度的组合对象 ;

    2. 提高扩展型 : 提高了系统的 可扩展性 ;
      解耦了 抽象 与 实现 , 二者可以继续进行扩展 , 不需要改变系统原有的功能 ;

    3. 符合开闭原则 ;

    4. 符合合成复用原则 ;

    桥接模式缺点 :

    系统复杂 : 增加了 系统的 理解 与 设计难度 ;

    识别变化维度 : 需要正确地 识别出 系统中 , 两个独立变化的 维度 ;

    四、代码实现

    在不同的操作系统实现播放不同的视频格式的视频为例。

    抽象视频

    public abstract class Video {
        protected abstract String getName();
    
        public void open() {
            System.out.println("打开"+getName());
        }
        public void play(){
            System.out.println("播放"+getName());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    MP4格式视频

    public class MP4Video extends Video{
        @Override
        protected String getName() {
            return "mp4视频";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    FLV格式视频

    public class FLVVideo extends Video{
        @Override
        protected String getName() {
            return "flv视频";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    下面抽象操作系统

    public abstract class OS {
    
        protected Video video;
    
        protected OS(Video video){
            this.video = video;
        }
    
        protected abstract String getName();
    
        public void boot(){
            System.out.println(getName()+" boot!");
        }
    
        public abstract void playVideo();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    定义Linux操作系统

    public class LinuxOS extends OS{
    
        public LinuxOS(Video video) {
            super(video);
        }
    
        @Override
        protected String getName() {
            return "linux os";
        }
    
        @Override
        public void playVideo() {
            System.out.println(getName()+" play video!");
            video.open();
            video.play();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    定义window操作系统

    public class WindowsOS extends OS{
        public WindowsOS(Video video) {
            super(video);
        }
    
        @Override
        protected String getName() {
            return "window os";
        }
    
        @Override
        public void playVideo() {
            System.out.println(getName()+" play video!");
            video.open();
            video.play();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    客户端调用

    public class Client {
        public static void main(String[] args) {
            //"mac os play flv"
            Video video = new FLVVideo();
            OS os = new MacOS(video);
            os.playVideo();
            System.out.println("##################");
            //"window os play flv"
            video = new MP4Video();
            os = new WindowsOS(video);
            os.playVideo();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
  • 相关阅读:
    [Spring笔记] SpringMVC-04-get请求与post请求发送普通参数
    c++可视化性能测试
    windows mysql 安装教程
    Learning Tone Curves for Local Image Enhancement
    Shopee市场爆单难?找准选品逻辑方式
    Linux 下使用 Docker 安装 MySQL
    基于springboot、logback的日志脱敏组件
    最长上升子序列Ⅱ
    java基于Springboot+vue的宠物销售商城网站 elementui
    Spring Boot layered(分层) jar 构建docker镜像
  • 原文地址:https://blog.csdn.net/maligebazi/article/details/139023063