当前位置: 首页 > news >正文

设计模式-桥接模式、组合模式

桥接模式和组合模式很相似,虽然都是组合,但是处理的场景不一样。

内容

桥接模式

组合模式

组合关系

桥接模式的组合是“拥有”关系

组合模式的组合是“包含”关系

关系方向

横向(抽象层 ↔ 实现层)

纵向(父节点 ↔ 子节点)

组合深度

通常一层(无嵌套)

支持多层递归嵌套

设计动机

避免继承耦合,灵活替换实现

统一操作部分与整体,简化复杂结构

典型应用

跨平台开发、驱动封装

文件系统、组织架构、UI组件树

桥接模式

Bridge(桥接)—对象结构型模式定义:将抽象和实现解耦,使得两者可以独立地变化。用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。

AbsShape 封装了 IDrawProgram 接口,这样它的子类想从 “蓝色”切换到 “红色” 或者别的,只需 set 进去就行啦(你看,这 UML 图多像座桥)

需求:在原来圆形和方形进行涂颜色。

package com.example.bridge;public class BridgeDemo {
// 定义了抽象的绘制操作,具体的绘制方式(比如颜色)由实现类提供interface IDrawProgram {void drawShape(String shapeType);}// 实现了IDrawProgram接口,提供在红色中绘制的具体方式static class RedDrawProgram implements IDrawProgram {@Overridepublic void drawShape(String shapeType) {System.out.println("用红色绘制 " + shapeType + "。");}}// 实现了IDrawProgram接口,提供在蓝色中绘制的具体方式static class BlueDrawProgram implements IDrawProgram {@Overridepublic void drawShape(String shapeType) {System.out.println("用蓝色绘制 " + shapeType + "。");}}// 抽象形状 (Abstraction)
// 包含一个IDrawProgram的引用,负责将抽象和实现分离
// 形状的具体绘制行为委托给IDrawProgram的实现类static abstract class AbsShape {protected IDrawProgram mProgram; // 绘制程序的引用// 设置绘制程序的方法public void setProgram(IDrawProgram program) {this.mProgram = program;}// 抽象的绘制方法,由子类实现public abstract void draw();}// 圆形 (Refined Abstraction 1)
// 具体的形状,继承自AbsShape,并实现自己的绘制逻辑static class Circle extends AbsShape {@Overridepublic void draw() {if (mProgram != null) {// 将实际的绘制工作委托给mProgram对象mProgram.drawShape("圆形");} else {System.out.println("圆形没有设置绘制程序。");}}}// 方形 (Refined Abstraction 2)
// 具体的形状,继承自AbsShape,并实现自己的绘制逻辑static class Rectangle extends AbsShape {@Overridepublic void draw() {if (mProgram != null) {// 将实际的绘制工作委托给mProgram对象mProgram.drawShape("方形");} else {System.out.println("方形没有设置绘制程序。");}}}public static void main(String[] args) {// 创建具体的绘制程序实现IDrawProgram redProgram = new RedDrawProgram();IDrawProgram blueProgram = new BlueDrawProgram();// 创建具体的形状(细化抽象)Circle circle = new Circle();Rectangle rectangle = new Rectangle();// 为形状设置不同的绘制程序,展示桥接模式的灵活性System.out.println("--- 绘制圆形 ---");circle.setProgram(redProgram); // 将圆形与红色绘制程序桥接circle.draw(); // 输出: 用红色绘制 圆形。circle.setProgram(blueProgram); // 将圆形与蓝色绘制程序桥接circle.draw(); // 输出: 用蓝色绘制 圆形。System.out.println("\n--- 绘制方形 ---");rectangle.setProgram(blueProgram); // 将方形与蓝色绘制程序桥接rectangle.draw(); // 输出: 用蓝色绘制 方形。rectangle.setProgram(redProgram); // 将方形与红色绘制程序桥接rectangle.draw(); // 输出: 用红色绘制 方形。// 演示未设置绘制程序的情况Circle defaultCircle = new Circle();defaultCircle.draw(); // 输出: 圆形没有设置绘制程序。}
}

设计原则:• 遵循单一职责• 迪米特法则(最少知识原则)• 开闭原则

使用场景:1.在进行系统设计时,发现类的继承有N层时,可以考虑使用桥梁模式。

组合模式

组合模式(Composite Pattern)允许你将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得客户端对单个对象和组合对象的使用具有一致性。

import java.util.ArrayList;
import java.util.List;// 1. Component(组件)接口:定义文件和文件夹的共同行为
interface FileSystemComponent {String getName();void display(int indent); // 用于演示层次结构
}// 2. Leaf(叶子节点):文件
class File implements FileSystemComponent {private String name;public File(String name) {this.name = name;}@Overridepublic String getName() {return name;}@Overridepublic void display(int indent) {// 根据缩进打印文件名称for (int i = 0; i < indent; i++) {System.out.print("  "); // 两个空格代表一个缩进}System.out.println("📄 " + name); // 使用表情符号更直观}
}// 3. Composite(组合节点):文件夹
class Folder implements FileSystemComponent {private String name;private List<FileSystemComponent> components; // 存储子组件(文件或文件夹)public Folder(String name) {this.name = name;this.components = new ArrayList<>();}@Overridepublic String getName() {return name;}// 添加子组件public void addComponent(FileSystemComponent component) {components.add(component);}// 移除子组件public void removeComponent(FileSystemComponent component) {components.remove(component);}@Overridepublic void display(int indent) {// 根据缩进打印文件夹名称for (int i = 0; i < indent; i++) {System.out.print("  ");}System.out.println("📁 " + name + "/"); // 文件夹通常以斜杠结尾// 递归地显示所有子组件for (FileSystemComponent component : components) {component.display(indent + 1); // 子组件的缩进增加}}
}// 客户端代码
public class CompositePatternDemo {public static void main(String[] args) {// 创建文件File file1 = new File("Document.txt");File file2 = new File("Image.jpg");File file3 = new File("Spreadsheet.xlsx");File file4 = new File("Report.pdf");// 创建文件夹Folder rootFolder = new Folder("Root");Folder documentsFolder = new Folder("Documents");Folder photosFolder = new Folder("Photos");Folder reportsFolder = new Folder("Reports");// 构建文件系统结构rootFolder.addComponent(documentsFolder);rootFolder.addComponent(photosFolder);rootFolder.addComponent(file4); // 直接在根目录下添加文件documentsFolder.addComponent(file1);documentsFolder.addComponent(file3);documentsFolder.addComponent(reportsFolder); // 文件夹中嵌套文件夹photosFolder.addComponent(file2);reportsFolder.addComponent(new File("Q1_Report.docx")); // 匿名文件System.out.println("--- 文件系统结构 ---");rootFolder.display(0); // 从根目录开始显示,初始缩进为0System.out.println("\n--- 移除一个文件后 ---");documentsFolder.removeComponent(file3); // 移除一个文件rootFolder.display(0);}
}

设计原则:• 遵循单一职责• 迪米特法则(最少知识原则)• 开闭原则

使用场景:树形结构,如 文件夹/文件公司/部门。,可以考虑使用组合模式。

总结:

  1. 如果是为了灵活替换底层实现 → 用桥接模式。(如更换数据库驱动、渲染引擎)
  2. 如果是为了处理树形结构的统一操作 → 用组合模式。(如遍历目录、计算组织架构的总人数)

桥接模式和组合模式都用了组合(Composition),但就像「螺丝刀」和「菜刀」都用金属制造,却完全不是同一种工具——它们的用途和设计目标有本质区别。

http://www.lqws.cn/news/525151.html

相关文章:

  • Selenium 二次封装通用页面基类 BasePage —— Python 实践
  • 矩阵题解——螺旋矩阵【LeetCode】
  • 大模型推理-高通qnn基础
  • PYTHON从入门到实践5-列表操作
  • 超级好用的小软件:geek,卸载软件,2m大小
  • vue2简单的路由切换
  • OpenCV图像旋转:单点旋转与图片旋转
  • Windows10中设置多个虚拟IP方法
  • Linux size命令详解
  • Boss:攻击
  • Azure虚拟机添加磁盘
  • Docker、Docker composer与Docker desktop
  • H5录音、图文视频IndexDB储存最佳实践:用AI生成语音备忘录
  • Fisco Bcos学习 - 开发第一个区块链应用
  • 高防IP能不能防住500GDdos攻击
  • AI系列1-1: 离线部署通义大模型及持续修正-RedHat+NVIDA GPU
  • Java课后习题(编程题)
  • SpringBoot高校党务系统
  • 激光雷达全链路光学系统及探测器能量耦合分析
  • python的少数民族音乐网站系统
  • request这个包中,get 这个方法里传入的是params ,post这个方法里传入的是data 和 json。这个区别是什么?
  • HarmonyOS5 如何性能优化?
  • Vue Devtools “Open in Editor” 配置教程(适用于 VSCode 等主流编辑器)
  • PyTorch RNN实战:快速上手教程
  • 笔记03:布线-过孔的调用与添加
  • 求助deepsee 生成语法树代码
  • matlab机器人工具箱(Robotics Toolbox)安装及使用
  • 使用node的mysql模块操作MySQL数据库
  • 多传感器标定简介
  • Linux驱动学习day7