Java设计模式(9):桥接模式

2023-11-06

9,桥接模式(Bridge)

9.1,问题引入_手机类型

  • 现在对不同类型不同品牌的手机实现操作编程,如下手机外观类型和对应品牌:
    在这里插入图片描述

  • 则需要编写的代码类图可能如下:
    在这里插入图片描述

  • 带来的问题如下:

    • 如果我们需要添加一个手机,则需要在各个类型下添加手机
    • 如果我们需要添加一个品牌,则需要在该品牌下添加各个类型的手机
  • 这样会造成基本的类爆炸,可以使用桥接模式对实现(手机品牌)和抽象(手机类型)分别进行向上抽取,通过抽象依赖实现的方式增强代码维护性

9.2,基本介绍

  • 桥接模式是指将实现抽象放在两个不同的类层次中,并可以进行独立改变。桥接模式是一种结构性设计模式
  • 桥接模式基于类的最小设计原则,使用封装、聚合和继承等行为让不同的类承担不同的职责。主要特点是把**抽象(Abstraction)实现(Implementation)**分离开来,从而保证各部分的独立性及功能扩展

9.3,类图

在这里插入图片描述

  • 对抽象和实现进行拆分,拆分为两个独立的模块,并通过组合关系关联在一起
  • 抽象模块是手机类型模块,以PhoneType为顶层抽象类,并派生出UpRightTypeFlodedType等具体类型类
  • 实现模块是手机品牌模块,以IBrand为顶层接口,并派生出各个手机品牌
  • 手机类型组合手机品牌,将手机品牌作为其内部的构造参数
  • 客户端在进行具体操作时,默认先适配机型,再适配具体手机

9.4,代码示例

  • 实现模块顶层接口:IBrand

    package com.self.designmode.bridge;
    
    /**
     * 手机品牌: 实现层顶层接口
     * @author PJ_ZHANG
     * @create 2020-07-27 17:51
     **/
    public interface IBrand {
        void open();
        void call();
        void close();
    }
    
  • 实现模块实现类_1:Huawei

    package com.self.designmode.bridge;
    
    /**
     * 具体实现类: 华为手机
     * @author PJ_ZHANG
     * @create 2020-07-27 17:55
     **/
    public class Huawei implements IBrand {
        @Override
        public void open() {
            System.out.println("华为手机开机...");
        }
    
        @Override
        public void call() {
            System.out.println("华为手机打电话...");
        }
    
        @Override
        public void close() {
            System.out.println("华为手机关机");
        }
    }
    
  • 实现模块实现类_2:Xiaomi

    package com.self.designmode.bridge;
    
    /**
     * 具体实现类: 小米手机
     * @author PJ_ZHANG
     * @create 2020-07-27 17:56
     **/
    public class Xiaomi implements IBrand {
        @Override
        public void open() {
            System.out.println("小米手机开机...");
        }
    
        @Override
        public void call() {
            System.out.println("小米手机打电话...");
        }
    
        @Override
        public void close() {
            System.out.println("小米手机关机");
        }
    }
    
  • 抽象模块顶层抽象类:PhoneType

    package com.self.designmode.bridge;
    
    import com.self.designmode.adapter.interfaceadapter.Phone;
    
    /**
     * 手机类型: 抽象层顶层类
     * @author PJ_ZHANG
     * @create 2020-07-27 17:53
     **/
    public abstract class PhoneType {
        private IBrand brand;
        public PhoneType(IBrand brand) {
            this.brand = brand;
        }
        public void open() {
            brand.open();
        }
        public void call() {
            brand.call();
        }
    
        public void close() {
            brand.close();
        }
    }
    
  • 抽象模块子类_1:FlodedType

    package com.self.designmode.bridge;
    
    /**
     * 抽象子类: 旋转类型手机
     * @author PJ_ZHANG
     * @create 2020-07-27 17:57
     **/
    public class FlodedType extends PhoneType{
        public FlodedType(IBrand brand) {
            super(brand);
        }
        public void open() {
            super.open();
            System.out.println("旋转类型手机开机...");
        }
        public void call() {
            super.call();
            System.out.println("旋转类型手机打电话...");
        }
    
        public void close() {
            super.close();
            System.out.println("旋转类型手机关机...");
        }
    }
    
  • 抽象模块子类_2:UpRightType

    package com.self.designmode.bridge;
    
    /**
     * 抽象子类: 直立类型手机
     * @author PJ_ZHANG
     * @create 2020-07-27 17:57
     **/
    public class UpRightType extends PhoneType{
        public UpRightType(IBrand brand) {
            super(brand);
        }
        public void open() {
            super.open();
            System.out.println("直立类型手机开机...");
        }
        public void call() {
            super.call();
            System.out.println("直立类型手机打电话...");
        }
    
        public void close() {
            super.close();
            System.out.println("直立类型手机关机...");
        }
    }
    
  • 客户端:Client

    package com.self.designmode.bridge;
    
    /**
     * @author PJ_ZHANG
     * @create 2020-07-27 17:58
     **/
    public class Client {
        public static void main(String[] args) {
            PhoneType phoneType = new UpRightType(new Huawei());
            phoneType.call();
    
            phoneType = new FlodedType(new Xiaomi());
            phoneType.open();
        }
    }
    

9.5,注意事项和细节

  • 实现了抽象部分和实现部分的分离,极大的提供了系统的灵活性,有助于系统的分层化设计,从而产生更好的结构化系统
  • 对于系统的高层部分,只需要知道抽象部分和实现部分的接口即可,具体业务由底层完成
  • 桥接模式替代多层继承关系,可以有效的介绍子类数量,降低系统管理和维护成本
  • 桥接模式的引入增加了系统的理解和设计难度,因为组合关联关系在抽象层,所以需要面向抽象层进行编程
  • 桥接模式需要准确的识别出系统中两个维度(抽象层,实现层),因此其使用场景有一定的局限性

9.6,常见使用场景

  • 银行转账系统
    • 转账分类:网上银行,柜台转账,ATM转账
    • 用户类型:普通用户,会员用户,金卡用户
  • 消息管理
    • 消息类型:即时消息,延时消息
    • 消息分类:手机短信,右键信息,QQ消息…
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java设计模式(9):桥接模式 的相关文章

随机推荐

  • 我的GIT练习Four

    目录 前言 GIT安装教程 Git作者 GIT优点 GIT缺点 为什么要使用 Git GIT练习Four C1 初始化项目 C2 设计项目首页 C3 设计登录页面 C4 实现登录功能 C5 设计后台页面 C6 设计注册页面 C7 实现注册功
  • 拼搏百天!上月喜获阿里内推,交叉面把面试官面傻眼了

    阿里内推一面 项目 1 面试官让我描述一个自己印象最深的项目 手画设计图 2 针对项目中的技术进行发问 比如 架构设计 部署图 模块之间的通信等 3 因为我描述项目存储数据比较多 让我重新设计数据库的表 怎么设计 后面都是针对项目技术的问题
  • iOS 蓝牙扫描枪扫描内容不正确

    背景 在移动设备上 使用蓝牙扫描枪 相当于接入了一下外接键盘 我们的客户使用我们的App 并连接蓝牙扫码枪 将扫描的内容传输到我们的App中 App再做出对应的响应 举个例子 较为常见的应用场景就是 拣货员拿着扫码枪 扫描产品上的UPC码
  • HttpClient的ssl方式发送请求

    最近因为项目需要 需要以rest方式和第三方平台交互 由于需要ssl方式连接 所以记录一下 maven依赖如下
  • openssl做HMAC实例(C++)

    1 HMAC简介 1 MAC Message Authentication Code 消息认证码算法 可以将其认为是含有秘钥的散列 Hash 函数算法 即兼容了MD和SHA算法 并在此基础上加上了秘钥 因此MAC算法也经常被称作HMAC算法
  • 常见的WRF运行错误

    转载至 https wk atmchem github io 2021 06 03 WRFbugandSolutions WPS Errors Ungrib exe Segmentation Fault Parsed 29 entries
  • sql server判断两个字符串是否相等(区分大小写)

    步骤 一 新增测试数据 新建测试表 create table testTable1 str1 varchar 100 str2 varchar 100 新增测试数据 如下图 二 两字符串进行比较 当直接使用 号进行判断时 是无法区分大小写的
  • 深度学习速学上手小项目

    demo仓库和视频演示 银色子弹zg的个人空间 银色子弹zg个人主页 哔哩哔哩视频 卷积网路CNN分类的模型一般使用包括alexnet DenseNet DLA GoogleNet Mobilenet ResNet ResNeXt Shuf
  • AIX下使用ASM

    metalink note 282036 1 IBM Software Requirements and PTFs for AIX 5 3 support of Oracle Database 10g Release 2 10 2 0 1
  • Anaconda 的Jupyter Notebook更换默认浏览器

    因为之前装的Anaconda默认使用的是系统自带的Edge浏览器 对的 就是这个玩意 然后自己近期一直用的win11 前几个版本还没什么太大问题 但是在20号左右系统自动更新了一下 对的就是这个 然后Microsoft Edge浏览器直接打
  • LUA中的and与or

    LUA中的and与or 2013 01 04 14 51 14074人阅读 评论 2 收藏 举报 分类 Lua 44 逻辑运算符认为false和nil是假 false 其他为真 0也是true and的优先级比or高 其它语言中的and表示
  • 小程序的数据驱动和Vue的双向绑定有何异同

    引言 在现代应用程序开发中 数据驱动和双向绑定是两个非常重要的概念 它们能够提供更好的用户体验和开发效率 本文将探讨小程序的数据驱动和Vue的双向绑定 并通过代码实例来说明它们的异同 让我们一起来了解吧 小程序的数据驱动 小程序是一种轻量级
  • Java初阶——练习题

    import java util Random import java util Scanner public class java 11 1 public static void main String args int ret numb
  • 模板的特化(具体化)

    模板的特化 具体化 重点注意 1 类模板和函数模板都可以被全特化 2 类模板能偏特化 不能被重载 3 函数模板可以实现重载 不能被偏特化 4 类模板调用优先级 全特化类 gt 偏特化类 gt 主版本模板类 6 函数模板同时存在具体化模板 函
  • ZYNQ中FreeRTOS中使用定时器

    使用普通的Timer中断方式时 Timer中断可以正常运行 但是UDP通信进程无法启动 其中TimerIntrHandler是中断服务程序 打印程序运行时间与从BRAM中读取的数据 void SetupInterruptSystem XSc
  • JetBrains各版本全家桶工具 编程开发全套永久软件!IDE也能免费用

    程序员每次换新电脑装IDE总是少不了的 但是奈何激活码难找 功夫不负有心人终于让我找到了激活方法 而且是可以永久激活的 更赞的是操作简单 无需注册机也无需修改文件和host 而且支持2018 2019 2020全版本的全家桶软件 之前也激活
  • shell 多线程介绍与举例

    在Shell脚本中实现多线程通常可以使用以下几种方式 后台执行 在Shell脚本中 你可以使用 符号将某个命令放在后台执行 这样可以同时执行多个命令 达到多线程的效果 例如 bin bash command1 command2 comman
  • CSerialPort教程4.3.x (4) - CSerialPort在QT中的使用

    CSerialPort教程4 3 x 4 CSerialPort在QT中的使用 环境 QT 5 6 3 前言 CSerialPort项目是一个基于C C 的轻量级开源跨平台串口类库 可以轻松实现跨平台多操作系统的串口读写 同时还支持C Ja
  • FTP:服务器发回了不可路由的地址,使用服务器地址代替 问题解决方案

    状态 连接建立 等待欢迎消息 状态 初始化 TLS 中 状态 TLS 连接已建立 状态 已登录 状态 读取目录列表 状态 服务器发回了不可路由的地址 使用服务器地址代替 打开阿里云控制面板 把放行端口中的39000 40000加入放行规则
  • Java设计模式(9):桥接模式

    9 桥接模式 Bridge 9 1 问题引入 手机类型 现在对不同类型不同品牌的手机实现操作编程 如下手机外观类型和对应品牌 则需要编写的代码类图可能如下 带来的问题如下 如果我们需要添加一个手机 则需要在各个类型下添加手机 如果我们需要添