您现在的位置是:首页 >学无止境 >设计模式(九):结构型之桥接模式网站首页学无止境

设计模式(九):结构型之桥接模式

冬天vs不冷 2024-09-11 12:01:04
简介设计模式(九):结构型之桥接模式

设计模式系列文章

设计模式(一):创建型之单例模式

设计模式(二、三):创建型之工厂方法和抽象工厂模式

设计模式(四):创建型之原型模式

设计模式(五):创建型之建造者模式

设计模式(六):结构型之代理模式

设计模式(七):结构型之适配器模式

设计模式(八):结构型之装饰器模式

设计模式(九):结构型之桥接模式



一、设计模式分类

  • 创建型模式
    • 用于描述“怎样创建对象”,它的主要特点是“将对象的创建与使用分离”
    • 提供了单例、原型、工厂方法、抽象工厂、建造者 5 种创建型模式
  • 结构型模式
    • 用于描述如何将类或对象按某种布局组成更大的结构
    • 提供了代理、适配器、桥接、装饰、外观、享元、组合 7 种结构型模式
  • 行为型模式
    • 用于描述类或对象之间怎样相互协作共同完成单个对象无法单独完成的任务,以及怎样分配职责
    • 提供了模板方法、策略、命令、职责链、状态、观察者、中介者、迭代器、访问者、备忘录、解释器 11 种行为型模式

二、桥接模式

1、概述

现在有一个需求,需要创建不同的图形,并且每个图形都有可能会有不同的颜色

类图如下:

  • 抽象形状父类
  • 抽象具体形状类
  • 具体颜色形状类

在这里插入图片描述
可以发现有很多的类,假如我们再增加一个形状或再增加一种颜色,就需要创建更多的类

定义

  • 将抽象与实现分离,使它们可以独立变化
  • 它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度

2、结构

桥接(Bridge)模式包含以下主要角色:

  • 抽象化(Abstraction)角色 :定义抽象类,并包含一个对实现化对象的引用
  • 扩展抽象化(Refined Abstraction)角色 :是抽象化角色的子类,实现父类中的业务方法,并通过组合关系调用实现化角色中的业务方法
  • 实现化(Implementor)角色 :定义实现化角色的接口,供扩展抽象化角色调用
  • 具体实现化(Concrete Implementor)角色 :给出实现化角色接口的具体实现

3、实现

视频播放器

  • 开发一个跨平台视频播放器
  • 可以在不同操作系统平台(如Windows、Mac、Linux等)上播放多种格式的视频文件
  • 常见的视频格式包括RMVB、AVI、WMV等
  • 该播放器包含了两个维度,适合使用桥接模式

类图如下:

在这里插入图片描述
代码如下:

  • 视频文件
// 抽象角色
public interface VideoFile {
    //解码功能
    void decode(String fileName);
}

// avi视频文件 具体角色
public class AviFile implements VideoFile {
    @Override
    public void decode(String fileName) {
        System.out.println("avi视频文件 :" + fileName);
    }
}

// rmvb视频文件 具体角色
public class RmvbFile implements VideoFile {
    @Override
    public void decode(String fileName) {
        System.out.println("rmvb视频文件 :" + fileName);
    }
}
  • 抽象的操作系统类
public abstract class OpratingSystem {
    //声明videFile变量
    protected VideoFile videoFile;

    public OpratingSystem(VideoFile videoFile) {
        this.videoFile = videoFile;
    }

    public abstract void play(String fileName);
}
  • 具体系统类
// windows操作系统
public class Windows extends OpratingSystem {
    public Windows(VideoFile videoFile) {
        super(videoFile);
    }
    @Override
    public void play(String fileName) {
        videoFile.decode(fileName);
    }
}

// Mac操作系统
public class Mac extends OpratingSystem {
    public Mac(VideoFile videoFile) {
        super(videoFile);
    }
    @Override
    public void play(String fileName) {
        videoFile.decode(fileName);
    }
}
  • 客户端测试类
public class Client {
    public static void main(String[] args) {
        //创建mac系统对象
        OpratingSystem system = new Mac(new AviFile());
        //使用操作系统播放视频文件
        system.play("战狼3");
    }
}

好处

  • 桥接模式提高了系统的可扩充性
    • 在两个变化维度中任意扩展一个维度,都不需要修改原有系统
    • 如:如果现在还有一种视频文件类型wmv,我们只需要再定义一个类实现VideoFile接口即可,其他类不需要发生变化

4、使用场景

  • 当一个类存在两个独立变化的维度,且这两个维度都需要进行扩展时
  • 当一个系统不希望使用继承或因为多层次继承导致系统类的个数急剧增加时
  • 当一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性时
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。