7.桥接模式

news2024/12/23 17:48:56

目录

简介

定义

特点

结构

示例

1. 新建 Brand.interface 接口类,定义不同品牌手机共有的基本功能

 2. 新建 Xiaomi.class 类,实现 Brand.interface 接口,实现具体功能

3. 新建 Vivo.class 类,实现 Brand.interface 接口,实现具体功能

4. 新建 Phone.class 类,这是桥接类,定义手机操作行为,不限手机品牌

5. 新建 FolderPhone.class 折叠样式手机类,继承 Phone.class,获得手机的功能;这一步就把手机样式和功能桥接起来了

6. 添加测试类,测试不同品牌折叠样式手机的功能


简介

在现实生活中,某些类具有两个或多个维度的变化,如图形既可按形状分,又可按颜色分;如何设计类似于 Photoshop 这样的软件,能画不同形状和不同颜色的图形呢?如果用继承方式,m 种形状和 n 种颜色的图形就有 m×n 种,不但对应的子类很多,而且扩展困难;桥接模式就是为了解决这样的问题

定义

桥接模式是将抽象部分与它的实现部分分离,使它们都可以独立地变化;它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(interface)模式

特点

桥接模式是指将实现与抽象放在两个不同的类层次中,使两个层次可以独立改变;

桥接模式是一种结构型设计模式

桥接模式基于类的最小设计原则,通过使用封装、聚合及继承等行为让不同的类承担

不同的职责;它的特点是把抽象的与行为分离开来,从而可以保持各部分的独立性以及对他们的功能扩展

结构

1)抽象化(Abstraction)角色:定义抽象类,并包含一个对实现化对象的引用

2)扩展抽象化(Refined Abstraction)角色:是抽象化角色的子类,实现父类中的业务方法,并通过组合关系调用实现化角色中的业务方法

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

4)具体实现化(Concrete Implementor)角色:给出实现化角色接口的具体实现

示例

以手机为例,手机有多个品牌(小米、vivo ...),有多种样式(折叠、直板、滑盖 ...),有多种功能(开机、关机、打电话 ...),使用桥接模式把手机品牌和样式分开实现然后再关联起来

示例代码

1. 新建 Brand.interface 接口类,定义不同品牌手机共有的基本功能

/**
 * 手机品牌, 任何品牌的手机都具有
 * 开机, 关机, 打电话的功能
 */
public interface Brand {
    // 开机
    void open();
    // 关机
    void close();
    // 打电话
    void call();
}

 2. 新建 Xiaomi.class 类,实现 Brand.interface 接口,实现具体功能

/**
 * 小米手机类, 实现具体功能
 */
public class Xiaomi implements Brand {
    @Override
    public void open() {
        System.out.println("小米手机开机");
    }

    @Override
    public void close() {
        System.out.println("小米手机关机");
    }

    @Override
    public void call() {
        System.out.println("小米手机打电话");
    }
}

3. 新建 Vivo.class 类,实现 Brand.interface 接口,实现具体功能

/**
 * vivo 手机类, 实现具体功能
 */
public class Vivo implements Brand {
    @Override
    public void open() {
        System.out.println("vivo手机开机");
    }

    @Override
    public void close() {
        System.out.println("vivo手机开机");
    }

    @Override
    public void call() {
        System.out.println("vivo手机打电话");
    }
}

4. 新建 Phone.class 类,这是桥接类,定义手机操作行为,不限手机品牌

/**
 * 桥接类, 定义手机操作行为, 不局限具体手机品牌
 */
public abstract class Phone {
    // 关联手机类型
    private Brand brand;
    public Phone(Brand brand) {
        this.brand = brand;
    }
    // 开机
    protected void open() {
        this.brand.open();
    }
    // 关机
    protected void close() {
        this.brand.close();
    }
    // 打电话
    protected void call() {
        this.brand.call();
    }
}

5. 新建 FolderPhone.class 折叠样式手机类,继承 Phone.class,获得手机的功能;这一步就把手机样式和功能桥接起来了

/**
 * 手机样式:折叠手机
 */
public class FolderPhone extends Phone {
    public FolderPhone(Brand brand) {
        super(brand);
    }
    // 开机
    public void open() {
        super.open();
        System.out.println("折叠样式手机开机");
    }
    // 关机
    public void close() {
        super.close();
        System.out.println("折叠样式手机关机");
    }
    // 打电话
    public void call() {
        super.call();
        System.out.println("折叠样式手机打电话");
    }
}

6. 添加测试类,测试不同品牌折叠样式手机的功能

/**
 * 测试类
 */
public class Test {
    public static void main(String[] args) {
        Phone xiaomi = new FolderPhone(new Xiaomi());
        xiaomi.open();
        xiaomi.close();
        xiaomi.call();

        Phone vivo = new FolderPhone(new Vivo());
        vivo.open();
        vivo.close();
        vivo.call();
    }
}

观察上述代码,这种设计模式带来的最大好处就是:当我们需要扩展更多样式的手机或者更多品牌的手机的时候,不需要动原来的代码,只需要继续添加样式或品牌手机类即可

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Mybatis源码学习笔记(六)之Mybatis中集成日志框架原理解析

1 Mybatis中集成日志框架示例 1.1 Mybatis使用log4j示例&#xff08;推荐方式&#xff09; 第一步&#xff1a;pom.xml引入log4j依赖 <!-- slf4j日志门面 --><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId&…

Thinkphp6使用RabbitMQ消息队列

Thinkphp6连接使用RabbitMQ&#xff08;不止tp6&#xff0c;其他框架对应改下也一样&#xff09;&#xff0c;如何使用Docker部署RabbitMQ&#xff0c;在上一篇已经讲了->传送门<-。 部署环境 开始前先进入RabbitMQ的web管理界面&#xff0c;选择Queues菜单&#xff0c;点…

深度学习实战20(进阶版)-文件智能搜索系统,可以根据文件内容进行关键词搜索,快速找到文件

大家好&#xff0c;我是微学AI&#xff0c;今天给大家带来深度学习实战项目-文件智能搜索系统&#xff0c;文件智能搜索系统是一种能够帮助用户通过文件的内容快速搜索和定位文件的软件系统。 随着互联网和数字化技术的普及&#xff0c;数据和信息呈现爆炸式增长的趋势&#xf…

ubuntu 将jupyter-lab保存为桌面快捷方式和favourites

ubuntu: 将jupyter-lab保存为桌面快捷方式和favourites desktop shortcut 建立一个新的desktop文件 cd ~/Desktop touch Jupyter-lab.desktop将文件修改成如下&#xff1a; [Desktop Entry] Version1.0 NameJupyterlab CommentBack up your data with one click Exec/home/cjb/…

SpringCloud学习笔记(一)

单体应用架构 在诞⽣之初&#xff0c;拉勾的⽤户量、数据量规模都⽐较⼩&#xff0c;项目所有的功能模块都放在一个工程中编码、编译、打包并且部署在一个Tomcat容器中的架构模式就是单体应用架构。 优点&#xff1a; 高效开发&#xff1a;项⽬前期开发节奏快&#xff0c;团…

02-Oracle数据库的启动与关闭

本文章主要讲解Oracle数据库的启动与关闭方法&#xff0c;详细讲解启动Oracle的命令&#xff0c;三种启动数据库的方法及区别&#xff1b;关闭数据库的4种方法及他们的区别。 启动和关闭数据库 •数据库没启动前&#xff0c;只有拥有DBA权限或者以sysoper或sysdba身份才能连接到…

设计跳表(动态设置节点高度)

最近学习redis的zset时候&#xff0c;又看到跳表的思想&#xff0c;突然对跳表的设置有了新的思考 这是19年设计的跳表&#xff0c;在leetcode的执行时间是200ms 现在我对跳表有了新的想法 1、跳表的设计&#xff0c;类似二分查找&#xff0c;但是不是二分查找&#xff0c;比较…

基于Canal的数据同步

基于Canal的数据同步 一、 系统结构 该数据同步系统由Spring Boot和Canal共同组成。 Spring Boot 是一个流行的 Java Web 框架&#xff0c;而 Canal 则是阿里巴巴开源的 MySQL 数据库的数据变更监听框架。结合 Spring Boot 和 Canal&#xff0c;可以实现 MySQL 数据库的实时数…

ASGCN之图卷积网络(GCN)

文章目录前言1. 理论部分1.1 为什么会出现图卷积网络&#xff1f;1.2 图卷积网络的推导过程1.3 图卷积网络的公式2. 代码实现参考资料前言 本文从使用图卷积网络的目的出发&#xff0c;先对图卷积网络的来源与公式做简要介绍&#xff0c;之后通过一个例子来代码实现图卷积网络…

Linux命令行安装Oracle19c教程和踩坑经验

安装 下载 从 Oracle官方下载地址 需要的版本&#xff0c;本次安装是在Linux上使用yum安装&#xff0c;因此下载的是RPM。另外&#xff0c;需要说明的是&#xff0c;Oracle加了锁的下载需要登录用户才能安装&#xff0c;而用户是可以免费注册的&#xff0c;这里不做过多说明。 …

最新使用nvm控制node版本步骤

一、完全卸载已经安装的node、和环境变量 ①、打开控制面板的应用与功能&#xff0c;搜索node&#xff0c;点击卸载 ②、打开环境变量&#xff0c;将node相关的所有配置清除 ③、打开命令行工具&#xff0c;输入node-v&#xff0c;没有版本号则卸载成功 二、下载nvm安装包 ①…

SBUS的协议详解

SBUS 1.串口配置&#xff1a; 100k波特率&#xff0c; 8位数据位&#xff08;在stm32中要选择9位&#xff09;&#xff0c; 偶校验&#xff08;EVEN), 2位停止位&#xff0c; 无控流&#xff0c;25个字节&#xff0c; 2.协议格式&#xff1a; [startbyte] [data1][data2]……

单月涨粉超600w,直播销售额破5亿,2月的黑马都是谁?

2月的抖音&#xff0c;黑马多多&#xff0c;处处有爆点。有直播间热度不减&#xff0c;在带货领域持续位列前茅&#xff1b;有达人通过“抓马式”连麦直播&#xff0c;涨粉657w&#xff1b;有0.01元的低价商品&#xff0c;一天热卖超1000w个。那么&#xff0c;2月有哪些主播表现…

微服务实战03-注册数据服务

EurekaServer &#xff0c;它扮演的角色是注册中心&#xff0c;用于注册各种微服务&#xff0c;以便于其他微服务找到和访问。有了EurekaServer&#xff0c;还需要一些微服务&#xff0c;注册到EurekaServer上去。 这一节&#xff0c;我们来写一个注册微服务。为了简单起见&am…

【同步工具类:Phaser】

同步工具类:Phaser介绍特性动态调整线程个数层次Phaser源码分析state 变量解析构造函数对state变量赋值阻塞方法arrive()awaitAdvance()业务场景实现CountDownLatch功能代码测试结果实现 CyclicBarrier功能代码展示测试结果总结介绍 一个可重复使用的同步屏障&#xff0c;功能…

26- AlexNet和VGG模型分析 (TensorFlow系列) (深度学习)

知识要点 AlexNet 是2012年ISLVRC 2012竞赛的冠军网络。 VGG 在2014年由牛津大学著名研究组 VGG 提出。 一 AlexNet详解 1.1 Alexnet简介 AlexNet 是2012年ISLVRC 2012&#xff08;ImageNet Large Scale Visual Recognition Challenge&#xff09;竞赛的冠军网络&#xff0…

paddle推理部署(cpu)

我没按照官方文档去做&#xff0c;吐槽一下&#xff0c;官方文档有点混乱。。一、概述总结起来&#xff0c;就是用c示例代码&#xff0c;用一个模型做推理。二、示例代码下载https://www.paddlepaddle.org.cn/paddle/paddleinferencehttps://github.com/PaddlePaddle/Paddle-In…

Clion连接Docker,使用HElib库

文章目录需求Clion连接服务器内的DockerDockerCLionDocker内配置HElib库参考需求 HElib库是用C编写的同态加密开源库&#xff0c;一般在Linux下使用为了不混淆生产环境&#xff0c;使用Docker搭建HElib运行环境本地在Windows下开发&#xff0c;使用的IDE为Clion&#xff0c;本…

动态规划:leetcode 121. 买卖股票的最佳时机、122. 买卖股票的最佳时机II

leetcode 121. 买卖股票的最佳时机leetcode 122.买卖股票的最佳时机IIleetcode 121. 买卖股票的最佳时机给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。你只能选择 某一天 买入这只股票&#xff0c;并选择在 未来的某一个不同的日…

node版本管理工具nvm

1.标题卸载nvm和node.js 系统变量中删除nvm添加变量&#xff1a;NVM_HOME和NVM_SYMLINK环境变量中 path&#xff1a;删除nvm自动添加的变量 Path %NVM_HOME%;%NVM_SYMLINK%删除自身安装node环境&#xff0c;参考图一图二 图一 图二 2.安装nvm nvm-window下载------https:/…