解锁Spring Boot中的设计模式—04.桥接模式:探索【桥接模式】的奥秘与应用实践!

桥接模式

桥接模式也称为桥梁模式、接口模式或者柄体(Handle and Body)模式,是将抽象部分与他的具体实现部分分离,使它们都可以独立地变化,通过组合的方式建立两个类之间的联系,而不是继承。

桥接模式是一种结构型设计模式,旨在将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过使用组合而不是继承的方式,可以更灵活地组织和管理代码。

结构:

  • 抽象部分(Abstraction):定义抽象类或接口,并维护一个指向实现部分的引用。
  • 扩充抽象类(Refined Abstraction):扩展抽象部分,可以添加更多的功能。
  • 实现部分(Implementor):定义实现类接口,供抽象部分调用。
  • 具体实现类(Concrete Implementor):实现实现部分的接口,提供具体的功能实现

优点:

  1. 解耦合:桥接模式能够将抽象部分和实现部分分离,使它们可以独立地进行变化。这种解耦合使得系统更加灵活和可维护。
  2. 扩展性:由于桥接模式采用了组合的方式而不是继承,因此更容易扩展和变化。新的抽象部分和实现部分可以独立地添加和修改,而不会对现有的代码产生影响。
  3. 隐藏实现细节:桥接模式可以隐藏实现的细节,使客户端代码只关注于抽象部分,而不需要关心具体的实现细节。这种隐藏可以减少系统中的耦合度,提高代码的可维护性和可理解性。
  4. 适应变化:桥接模式使得系统更加灵活和适应变化。通过抽象部分和实现部分的分离,系统可以更容易地应对需求的变化和新的功能的添加。

缺点:

  1. 增加复杂性:桥接模式引入了抽象部分和实现部分之间的桥梁,可能会增加系统的复杂性。特别是对于简单的系统,使用桥接模式可能会显得过于复杂。
  2. 理解成本:由于桥接模式涉及到多个类和接口之间的关系,可能会增加新成员对系统的理解成本。需要仔细地理解抽象部分和实现部分之间的关系,以及桥接模式的设计思想。
  3. 过度设计:在某些情况下,使用桥接模式可能会导致过度设计的问题。如果系统的抽象部分和实现部分之间的关系比较简单,使用桥接模式可能会显得不够自然和合适。
  4. 设计复用性:虽然桥接模式提高了系统的灵活性和扩展性,但如果不恰当地使用,可能会导致设计复用性下降。过度使用桥接模式可能会导致代码结构的过度抽象,使得代码变得难以理解和维护。

注意事项

  • 桥接模式适用于系统中多个维度的变化。
  • 避免过度设计,只有当两个维度中的一个或两个具有多个实现时才考虑使用桥接模式。

适用场景

  • 系统有多个维度同时变化,且不希望使用多层继承。
  • 想要在抽象和实现之间建立一个稳定的联系,但又不希望二者紧密耦合。

1.案例1-发送通知

需求

假设我们正在开发一个电商平台,该平台需要发送不同类型的通知给用户,例如电子邮件通知、短信通知、App推送通知等。同时,用户可能也有不同的偏好和设备,例如有些用户更喜欢通过邮件接收通知,而另一些用户则更倾向于使用手机App接收通知。

实现思路

  1. 通知接口(Notification):定义了发送通知的方法。
  2. 具体通知类(ConcreteNotification):实现了通知接口的具体通知类型,如邮件通知、短信通知、App推送通知等。
  3. 用户偏好(UserPreference):定义了用户的通知偏好,包含具体通知类,例如用户更喜欢接收邮件通知还是App推送通知。
  4. 用户类(User)包含用户的信息和偏好设置
  5. 通知服务类(NotificationService):负责根据用户的偏好选择合适的通知方式进行发送。(包含用户信息
Notification
+sendNotification(message)
EmailNotification
+sendNotification(message)
SMSNotification
+sendNotification(message)
AppNotification
+sendNotification(message)
UserPreference
+getNotification()
User
-preference: UserPreference
+receiveNotification(message)
NotificationService
+sendNotificationToUser(user, message)

在这里插入图片描述

1.1.通知接口
/**
 * 通知接口
 * @author 13723
 * @version 1.0
 * 2024/2/7 10:17
 */
public interface Notification {
	/**
	 * 通知
	 * @param message 通知消息
	 */
	void notify(String message);
}
1.1.2.具体通知类-APP
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.invoke.MethodHandles;

/**
 * APP通知类
 * @author 13723
 * @version 1.0
 * 2024/2/7 10:19
 */
public class APPNotification implements Notification{
	private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

	/**
	 * APP通知
	 * @param message 通知消息
	 */
	@Override
	public void notify(String message) {
		logger.error("【APP通知】: {}", message);
	}
}

1.1.3.具体通知类-短信
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.invoke.MethodHandles;

/**
 * 邮箱通知类
 * @author 13723
 * @version 1.0
 * 2024/2/7 10:21
 */
public class EMailNotification implements Notification{
	private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

	/**
	 * 邮箱通知
	 * @param message 通知消息
	 */
	@Override
	public void notify(String message) {
		logger.error("【邮件通知】: {}", message);
	}
}

1.1.4.具体通知类-邮箱
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.invoke.MethodHandles;

/**
 * 邮箱通知类
 * @author 13723
 * @version 1.0
 * 2024/2/7 10:21
 */
public class EMailNotification implements Notification{
	private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

	/**
	 * 邮箱通知
	 * @param message 通知消息
	 */
	@Override
	public void notify(String message) {
		logger.error("【邮件通知】: {}", message);
	}
}

1.1.5.用户偏好类
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.invoke.MethodHandles;

/**
 * 用户偏好类
 * @author 13723
 * @version 1.0
 * 2024/2/7 10:23
 */
public class UserPreference {
	private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
	/**
	 * 此处引入通知接口,实现桥接模式,将通知接口和用户偏好类解耦
	 */
	private Notification notification;

	/**
	 * 用户偏好
	 * @param notification 通知
	 */
	public UserPreference(Notification notification) {
		this.notification = notification;
	}

	public Notification getNotification() {
		return notification;
	}
}
1.1.6.用户类
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.invoke.MethodHandles;

/**
 * 用户类
 * @author 13723
 * @version 1.0
 * 2024/2/7 10:26
 */
public class User {
	private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
	/**
	 * 用户名称
	 */
	private String name;

	/**
	 * 用户偏好
	 */
	private UserPreference userPreference;

	public User(String name, UserPreference userPreference) {
		this.name = name;
		this.userPreference = userPreference;
	}

	protected void receiveNotification(String message) {
		message = name + ":" + message;
		userPreference.getNotification().notify(message);
	}

}
1.1.7.服务通知类
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.invoke.MethodHandles;

/**
 * @author 13723
 * @version 1.0
 * 2024/2/7 10:37
 */
public class NotificationService {
	private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());


	/**
	 * 发送通知
	 * @param user 用户,用户里面已经设置好偏好通知了,偏好通知里面已经设置好具体的通知方式了
	 * @param message 通知消息
	 */
	public void sendNotification(User user, String message) {
		user.receiveNotification(message);
	}
}

1.1.8.测试类
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.invoke.MethodHandles;

/**
 * 测试 桥梁模式-通知用户
 * @author 13723
 * @version 1.0
 * 2024/2/7 10:42
 */
public class NotificationTest {
	private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());


	@Test
	@DisplayName("测试通知用户")
	public void testNotification() {
		// 设置通知方式
		APPNotification appNotification = new APPNotification();
		SMSNotification smsNotification = new SMSNotification();

		// 设置用户偏好
		UserPreference zs = new UserPreference(appNotification);
		UserPreference ls = new UserPreference(smsNotification);

		// 设置用户
		User user1 = new User("张三", zs);
		User user2 = new User("李四", ls);



		// 通知服务
		NotificationService notificationService = new NotificationService();

		notificationService.sendNotification(user1, "你好,你的账号被人盗走了!请联系客户找回,85852555!");
		notificationService.sendNotification(user2, "你好,你的账号被人盗走了!请联系客户找回,85852555!");


	}
}

在这里插入图片描述

2.Spring代码-JdbcTemplate

2.1.案例

@SpringBootTest
public class BridgeTest {
	private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

	@Test
	@DisplayName("测试template")
	public void test(){
		DriverManagerDataSource dataSource = new DriverManagerDataSource();
		dataSource.setDriverClassName("org.postgresql.Driver");
		dataSource.setUrl("jdbc:postgresql://192.168.1.56/postgres?currentSchema=gwstd");
		dataSource.setUsername("postgres");
		dataSource.setPassword("152564.lmy");
		JdbcTemplate jdbcTemplate = new JdbcTemplate();
		jdbcTemplate.setDataSource(dataSource);
		String sql = "select * from t_dec_order_head limit 1";
		List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
		for (Map<String, Object> map : maps) {
			logger.error("result:{}",map);
		}
	}
}

在这里插入图片描述

JdbcTemplate 使用了桥接模式来实现数据库操作的抽象和实现的解耦合。这种模式使得应用程序能够专注于高级的业务逻辑,而不必关心底层数据库访问的细节。

JdbcTemplate 使用了以下几个关键角色:

  1. 抽象部分(Abstraction)
    • JdbcTemplate 中,抽象部分代表了对数据库操作的抽象接口,例如 JdbcTemplate 类本身以及它的一些方法,如 query()update() 等。
    • 这些方法定义了客户端与数据库交互的高级操作,比如查询数据、更新数据等。
  2. 扩充抽象类(Refined Abstraction)
    • 在 JdbcTemplate 中,扩充抽象部分是对抽象部分的扩展,可以添加更多的功能或者调整现有的功能。
    • 例如,你可以创建自定义的 JdbcTemplate 子类,通过添加新的方法或者重写现有方法来实现更具体的数据库操作。
  3. 实现部分(Implementor)
    • JdbcTemplate 中,实现部分代表了对底层数据库访问的实现,例如 DataSource 接口和各种数据库驱动实现。
    • 这些实现提供了底层的数据库连接和操作功能,但不暴露给应用程序直接使用。
  4. 具体实现类(Concrete Implementor)
    • 具体实现类是实现部分的具体实现,比如 DriverManagerDataSourceC3P0DataSource 等。
    • 它们提供了具体的数据库连接池实现、连接配置等功能。
// 在创建JDBC的模板类时,需要传入数据源,这样JDBC的模板类才知道连接哪个数据库

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

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

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

相关文章

代码随想录刷题笔记 DAY 29 | 非递减子序列 No.491 | 全排列 No.46 | 全排列 II No. 47

文章目录 Day 2901. 非递减子序列&#xff08;No. 491&#xff09;1.1 题目1.2 笔记1.3 代码 02. 全排列&#xff08;No. 46&#xff09;2.1 题目2.2 笔记2.3 代码 03. 全排列 II&#xff08;No. 47&#xff09;3.1 题目3.2 笔记3.3 代码 Day 29 01. 非递减子序列&#xff08;…

数据结构——单链表专题

目录 1. 链表的概念及结构2. 实现单链表初始化尾插头插尾删头删查找在指定位置之前插入数据在指定位置之后插入数据删除指定位之前的节点删除指定位置之后pos节点销毁链表 3. 完整代码test.cSList.h 4. 链表的分类 1. 链表的概念及结构 在顺序表中存在一定的问题&#xff1a; …

15.一种坍缩式的简单——组合模式详解

当曾经的孩子们慢慢步入社会才知道&#xff0c;那年味渐淡的春节就像是疾驰在人生路上的暂停键。 它允许你在隆隆的鞭炮声中静下心来&#xff0c;瞻前顾后&#xff0c;怅然若失。 也允许你在寂静的街道上屏气凝神&#xff0c;倾听自己胸腔里的那团人声鼎沸。 孩子们会明白的&am…

库的操作【数据库】

目录 一、创建数据库 二、删除数据库 ​编辑 三、数据库编码问题 四、库的改查 查 1&#xff09;查有哪些数据库&#xff1a; 2&#xff09;使用某个数据库&#xff1a; 3&#xff09;当前在哪个数据库&#xff1a; 4&#xff09;有谁在使用 改alter 五、备份和恢复 …

Shiro-02-shiro 是什么?

序言 大家好&#xff0c;我是老马。 前面我们学习了 5 分钟入门 shiro 安全框架实战笔记&#xff0c;让大家对 shiro 有了一个最基本的认识。 shiro 还有其他优秀的特性&#xff0c;今天我们就一起来学习一下&#xff0c;为后续深入学习奠定基础。 Apache Shiro 是什么&…

2.18通过字符设备驱动分步注册过程实现LED驱动的编写,编写应用程序测试

应用程序&#xff1a; #include<stdlib.h> #include<stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include<unistd.h> #include<string.h> #include<sys/ioctl.h> #include"myled.h&quo…

LabVIEW智能家居控制系统

LabVIEW智能家居控制系统 介绍了一个基于LabVIEW的智能家居控制系统的开发过程。该系统利用LabVIEW软件与硬件设备相结合&#xff0c;通过无线网络技术实现家居环境的实时监控与控制&#xff0c;提升居住舒适度和能源使用效率。 项目背景&#xff1a;随着科技的发展和生活水平…

vue-router 实现路由懒加载

在现代的Web开发中&#xff0c;前端技术的发展日新月异。在构建大规模单页应用&#xff08;Single Page Application&#xff09;时&#xff0c;路由管理是一个非常重要的环节。随着用户对网页速度和性能的要求越来越高&#xff0c;有效的路由管理能够显著提升用户体验。本篇博…

【RT-DETR有效改进】利用EMAttention加深网络深度提高模型特征提取能力(特征选择模块)

一、本文介绍 本文给大家带来的改进机制是EMAttention注意力机制,它的核心思想是,重塑部分通道到批次维度,并将通道维度分组为多个子特征,以保留每个通道的信息并减少计算开销。EMA模块通过编码全局信息来重新校准每个并行分支中的通道权重,并通过跨维度交互来捕获像素级…

IT行业高含金量证书全解析:开启职业生涯新篇章

在快速发展的IT行业&#xff0c;持续学习和专业认证是提升个人竞争力的重要途径。全球范围内存在着众多的IT认证&#xff0c;它们不仅能够验证你的技术能力&#xff0c;还能在求职和职业晋升中起到关键作用。 本篇博客将深入探讨IT行业中部分高含金量的证书&#xff0c;包括中…

【IO流】IOException IO流异常

IOException IO流异常 1. 概述2. try...catch异常处理2.1 基础做法2.2 JDK7方案2.3 JDK9方案 3. 注意事项 异常 概括 1. 概述 IOException&#xff08;Input/Output Exception&#xff0c;输入/输出异常&#xff09;是 Java 编程中常见的异常类型之一。它是 java.io 包中定义的…

速看!2024年泰国国际电力能源展10月16-18日

2024年泰国&#xff08;亚洲&#xff09;国际电力能源展暨电工技术设备展 展会时间&#xff1a;2024年10月16-18日 展会地点&#xff1a;泰国.曼谷BITEC会展中心 主办单位&#xff1a;新加坡Fireworks展览集团 组织单位&#xff1a;武汉柏翰展览有限公司(Fireworks China) …

SQL Developer 小贴士:Unshared Worksheet

在Oracle SQL Developer中&#xff0c;最常用的功能应该是SQL Worksheet&#xff0c;或Worksheet。 可以创建两类Worksheet&#xff0c;即Worksheet和Unshared Worksheets。前者是共享数据库连接的&#xff0c;后者会单独创建自己的连接。前者的快捷键是AltF10&#xff1b;后者…

趋高技术开发出超低价的视觉尺寸测量仪软件

2024年1月1日元旦节当日&#xff0c;深圳市趋高技术有限公司Fuxi实验室开发组成员成功开发出一款视觉尺寸测量仪软件。这款软件类比市场价格处于超低价。仅报三千二百元。有需要的码农或客户都可以了解一下&#xff0c;带回家。 趋高技术HITREND是深圳的一家高科技公司。 …

阅读笔记(SOFT COMPUTING 2018)Seam elimination based on Curvelet for image stitching

参考文献&#xff1a; Wang Z, Yang Z. Seam elimination based on Curvelet for image stitching[J]. Soft Computing, 2018: 1-16. 注&#xff1a;SOFT COMPUTING 大类学科小类学科Top期刊综述期刊工程技术 3区 COMPUTER SCIENCE, ARTIFICIAL INTELLIGENCE 计算机&#xf…

【论文解读】Latency-Aware Collaborative Perception

Latency-Aware Collaborative Perception 摘要引言方法SystemSyncNet 实验 摘要 协作感知最近显示出提高单智能体感知感知能力的巨大潜力。现有的协同感知方法通常考虑理想的通信环境。然而&#xff0c;在实践中&#xff0c;通信系统不可避免地存在延迟问题&#xff0c;导致安…

IO进程线程第一天

1.完成注册登录功能&#xff1a; 做个小菜单&#xff0c;功能1&#xff1a;是注册功能&#xff0c;输入注册账户和注册密码&#xff0c;将账户和密码写入文件中 功能2&#xff1a;是登录功能&#xff0c;提示并输入登录账户和登录密码&#xff0c;并用其遍历文件中的每一组账户…

应用回归分析:岭回归

岭回归&#xff0c;也称为Tikhonov正则化&#xff0c;是一种专门用于处理多重共线性问题的回归分析技术。多重共线性是指模型中的自变量高度相关&#xff0c;这种高度的相关性会导致普通最小二乘法&#xff08;OLS&#xff09;估计的回归系数变得非常不稳定&#xff0c;甚至无法…

二维码的颜色怎么改变?轻松3步修改二维码样式

怎么修改二维码的颜色呢&#xff1f;一般我们制作的二维码或者经过系统生成的二维码大多都是黑白颜色的&#xff0c;有些小伙伴会觉得不太美观无法满足自己的使用需求。那么对于想要修改二维码样式的小伙伴&#xff0c;可以使用二维码生成器的二维码美化功能来处理&#xff0c;…

力扣 第 124 场双周赛 解题报告 | 珂学家 | 非常规区间合并

前言 整体评价 T4的dp解法没想到&#xff0c;走了一条"不归路", 这个区间合并解很特殊&#xff0c;它是带状态的&#xff0c;而且最终的正解也是基于WA的case&#xff0c;慢慢理清的。 真心不容易&#xff0c;太难了。 T1. 相同分数的最大操作数目 I 思路: 模拟 c…
最新文章