【设计模式】3W 学习法全面解析 7 大结构型模式:Java 实战 + 开源框架应用

3W 学习法总结结构型模式(附 Java 代码实战及开源框架应用)

结构型模式 主要关注 类与对象的组合,确保不同组件之间能够高效协作,提高系统的灵活性和可维护性。本文采用 3W 学习法(What、Why、How),深入分析 七大结构型模式(适配器、桥接、装饰器、组合、外观、享元、代理),并结合 Java 代码实战开源框架中的应用,帮助你高效掌握这些模式的实战技巧。


1. 适配器模式(Adapter)

✅ What:适配器模式是什么?

适配器模式 通过 转换接口 使原本不兼容的类能够一起工作。

🤔 Why:为什么要使用适配器模式?

  • 解决接口不兼容问题,让新旧代码无缝衔接。
  • 复用已有代码,避免修改原始代码。

🚀 How:如何实现适配器模式?(Java 代码实战)

// 目标接口
interface Target {void request();
}// 需要适配的类
class Adaptee {void specificRequest() {System.out.println("Adaptee 特定请求");}
}// 适配器
class Adapter implements Target {private Adaptee adaptee = new Adaptee();public void request() {adaptee.specificRequest();}
}// 客户端调用
public class AdapterDemo {public static void main(String[] args) {Target target = new Adapter();target.request(); // 输出: Adaptee 特定请求}
}

📌 在开源框架中的应用:

  • Spring HandlerAdapter:适配不同类型的 Controller(如 RequestMappingHandlerAdapter)。
  • java.io.InputStreamReader:将 InputStream 适配为 Reader

2. 桥接模式(Bridge)

✅ What:桥接模式是什么?

桥接模式 通过 分离抽象部分和实现部分,让它们可以独立变化。

🤔 Why:为什么要使用桥接模式?

  • 降低耦合:抽象和实现独立演化,不受对方影响。
  • 增强扩展性:适用于 多个维度变化 的场景。

🚀 How:如何实现桥接模式?(Java 代码实战)

// 实现接口
interface Implementor {void operationImpl();
}// 具体实现A
class ConcreteImplementorA implements Implementor {public void operationImpl() {System.out.println("具体实现A的操作");}
}// 抽象类
abstract class Abstraction {protected Implementor implementor;public Abstraction(Implementor implementor) {this.implementor = implementor;}abstract void operation();
}// 具体抽象类
class RefinedAbstraction extends Abstraction {public RefinedAbstraction(Implementor implementor) {super(implementor);}public void operation() {implementor.operationImpl();}
}// 客户端调用
public class BridgeDemo {public static void main(String[] args) {Implementor impl = new ConcreteImplementorA();Abstraction abstraction = new RefinedAbstraction(impl);abstraction.operation(); // 输出: 具体实现A的操作}
}

📌 在开源框架中的应用:

  • JDBC 驱动java.sql.DriverManager 通过桥接不同数据库的驱动。
  • Slf4j + Logback/Log4j:日志框架使用桥接模式适配不同日志实现。

3. 装饰器模式(Decorator)

✅ What:装饰器模式是什么?

装饰器模式 通过 动态添加新功能,而不修改原有对象。

🤔 Why:为什么要使用装饰器模式?

  • 符合开闭原则:可扩展对象功能,避免修改原始代码。
  • 支持功能叠加:适用于 多个额外行为 组合的场景。

🚀 How:如何实现装饰器模式?(Java 代码实战)

// 抽象组件
interface Component {void operation();
}// 具体组件
class ConcreteComponent implements Component {public void operation() {System.out.println("基本功能");}
}// 装饰器
abstract class Decorator implements Component {protected Component component;public Decorator(Component component) {this.component = component;}public void operation() {component.operation();}
}// 具体装饰器A
class ConcreteDecoratorA extends Decorator {public ConcreteDecoratorA(Component component) {super(component);}public void operation() {super.operation();System.out.println("附加功能A");}
}// 客户端调用
public class DecoratorDemo {public static void main(String[] args) {Component component = new ConcreteDecoratorA(new ConcreteComponent());component.operation();// 输出:// 基本功能// 附加功能A}
}

📌 在开源框架中的应用:

  • Spring BeanPostProcessor:可动态增强 Bean 的功能。
  • BufferedInputStream:装饰 InputStream,提供缓冲能力。

4. 组合模式(Composite)

✅ What:组合模式是什么?

组合模式 允许 树形结构的对象 统一处理。

🤔 Why:为什么要使用组合模式?

  • 统一对象处理方式:无论是单个对象还是组合对象,均可一致调用。
  • 适用于层级结构:如 文件系统、组织架构 等。

🚀 How:如何实现组合模式?(Java 代码实战)

// 抽象组件
interface Component {void operation();
}// 叶子节点
class Leaf implements Component {public void operation() {System.out.println("执行叶子节点操作");}
}// 组合节点
class Composite implements Component {private List<Component> children = new ArrayList<>();public void add(Component component) {children.add(component);}public void operation() {for (Component child : children) {child.operation();}}
}// 客户端调用
public class CompositeDemo {public static void main(String[] args) {Composite root = new Composite();root.add(new Leaf());root.add(new Leaf());Composite branch = new Composite();branch.add(new Leaf());root.add(branch);root.operation();}
}

📌 在开源框架中的应用:

  • Spring Security:权限规则采用组合模式组织权限节点。
  • GUI 组件:Swing 的 JComponent 使用组合模式。

确实,结构型模式共有 7 种,前面只介绍了 4 种,缺少了 外观模式(Facade)、享元模式(Flyweight)、代理模式(Proxy)。下面继续补充它们的 3W 学习法解析、Java 实战代码及在开源框架中的应用


5. 外观模式(Facade)

✅ What:外观模式是什么?

外观模式(Facade) 通过 提供一个统一的接口,简化子系统的复杂操作,降低系统耦合性。

🤔 Why:为什么要使用外观模式?

  • 降低复杂性,隐藏子系统细节,使调用者只需与一个简单接口交互。
  • 解耦代码,避免高层代码直接依赖多个复杂子系统。

🚀 How:如何实现外观模式?(Java 代码实战)

// 子系统A
class SubsystemA {void operationA() {System.out.println("子系统 A 操作");}
}// 子系统B
class SubsystemB {void operationB() {System.out.println("子系统 B 操作");}
}// 外观类(Facade)
class Facade {private SubsystemA subsystemA = new SubsystemA();private SubsystemB subsystemB = new SubsystemB();void operation() {subsystemA.operationA();subsystemB.operationB();}
}// 客户端调用
public class FacadeDemo {public static void main(String[] args) {Facade facade = new Facade();facade.operation();// 输出:// 子系统 A 操作// 子系统 B 操作}
}

📌 在开源框架中的应用:

  • Spring JdbcTemplate:封装了数据库操作,简化 JDBC 使用。
  • HttpClient:简化底层 HTTP 请求的复杂性。

6. 享元模式(Flyweight)

✅ What:享元模式是什么?

享元模式(Flyweight) 通过 共享对象 来减少内存占用,提高性能。

🤔 Why:为什么要使用享元模式?

  • 减少内存开销,适用于 大量相似对象 场景。
  • 提升系统性能,避免重复创建对象。

🚀 How:如何实现享元模式?(Java 代码实战)

import java.util.HashMap;
import java.util.Map;// 享元接口
interface Flyweight {void operation(String extrinsicState);
}// 具体享元
class ConcreteFlyweight implements Flyweight {private final String intrinsicState;ConcreteFlyweight(String intrinsicState) {this.intrinsicState = intrinsicState;}public void operation(String extrinsicState) {System.out.println("享元对象:" + intrinsicState + ",外部状态:" + extrinsicState);}
}// 享元工厂
class FlyweightFactory {private static final Map<String, Flyweight> pool = new HashMap<>();static Flyweight getFlyweight(String key) {if (!pool.containsKey(key)) {pool.put(key, new ConcreteFlyweight(key));}return pool.get(key);}
}// 客户端调用
public class FlyweightDemo {public static void main(String[] args) {Flyweight fw1 = FlyweightFactory.getFlyweight("A");Flyweight fw2 = FlyweightFactory.getFlyweight("A");Flyweight fw3 = FlyweightFactory.getFlyweight("B");fw1.operation("X");fw2.operation("Y");fw3.operation("Z");System.out.println(fw1 == fw2); // 输出: true(共享同一个对象)}
}

📌 在开源框架中的应用:

  • Integer.valueOf(int):JDK 享元模式,缓存 -128 ~ 127 的 Integer 对象。
  • 线程池(Thread Pool):复用线程对象,减少资源消耗。

7. 代理模式(Proxy)

✅ What:代理模式是什么?

代理模式(Proxy) 通过 控制访问目标对象,增加额外行为(如权限控制、懒加载、缓存等)。

🤔 Why:为什么要使用代理模式?

  • 增强功能(如日志、事务、权限)。
  • 控制对象访问(如远程代理、虚拟代理)。

🚀 How:如何实现代理模式?(Java 代码实战)

静态代理
// 接口
interface Service {void operation();
}// 真实对象
class RealService implements Service {public void operation() {System.out.println("真实业务逻辑");}
}// 代理类
class ProxyService implements Service {private RealService realService = new RealService();public void operation() {System.out.println("前置增强逻辑");realService.operation();System.out.println("后置增强逻辑");}
}// 客户端调用
public class StaticProxyDemo {public static void main(String[] args) {Service service = new ProxyService();service.operation();// 输出:// 前置增强逻辑// 真实业务逻辑// 后置增强逻辑}
}
动态代理(JDK 动态代理)
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;// 动态代理处理器
class DynamicProxyHandler implements InvocationHandler {private Object target;DynamicProxyHandler(Object target) {this.target = target;}public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("前置增强逻辑");Object result = method.invoke(target, args);System.out.println("后置增强逻辑");return result;}
}// 客户端调用
public class DynamicProxyDemo {public static void main(String[] args) {Service realService = new RealService();Service proxy = (Service) Proxy.newProxyInstance(realService.getClass().getClassLoader(),realService.getClass().getInterfaces(),new DynamicProxyHandler(realService));proxy.operation();// 输出:// 前置增强逻辑// 真实业务逻辑// 后置增强逻辑}
}

📌 在开源框架中的应用:

  • Spring AOP:代理模式增强 Bean 功能,如事务、日志、权限控制。
  • MyBatis Mapper:动态代理生成 SQL 查询接口的实现类。

总结

设计模式主要作用适用场景
适配器模式让不兼容的接口协同工作HandlerAdapterInputStreamReader
桥接模式分离抽象和实现,解耦JDBC 驱动、日志框架
装饰器模式动态增强对象功能BufferedInputStreamBeanPostProcessor
组合模式统一树形结构处理Spring Security 权限管理、GUI 组件
外观模式简化系统调用JdbcTemplateHttpClient
享元模式共享对象减少内存消耗Integer.valueOf(int)、线程池
代理模式控制访问目标对象,增强功能AOP、MyBatis 动态代理

掌握这 7 大结构型模式,让你的代码 更清晰、可扩展、性能更优!🚀

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

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

相关文章

在大数据开发中ETL是指什么?

hello宝子们...我们是艾斯视觉擅长ui设计和前端数字孪生、大数据、三维建模、三维动画10年经验!希望我的分享能帮助到您!如需帮助可以评论关注私信我们一起探讨!致敬感谢感恩! 在数字经济时代&#xff0c;数据已成为企业最核心的资产。然而&#xff0c;分散在业务系统、日志文件…

前端面试项目拷打

Axios相关 1.在Axios二次封装时&#xff0c;具体封装了哪些内容&#xff0c;如何处理请求拦截和响应拦截&#xff1f; axios二次封装的目的&#xff1a;为了统一处理请求和响应拦截器、错误处理、请求超时、请求头配置等&#xff0c;提高代码可维护性和复用性。 首先创建axios…

「JavaScript深入」Server-Sent Events (SSE):轻量级实时通信技术

Server-Sent Events&#xff08;SSE&#xff09; SSE 的特点1. 单向通信2. 简单易用&#xff0c;浏览器原生支持3. 持久连接4. 纯文本传输5. 自动重连机制6. 轻量级协议 SSE 的实现服务器端实现&#xff08;Node.js 示例&#xff09;1. HTTP 响应头设置2. 数据推送模式3. 服务器…

蓝桥杯2023年第十四届省赛真题-阶乘的和

蓝桥杯2023年第十四届省赛真题-阶乘的和 时间限制: 2s 内存限制: 320MB 提交: 3519 解决: 697 题目描述 给定 n 个数 Ai&#xff0c;问能满足 m! 为∑ni1(Ai!) 的因数的最大的 m 是多少。其中 m! 表示 m 的阶乘&#xff0c;即 1 2 3 m。 输入格式 输入的第一行包含一个整…

影刀RPA拓展-Python变量类型转换

1. Python变量类型转换概述 1.1 类型转换的必要性 Python作为一种动态类型语言&#xff0c;在编程过程中经常需要进行变量类型转换。这主要是因为不同数据类型在存储结构、运算规则和使用场景上存在差异&#xff0c;而在实际开发中&#xff0c;我们常常需要对不同类型的数据进…

Python pyqt+flask做一个简单实用的自动排班系统

这是一个基于Flask和PyQt的排班系统&#xff0c;可以将Web界面嵌入到桌面应用程序中。 系统界面&#xff1a; 功能特点&#xff1a; - 读取员工信息和现有排班表 - 自动生成排班表 - 美观的Web界面 - 独立的桌面应用程序 整体架构&#xff1a; 系统采用前后端分离的架构…

Pycharm接入DeepSeek,提升自动化脚本的写作效率

一.效果展示&#xff1a; 二.实施步骤&#xff1a; 1.DeepSeek官网创建API key&#xff1a; 创建成功后&#xff0c;会生成一个API key&#xff1a; 2. PyCharm工具&#xff0c;打开文件->设置->插件&#xff0c;搜索“Continue”&#xff0c;点击安装 3.安装完成后&…

Java:Arrays类:操作数组的工具类

文章目录 Arrays类常见方法SetAll(); 代码排序如果数组中存储的是自定义对象 Arrays类 常见方法 SetAll(); 注意&#xff1a; 不能用新的数组接是因为修改的是原数组&#xff0c;所以完了要输出原数组发现会产生变化参数是数组下标变成灰色是因为还能简化&#xff08;Lambda…

2025-gazebo配置on vmware,wsl

ros2安装 # 安装ros2, 推荐鱼香ros一键式安装 wget http://fishros.com/install -O fishros && . fishros安装版本&#xff1a;ubuntu24.04 ros2 jazzy gazebo Getting Started with Gazebo? — Gazebo ionic documentation ros与gz的版本对应关系&#xff1a; ​…

格力地产更名“珠免集团“ 全面转型免税赛道

大湾区经济网品牌观察讯&#xff0c;3月18日&#xff0c;格力地产股份有限公司公告宣布&#xff0c;拟将公司名称变更为"珠海珠免集团股份有限公司"&#xff0c;证券简称同步变更为"珠免集团"。此次更名并非简单的品牌焕新&#xff0c;而是标志着这家曾以房…

网络编程--服务器双客户端聊天

写一个服务器和客户端 运行服务器和2个客户端&#xff0c;实现聊天功能 客户端1和客户端2进行聊天&#xff0c;客户端1将聊天数据发送给服务器&#xff0c;服务器将聊天数据转发给客户端2 要求&#xff1a; 服务器使用 select 模型实现 &#xff0c;客户端1使用 poll 模型实现…

k8s主要控制器简述(一)ReplicaSet与Deployment

目录 一、ReplicaSet 关键特性 示例 解释 支持的 Operator 二、Deployment 1. 声明式更新 示例 2. 滚动更新 示例 3. 回滚 示例 4. ReplicaSet 管理 示例 5. 自动恢复 示例 6. 扩展和缩容 示例 示例 一、ReplicaSet ReplicaSet 是 Kubernetes 中的一个核心控…

python中redis操作整理

下载redis命令 pip install redis 连接redis import redis # host是redis主机&#xff0c;需要redis服务端和客户端都起着 redis默认端口是6379 pool redis.ConnectionPool(hostlocalhost, port6379,decode_responsesTrue) r redis.Redis(connection_poolpool)操作字符串 …

自然语言处理入门4——RNN

一般来说&#xff0c;提到自然语言处理&#xff0c;我们都会涉及到循环神经网络&#xff08;RNN&#xff09;&#xff0c;这是因为自然语言可以被看作是一个时间序列&#xff0c;这个时间序列中的元素是一个个的token。传统的前馈神经网络结构简单&#xff0c;但是不能很好的处…

数据结构之链表(双链表)

目录 一、双向带头循环链表 概念 二、哨兵位的头节点 优点&#xff1a; 头节点的初始化 三、带头双向链表的实现 1.双链表的销毁 2.双链表的打印 3.双链表的尾插和头插 尾插&#xff1a; 头插&#xff1a; 4.双链表的尾删和头删 尾删&#xff1a; 头删&#xff1a; …

ASP3605同步降压调节器——满足汽车电子严苛要求的电源芯片方案

ASP3605高效同步降压调节器&#xff0c;通过AEC-Q100 Grade1认证&#xff0c;输入电压4V至15V&#xff0c;输出电流5A&#xff0c;峰值效率94%。车规级型号ASP3605A3U支持-40C至125C工作温度&#xff0c;适用于ADAS、车载信息娱乐系统等场景。 面向汽车电子的核心功能设计 1. …

vue3+Ts+elementPlus二次封装Table分页表格,表格内展示图片、switch开关、支持

目录 一.项目文件结构 二.实现代码 1.子组件&#xff08;表格组件&#xff09; 2.父组件&#xff08;使用表格&#xff09; 一.项目文件结构 1.表格组件&#xff08;子组件&#xff09;位置 2.使用表格组件的页面文件&#xff08;父组件&#xff09;位置 3.演示图片位置 ele…

[特殊字符]1.2.1 新型基础设施建设

&#x1f680; 新型基础设施建设全解析 &#x1f31f; 核心概念与定义 维度详细内容定义以新发展理念为引领&#xff0c;以技术创新为驱动&#xff0c;以信息网络为基础&#xff0c;提供数字转型、智能升级、融合创新服务的基础设施体系。提出背景2018年中央经济工作会议首次提…

SQL Server数据库慢SQL调优

SQL Server中慢SQL会显著降低系统性能并引发级联效应。首先&#xff0c;用户直接体验响应时间延长&#xff0c;核心业务操作&#xff08;如交易处理、报表生成&#xff09;效率下降&#xff0c;导致客户满意度降低甚至业务中断。其次&#xff0c;资源利用率失衡&#xff0c;CPU…

【安全运营】安全运营关于告警降噪的一些梳理

目录 前言一、智能技术层面1、机器学习和 AI 模型训练2、攻击成功判定 二、多源关联分析1、多源设备关联&#xff08;跨设备日志整合&#xff09;2、上下文信息增强 三、业务白名单和策略优化1、动态白名单机制2、阈值和规则调整 四、自动化和流程化1、告警归并与去重2、同类型…