桥接模式(十)

不管怎么样,都要继续充满着希望

上一章简单介绍了适配器模式(九), 如果没有看过, 请观看上一章

一. 桥接模式

引用 菜鸟教程里面的 桥接模式介绍: https://www.runoob.com/design-pattern/bridge-pattern.html

桥接(Bridge)是用于把抽象化与实现化解耦,使得二者可以独立变化。这种类型的设计模式属于结构型模式,

它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦。

这种模式涉及到一个作为桥接的接口,使得实体类的功能独立于接口实现类。这两种类型的类可被结构化改变而互不影响

一.一 介绍

意图:将抽象部分与实现部分分离,使它们都可以独立的变化。

主要解决:在有多种可能会变化的情况下,用继承会造成类爆炸问题,扩展起来不灵活。

何时使用:实现系统可能有多个角度分类,每一种角度都可能变化。

如何解决:把这种多角度分类分离出来,让它们独立变化,减少它们之间耦合。

关键代码:抽象类依赖实现类。

应用实例

1、猪八戒从天蓬元帅转世投胎到猪,转世投胎的机制将尘世划分为两个等级,即:灵魂和肉体,前者相当于抽象化,后者相当于实现化。生灵通过功能的委派,调用肉体对象的功能,使得生灵可以动态地选择。

2、墙上的开关,可以看到的开关是抽象的,不用管里面具体怎么实现的。

  1. JDBC 驱动程序
  2. 银行转账系统 (有分类和用户类型)
  3. 消息管理 (有消息类型,即时/延时, 有消息的分类,手机,邮箱等)

优点: 1、抽象和实现的分离。 2、优秀的扩展能力。 3、实现细节对客户透明。

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

使用场景
1、如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。
2、对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。
3、一个类存在两个独立变化的维度,且这两个维度都需要进行扩展。

注意事项:对于两个独立变化的维度,使用桥接模式再适合不过了。

image-20230614161005310

如手机的品牌 和手机打开的方式 ( 上,下)是不同的信息。
注意,用大的范围在外面, 引用小的范围。

组成角色具体关系作用
ImplementorBrand行为实现类的接口行为实现类的接口
ConcreteImplementorA /BHuaWeiBrand,XiaoMiBrand行为的具体实现类行为的具体实现类
抽象类(Abstraction)Phone维护行为维护行为
RefinedAbstractionUpPhone,DownPhone是 Abstraction 抽象类的子类是 Abstraction 抽象类的子类

二. 桥接应用

二.一 品牌接口

public interface Brand {

    void sendMessage();

    void open();

    void close();

    void call();

}

二.二 品牌实现

@Slf4j
public class HuaWeiBrand implements Brand{

    @Override
    public void sendMessage() {
        log.info("华为手机实现发送短信功能");
    }

    @Override
    public void open() {
        log.info("华为手机实现发送开机");
    }

    @Override
    public void close() {
        log.info("华为手机实现关机");
    }

    @Override
    public void call() {
        log.info("华为手机实现打电话");
    }
}

@Slf4j
public class XiaoMiBrand implements Brand{

    @Override
    public void sendMessage() {
        log.info("小米手机实现发送短信功能");
    }

    @Override
    public void open() {
        log.info("小米手机实现发送开机");
    }

    @Override
    public void close() {
        log.info("小米手机实现关机");
    }

    @Override
    public void call() {
        log.info("小米手机实现打电话");
    }
}

二.三 手机 Phone

依赖 Brand

public abstract class Phone {

    private Brand brand ;

    public Phone (Brand brand) {
        this.brand = brand;
    }

    public void sendMessage() {
       brand.sendMessage();
    }

    public void open() {
        brand.open();
    }

    public void close() {
        brand.close();
    }

    public void call() {
        brand.call();
    }
}

二.四 抽象类实现

public class UpPhone extends Phone{

    public UpPhone(Brand brand) {
        super(brand);
    }

    @Override
    public void sendMessage() {
        super.sendMessage();
    }

    @Override
    public void open() {
        super.open();
    }

    @Override
    public void close() {
        super.close();
    }

    @Override
    public void call() {
        super.call();
    }
}
public class DownPhone extends Phone{

    public DownPhone(Brand brand) {
        super(brand);
    }

    @Override
    public void sendMessage() {
        super.sendMessage();
    }

    @Override
    public void open() {
        super.open();
    }

    @Override
    public void close() {
        super.close();
    }

    @Override
    public void call() {
        super.call();
    }
}

二.五 测试调用

 @Test
    public void oneTest() {
        Phone phone = new UpPhone(new XiaoMiBrand());
        phone.open();
        phone.close();

        phone = new DownPhone(new XiaoMiBrand());

        phone.sendMessage();
        phone.call();
    }

image-20230614161808670

桥接模式替代多层继承方案,可以减少子类的个数,降低系统的管理和维护成本


本章节的代码放置在 github 上:


https://github.com/yuejianli/DesignPattern/tree/develop/Bridge


谢谢您的观看,如果喜欢,请关注我,再次感谢 !!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/28675.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

谷粒商城p46-配置网关路由与路径重写

软件 : vscode idea 服务: renren-fast,gulimall-product,gulimall-gateway、nacos 前提条件: gateway、renren-fast已经注册到nacos 注意: 1、renren-fast单独注入nacos依赖,不要注入common…

#2023开放原子全球开源峰会之旅

#2023我在开源峰会 2023开放原子全球开源峰会参会指南 嗨咯,大家好! 6月11号,是一年一度的开放原子大会,有幸参加,很开心! 文章目录 1、逛展区(领周边)环节1.1 CSDN展区1.2 阿里云 …

ansible的部署和命令模块

一、 ansible 的概述 1、ansible简介 Ansible是一款为类Unix系统开发的自由开源的配置和自动化工具。 它用Python写成,类似于saltstack和Puppet,但是有一个不同和优点是我们不需要在节点中安装任何客户端。 它使用SSH来和节点进行通信。Ansible基于 …

(九)CSharp-数组

一、矩形数组 1、访问数组元素 class Program{static void Main(string[] args){int[] intArr1 new int[15];intArr1[2] 10;int var1 intArr1[2];int[,] intArr2 new int[5, 10];intArr2[2, 3] 7;int var2 intArr2[2, 3];int[] myIntArray new int[4];for (int i 0; i…

计算字母出现次数【存在括号计算】

计算字母出现次数【存在括号计算】 此代码考虑到了本问题的大多可能情况,闲话少述,代码中的注释很丰富。 代码绝对可以解决你的问题! 不行你就评论,回复速度超快 作者时间YaoChongChong2023年6月14日10:40 Descript…

【gcc, cmake, eigen, opencv,ubuntu】五.CMakeLists.txt编写

文章目录 CMakeLists.txt编写1.CMakeLists.txt模板2.设置编程语言版本3.设置编译类型Debug,Release4.设置获取文件列表5.添加include目录6.配置编译选项 CMakeLists.txt编写 1.CMakeLists.txt模板 一个使用opencv 的 CMakeLists.txt # cmake最低版本要求 cmake_m…

该怎么学Python?自学Python的方法和资料整理!

导语 Python 作为一门简洁、易学且功能强大的编程语言,备受程序员和初学者的喜爱。如果你也想学习 Python,但不知从何入手,本文将为你整理一些自学 Python 的方法,助你快速入门并掌握这门语言。 为什么学习Python?&a…

requests库的使用

文章目录 get 请求post 请求get 请求和 post 请求的区别response1. res.headers2. status_code3. json get 请求 参数类型作用urlstr发起请求的地址params字典url为基准地址,不包含查询参数;使用此参数会自动对 params 字典编码,然后和url拼…

函数参数的拓展

函数参数的默认值 C 中可以在函数声明时为参数提供一个默认值 当函数调用时没有提供默认参数的值,则使用默认值 参数的默认值必须在函数声明中指定 当函数声明时没有出现参数的默认值,而定义的时候出现参数的默认值,编译器会报错 当函数声…

看了这几个C语言例子,你一定和我一样连说5个卧槽,声音一次比一次大

曾经我一直以为自己C语言学的还挺好的&#xff0c;直到看到这几个例子。 例1 首先来看一下&#xff0c;大师是如何求圆周率的&#xff0c;一口君实在词穷&#xff0c;first卧槽。 #include <stdio.h>long a10000,b0,c10000,d,e,f[10001],g;void main(){for(;b ! c; f[…

nginx的安装及代理和负载均衡设置

一、通过yum方式进行安装 官网参考地址&#xff1a;https://nginx.org/en/linux_packages.html#RHEL 1.1 安装好依赖 执行下面的命令安装 sudo yum install yum-utils1.2、 先配置好yum源 新建文件/etc/yum.repos.d/nginx.repo&#xff0c;文件内容&#xff1a; [nginx-s…

Spark SQL数据源:Hive表

文章目录 一、Spark SQL支持读写Hive二、Spark配置hive-site.xml三、准备工作&#xff08;一&#xff09;启动Hive的metastore&#xff08;二&#xff09;启动Spark Shell 四、Spark读写Hive数据&#xff08;一&#xff09;导入SparkSession&#xff08;二&#xff09;创建Spar…

内网安全:Cobalt Strike 与 MSF 联动( 会话 相互转移 )

内网安全&#xff1a;Cobalt Strike 与 MSF 联动&#xff08; 会话 相互转移 &#xff09; 在渗透中&#xff0c;有时候 Cobalt Strike 会话可能会受限制&#xff0c;所以我们需要把 Cobalt Strike 会话转移到 MSF 上进行后面的渗透。也有的时候会话在 MSF 上&#xff0c;但是…

MySQL数据库的认识及基础命令操作

目录 一、数据库的基本概念 1、数据库定义 &#xff08;1&#xff09; 数据 &#xff08;2&#xff09;表 &#xff08;3&#xff09; 数据库 2、 数据库管理系统&#xff08;DBMS&#xff09; 3、 数据库系统&#xff08;DBS&#xff09; 二、数据库系统发展史 1、 第一…

编程必备:JAVA多线程详解

目录 前言 1.入门多线程 1.1. 线程、进程、多线程、线程池 1.2.并发、串行、并行 1.3. 线程的实现方式 1.3.1. 继承 Thread 类 1.3.2. 实现 Runnable 接口 1.3.3. 使用 Callable 和 Future 1.3.4. 使用线程池 1.4.线程的状态 1.5. 线程常用方法 1.5.1 sleep() 1.4…

docker 网络理论知识点 - CNM 和命名空间

Network 目录 1 network namespace1.1 动手小实验 2 回到 docker2.1 driver and docker02.2 network2.3 网桥 docker0 3 总结 1 network namespace 1.1 动手小实验 网络命名空间。linux kernel 提供的网络虚拟化的功能。创建多个隔离的网络空间。每个空间内 firewall, ether …

【taro react】---- 解决H5接入uni-app版本的IM

1. 问题 由于项目开发比较紧张&#xff0c;腾讯 IM 的接入就使用了 TUIKit 含UI集成方案&#xff0c;遇到的问题&#xff0c;uni-app的UI本来就是一个单独的项目&#xff0c;需要集成到现有的 Taro React 中&#xff0c;就只能作为一个独立的项目&#xff0c;不跳转时不影响原有…

在十四届蓝桥杯开赛前一星期开始复习

文章目录 十三届蓝桥杯国赛原题1.20222.钟表3卡牌4最大数字4.5 Dijkstra算法5出差 十三届蓝桥杯国赛原题 1.2022 #include<iostream> using namespace std;long long int f[2023][11][2023]; //表示前2022个物品选择10个物品&#xff0c;体积总和为2022的方案个数 ,,数…

入门编程其实也简单

随着信息技术的快速发展&#xff0c;编程已经成为一个越来越重要的技能。那么&#xff0c;我们该如何入门编程呢&#xff1f; 编程是指使用计算机语言编写计算机程序的过程。计算机程序是一系列指令的集合&#xff0c;这些指令告诉计算机要执行的操作。编程的目的是创建计算机…

Unity编辑器扩展-第二集-按钮排序/分组/放入右键菜单

第一集链接&#xff1a;Unity编辑器扩展-第一集-在菜单栏加入自己的按钮_菌菌巧乐兹的博客-CSDN博客 一、本节目标效果展示 1.按钮排序 变成 2.按钮分组 仔细看&#xff0c;有个灰色的杠杠 3.放入右键菜单 4.皮一下 二、按钮排序具体流程 第一集讲&#xff0c;如果想放入…