Java常用设计模式————桥接模式

引言

在实际的业务中,经常会遇到多维度的概念组合,公园的门票,颐和园有年票、月票、日票,故宫也有年票、月票、日票。那么不同的公园票种类型就可以视为两种不同的纬度,它们之间会形成相互组合的关系。

在类的设计上,如果任由两种纬度的类任意组合的话,那么就会形成笛卡尔积的情况,使类泛滥,难以维护。

在设计模式中,桥接模式就是为了解决这个问题而提出的,它通过将两种或多种纬度以上层抽象的组合关系为基础,形成一种桥接模型,将业务的组合时机延迟到客户端调用使才发生,避免在编写类的时候,大量的枚举每一种具体情况。

一、待解决问题描述

类似上面公园和票种的纬度关系,这里提出一种简单的案例:形状和颜色。

假设我们需要两种不同的形状——圆形、正方形,和两种不同的颜色——红色、白色,并将它们组合以产生特定的类型,那么我们就需要四种不同:

这种做法虽然简单直观,但也大大增加了类的数量,而且两个维度的概念耦合性太强,如果增加了新的纬度,那么类的规模将成倍增长。

二、桥接模式类图

在学习桥接模式的时候,不仅应该掌握最主要的纬度的划分与如何实现桥接,还应该思考桥接模式之外的内容,比如上面的例子中,我们可以很清晰的划分出形状颜色两个维度,同时下面的类图也展示了通过怎样的编码技巧实现桥接的解耦。还有一点之外的内容就是,我们应该以哪种维度作为主干?为什么接入主干维度的其他维度要采用接口?而主干维度采用抽象类?

上图中,Shape是一个抽象类,这是对主干维度——形状的一个抽象,其实现类有Circle、Square,它们代表了一种具体的形状。

Color是一个接口,Red、White代表两种不同的具体的颜色。

在这个例子中,Color 和 Shape 相比,很显然Shape更像是一种主体纬度,而颜色,更适合作为一种附属属性依附于主体纬度,在这个例子中 Color 仅仅提供了一种行为,所以直接使用接口来描述,这当然不是必须的。

Color 与 Shape 的关系是聚合,采用的是 set 方法注入到 Shape 中,这需要根据具体的业务来判断两种纬度的依赖关系,聚合的耦合度更低,且更灵活,可以只在必要的时候将两种纬度聚合在一起。而组合可能在构造时就需要传入属性,这需要视具体情况而定。

三、桥接模式的具体实现

/*** 主干维度————形状*/
public abstract class Shape {protected Color color;public void setColor(Color color) {this.color = color;}public abstract void draw();
}
/*** 颜色维度*/
public interface Color {void paint(String shape);
}
public class Circle extends Shape {@Overridepublic void draw() {color.paint("圆形");}
}
public class Square extends Shape {@Overridepublic void draw() {color.paint("正方形");}
}
public class Red implements Color {@Overridepublic void paint(String shape) {System.out.println("红色的" + shape);}
}
public class White implements Color {@Overridepublic void paint(String shape) {System.out.println("白色的" + shape);}
}

 以上是桥接模式中的几个重要角色,以下是测试代码:

public class Client {public static void main(String[] args) {Shape square = new Square();square.setColor(new Red());square.draw();square.setColor(new White());square.draw();System.out.println("==============");Shape circle = new Circle();circle.setColor(new Red());circle.draw();circle.setColor(new White());circle.draw();}
}

输出结果:

红色的正方形
白色的正方形
==============
红色的圆形
白色的圆形

总结

桥接模式基于类的最小设计原则,其中包括几个重要的角色:

1、Client,客户端

2、Abstraction,抽象类

3、Refined Abstraction ,扩展抽象类

4、Implementor,行为实现类接口

5、ConcreteImplementor, 具体的行为实现

桥接模式标准类图如下: 

桥接模式有以下几点好处:

1、实现了抽象与行为的分离

2、更好的扩展性

3、可动态切换实现

4、实现细节对客户端透明,可以对用户隐藏实现细节

缺点也有几点:

1、增加了系统的理解难度和设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计和编程。

2、桥接模式要求正确识别出系统中的两个独立变化的纬度,因此使用范围具有一定的局限性。

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

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

相关文章

Java常用设计模式————装饰者模式

引言 装饰者模式,又叫装饰器模式。它可以动态的将新功能附加到对象上。在对象功能扩展方面,它比继承更灵活,同时装饰者模式也体现了OCP原则。 在客户端调用使用了装饰者模式的对象时,就好像在使用构造器层层包裹核心对象&#x…

Java常用设计模式————组合模式

引言 组合模式,是一种类似递归算法的结构性设计模式,通过以简单的 List ,组合本类对象,实现树状对象结构的“部分、整体”的层次。 它可以让调用程序不需要关心复杂对象与简单对象的区别,而统一地实现处理逻辑。 对…

Java常用设计模式————外观模式

引言 外观模式(Facade Pattern),又叫“过程模式”。外观模式为子系统中的一组接口提供一个一致的入口,此模式定义了一个高层接口,这个接口使得这一组子系统更加易用。 一、案例分析 生活中有很多类似的案例&#xf…

Java常用设计模式————享元模式

引言 享元模式,也叫蝇量模式(Flyweight Pattern)。运用共享技术有效地支持大量细粒度的对象。 享元模式常用于系统底层开发,解决系统的性能问题。例如数据库连接池,里面都是创建好的连接对象,在这些连接对…

IDEA——常用基础设置

一、设置入口 File—>Settings... 或者 在工具栏的“小扳手”图标。 二、主题设置 三、编辑通用设置 设置面板中的 Editor 3.1 自动导包 可以设置IDEA自动为程序导包,在书写时加入准确的导包,在书写时优化导包(自动去掉未使用的&#…

IDEA——常用快捷键

引言 总结 IDEA 的常用快捷键,除了部分快捷键与 Eclipse 保持一致之外,枚举更多的实用快捷键。 一、如何设置快捷键 在 Settings -> Keymap 中,下拉框里选择 Eclipse ,即可将 IDEA 的快捷键设置为与 Eclipse 保持一致。但并…

IDEA——常用代码模板

引言 IDEA 提供了一些内置的代码模板,可以让开发者快速方便的使用,当然 eclipse 中也是有的,比如输入 syso 快速生成输出语句,main 快速生成主函数等。 idea 的模板设置都在 Settings --> Live Templates 和 General-->Po…

IDEA——Git 的设置与使用

引言 在本机下载好 Git 之后,再去在 IDEA 中设置 Git 相关的参数。详细的 Git 操作和 Eclipse 大同小异,可以移步至:《Git必知必会》 一、设置Git执行程序路径 二、导入一个新的远程 git 托管项目 打开 File ——> New ——> Project…

IDEA——Maven的配置与使用

引言 简单介绍一下如何在 idea 中配置maven,以及如何去使用 maven 。 一、配置 Maven home Maven home 和 settings 文件一般都需要进行重新设置,关联到本机已经安装好的 maven 版本,settings 这里可以使用默认,也可以设置为 ma…

Spring Cloud Alibaba——Nacos实现服务治理

引言 本博客总结微服务开发中各个微服务调用的实现,并使用 Nacos 完成服务注册和发现。 文章中会涉及到 maven 的使用,以及 spring boot 的一些知识。开发工具采用 IDEA 2020.2。 设计一个电商订单和商品购买微服务,实现微服务的注册发现与…

Spring Cloud —— Feign 实现服务调用

引言 本篇博客简单介绍 Feign 的基础知识和基本应用,以前一篇博客《Spring Cloud Alibaba——Nacos实现服务治理》为代码基础,实现更简单的微服务调用方式。 一、什么是Feign restTemplate 实现的微服务调用方式: // 调用商品微服务&…

Spring Cloud —— 负载均衡与 Ribbon 应用

引言 本篇博客简单介绍微服务负载均衡的概念,并通过 IDEA 多端口启动应用的方式,模拟多个应用实例,使用自定义和 Ribbon 两种方式实现基本的负载均衡策略。 微服务代码以《Spring Cloud Alibaba——Nacos实现服务治理》为基础。 一、什么是…

Spring —— 容器内部逻辑

引言 上一篇关于IoC容器的详解《Spring —— IoC 容器详解》真是工程浩大,可以说Spring官网对核心中的核心IOC容器做了非常全面的使用说明,包括在《Spring揭秘》中让我一直没有成功的Method Injection,官网也解决了我的疑惑,并最…

2020 年度总结

2020年给我的感觉是短平快的一年。 由于年初的新冠肺炎疫情,我大半年都呆在北京的破旧出租屋里写代码。整个春天和夏天,平平无奇。 2月1日返京,居家办公,夜跑。8月复工,疯狂爆痘、烂脸,月末落户天津。9月…

JDBC——概述与JDBC的使用

引言 一直希望深入学习一下数据库持久化技术,接触过Hibernate、Mybatis,也使用过Spring事务管理来控制回滚操作,但是越发觉得底层知识有一定的知识盲区和空洞。 很多ORM框架都是基于JDBC规范来进行构建的,因此,学习J…

JDBC——编程式事务的实现逻辑

引言 数据库事务的概念和基础,总结在《MySQL 基础 ————事务与隔离级别总结》。 本篇博客通过“JDBC 纯编码”方式实现事务控制,完成一个 A 给 B 转账的小功能,在进一步熟练JDBC的编程流程的同时,重点关注 Java 语言如何操作…

排序算法——插入排序

一、算法思想 给定一个无序数列,模拟一个指针从第0位开始向后,始终保持当前位置左边的数列是有序的。 指针位置上的元素依次与前面的元素比较,当遇到小于自己的数或右边已经没有元素时,都停止比较,开始下一轮。 生活…

Linux 底层原理 —— epoll 与多路复用

引言 epoll 是 Linux 系统下高性能网络服务的必备技术,很多面试中高频出现的 Nginx、Redis 都使用了这一技术,本文总结 linux 多路复用模型的演变过程,看一看epoll 是如何实现高性能的。 一、相关基础知识 1.1 文件描述符 文件描述符&…

异或运算的应用

一、基础知识 异或运算,相异为1。 异或运算是一种常用的位运算,在算法题中,对于避免额外的空间复杂度有独特的用处。 异或运算也被称为“无进位相加”,它具有以下特性: 特性1:0 ^ N N 特性2&#xff1a…

单向队列、双端队列、栈的模型实现

引言 自己实现简单的队列、栈的逻辑结构。 队列都包含头和尾两个指针,简单的单向队列只能在一端(如:head端)入列,在另一端(如:tail 端)出列;双端队列可以在 head 进出&…