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

领悟8种常见的设计模式

很多 Java 初学者觉得设计模式 “抽象难学”,其实是没抓住核心逻辑 —— 设计模式不是 “炫技代码”,而是前辈们总结的 “解决高频复杂问题的通用思路”,好吧,你可以过一遍了解这些大概是个什么东西

不求我们能够完全理解,毕竟我们小时候家人跟我们说人生大道理我们也不太当回事

一、先明确:Java 设计模式到底是什么?

一句话总结核心:设计模式是 “针对 Java 开发中重复出现的复杂场景,前辈们总结的、可复用的代码解决思路”。

你可以从 3 个角度理解,瞬间消除 “抽象感”:

  1. 不是 “固定代码模板”,而是 “解决问题的思路”
    比如 “单例模式” 的核心思路是 “让一个类只创建一个对象”,具体代码可以有
    “双重检查锁”“静态内部类” 等多种写法,但 “只存一个实例” 的思路不变。

生活类比:“做米饭要先加水再加热” 是思路,具体用电饭锅还是高压锅,是实现方式 —— 思路统一,实现灵活。

  1. 只解决 “特定复杂问题”,不是 “万能工具”
    设计模式针对的是 “不用就会踩坑” 的场景:比如 “想避免重复创建对象浪费资源”“想动态切换支付方式又不想写一堆 if-else”“想加日志又不改动原有业务代码”。
    简单场景(比如一个工具类只提供 1 个静态方法)不需要设计模式,直接写简单代码更高效。

  2. 核心价值是 “让代码易维护、易扩展”
    没有设计模式的代码,后期迭代会变成 “一团乱麻”:比如新增支付方式要改原有代码、加日志要在每个方法里写重复逻辑。
    设计模式能让代码 “解耦”—— 新增功能不用改老代码、增强逻辑不侵入业务,后期维护不用 “牵一发而动全身”。

二、Java 开发中最常用的设计模式有哪些?

设计模式官方有 23 种,但 Java 开发者日常用得最多、面试问得最频繁的,集中在3 大类 8 种,按 “解决的核心问题” 分类,一目了然:
在这里插入图片描述

三、创建型模式

1. 单例模式(Singleton)—— 一个类只创建一个对象

  • 定义
    保证一个类在整个 Java 程序运行过程中,只有一个实例对象并且提供一个全局统一的访问入口
  • 生活例子
    公司的 “CEO”—— 全公司只有 1 位 CEO,所有部门对接 CEO 时,都只能找这同一个人,不可能同时存在两位 CEO;而且所有人都知道 “找 CEO 要通过秘书(全局入口)”,不能自己 “造一个 CEO”。
  • 业务场景
    日志工具类 :日志需要统一写入文件 / 数据库,多实例会导致日志内容错乱;
    线程池: 线程池需要控制线程数量,多实例会导致线程过多,耗尽服务器资源;
    数据库连接池:数据库连接数有限,多实例会导致连接超标,数据库拒绝访问。

2. 简单工厂模式(Simple Factory)—— 统一创建同一类对象

  • 定义
    定义一个 “工厂类”,由工厂统一创建同一类别下的所有对象(比如各种支付方式、各种日志类型),外部不用关心对象的创建细节,只需要告诉工厂
    “要什么”,就能拿到对应的对象。
  • 生活例子
    奶茶店的 “收银台”—— 顾客不用自己动手做奶茶(不用关心奶茶怎么煮、怎么加配料),只需要告诉收银台(工厂)“要珍珠奶茶” 或
    “要水果茶”,收银台就会给顾客对应的奶茶(产品)。
  • 业务场景
    支付系统:需要创建微信支付、支付宝支付、银联支付对象,用工厂根据用户选择的支付方式统一创建;
    日志系统:需要创建文件日志、控制台日志、数据库日志对象,用工厂根据配置统一创建;
    文档导出:需要创建 Excel 导出、PDF 导出、Word 导出对象,用工厂根据用户选择的格式统一创建。

3. 建造者模式(Builder)—— 分步创建复杂对象

  • 定义
    针对 “有多个属性(尤其是可选属性)的复杂对象”,将对象的创建过程拆分成多个步骤,逐步设置属性,最后统一构建出完整对象,避免创建出
    “属性不完整” 的对象。
  • 生活例子
    组装电脑 —— 电脑有 “CPU、内存、硬盘” 等必选属性(没有这些电脑无法运行),还有 “显卡、键盘、鼠标” 等可选属性(没有也能运行,但体验差)。组装时,必须先装必选部件,再按需装可选部件,最后拼成完整电脑。
  • 业务场景
    订单创建:订单有 “订单号、商品 ID、金额” 等必选属性,有 “收货地址、优惠券、备注” 等可选属性;
    用户注册:用户有 “手机号、密码” 等必选属性,有 “昵称、头像、生日” 等可选属性;
    文档生成:文档有 “标题、内容” 等必选属性,有 “作者、日期、封面” 等可选属性。

四、结构型模式

1. 代理模式(Proxy)—— 给对象加 “增强层”

  • 定义
    给 “目标对象”(核心业务对象)创建一个 “代理对象”,外部通过代理对象访问目标对象,在访问前后可以添加额外逻辑(比如日志、权限、事务),不修改目标对象的代码。
  • 生活例子
    明星的 “经纪人”—— 粉丝想找明星商演(访问目标对象),不能直接联系明星,必须通过经纪人(代理对象):经纪人会先 “筛选商演需求”(权限校验)、“记录行程”(日志),再安排明星去商演(调用目标对象方法),商演后还会 “结算费用”(后续增强)。
  • 业务场景
    Spring AOP:给 Service 方法加事务(代理在方法前开启事务,方法后提交 / 回滚);
    日志记录:给 Controller 方法加访问日志(代理在方法前记录请求参数,方法后记录返回结果);
    权限校验:给敏感接口加权限(代理在方法前判断用户是否有权限,无权限则拒绝)。

2. 策略模式(Strategy)—— 动态切换逻辑,消除 if-else

  • 定义
    将 “不同的算法 / 逻辑” 封装成独立的 “策略类”策略类之间可以互相替换,外部根据场景动态选择对应的策略,不用在代码中写大量 if-else。
  • 生活例子
    出行方式选择 —— 去公司可以选 “地铁”“公交”“打车” 三种策略:赶时间选 “打车”,想省钱选 “公交”,平衡时间和成本选 “地铁”。每种策略的 “路线、费用、时间” 独立且可以随时切换
  • 业务场景
    订单折扣:普通用户无折扣、会员 9 折、VIP8 折,根据用户等级动态选策略;**
    支付方式 :微信、支付宝、银联支付,根据用户选择动态选策略;
    排序算法:数据量小用 “冒泡排序”,数据量大用 “快速排序”,根据数据量动态选策略。

3. 装饰器模式(Decorator)—— 动态给对象加功能

  • 定义
    在不修改原有对象代码的前提下,通过 “包装” 的方式给对象动态添加新功能,并且可以灵活组合多个功能(比继承更灵活)。
  • 生活例子
    咖啡店的 “咖啡加配料”—— 一杯美式咖啡(基础对象)可以加奶泡(装饰器 1)、加糖(装饰器 2)、加冰(装饰器 3),每种配料都是一个独立的 “装饰”,可以自由组合(比如 “美式 + 奶泡 + 糖”“美式 + 冰”),且不改变咖啡本身的制作逻辑。
  • 业务场景
    日志增强:基础日志功能可以动态添加 “时间戳装饰”“用户 ID 装饰”“模块名称装饰”;
    数据加密:基础数据传输可以动态添加 “Base64 加密装饰”“MD5 加密装饰”
    IO 流扩展:Java 中的BufferedInputStream就是FileInputStream的装饰器,添加了缓冲功能。

五、行为型模式

1. 适配器模式(Adapter)—— 让不兼容的类一起工作

  • 定义
    将一个类的接口转换成客户端期望的另一个接口,使原本因接口不兼容而无法一起工作的类能够协同工作。
  • 生活例子
    手机充电器 “转接头”—— 安卓手机充电器(原有接口)不能直接给苹果手机(目标接口)充电,用一个转接头(适配器)就能让安卓充电器给苹果手机充电,转接头内部完成 “安卓接口” 到 “苹果接口” 的转换。
  • 业务场景
    老系统升级:老系统返回 XML 格式数据,新系统需要 JSON 格式,用适配器转换;
    第三方接口集成:第三方接口返回的字段名(如user_name)和本地系统(如username)不一致,用适配器映射;
    旧 API 兼容:项目中原来的Payment接口有pay(double amount)方法,新引入的支付 SDK 方法是doPayment(BigDecimal money),用适配器适配。

2. 观察者模式(Observer)—— 实现对象间的动态通知

  • 定义
    当一个对象(被观察者)的状态发生变化时,所有依赖它的对象(观察者)会自动收到通知并更新,实现 “一对多” 的动态通信。
  • 生活例子
    微信公众号 —— 你关注的公众号(被观察者)发布新文章时,所有关注该公众号的用户(观察者)都会收到推送通知,用户可以选择阅读或忽略,但公众号不需要知道具体有哪些用户关注它。
  • 业务场景
    电商库存预警:商品库存低于阈值时,自动通知 “库存管理系统”“订单取消系统”“用户提醒系统”;
    消息队列:生产者发送消息到队列(被观察者),所有订阅该队列的消费者(观察者)自动接收消息;
    GUI 事件处理:按钮(被观察者)被点击时,所有注册了点击事件的监听器(观察者)自动执行回调。

总结:8 种常用设计模式的核心价值​

这 8 种设计模式覆盖了 Java 开发中 “创建对象、组织结构、协调行为” 的核心场景,记住它们的核心解决点:

在这里插入图片描述

实际开发中,不必刻意追求 “用了多少模式”,而是当遇到对应痛点时,能想到 “用哪种模式可以更优雅地解决”—— 这才是学设计模式的最终目的。

http://www.xdnf.cn/news/1381105.html

相关文章:

  • 导入文件允许合并表格
  • HBase Compaction HFile 可见性和并发安全性分析
  • audioMAE模型代码分析
  • 流程控制语句(3)
  • 帕萨特盘式制动器cad+设计说明书
  • 【C语言16天强化训练】从基础入门到进阶:Day 13
  • week5-[一维数组]归并
  • 公共字段自动填充
  • 云计算学习100天-第29天
  • 基于SamOut的音频Token序列生成模型训练指南
  • Linux shell getopts 解析命令行参数
  • 算力沸腾时代,如何保持“冷静”?国鑫液冷SY4108G-G4解锁AI服务器的“绿色空调”!
  • 使用Rag 命中用户feedback提升triage agent 准确率
  • Elasticsearch数据迁移方案深度对比:三种方法的优劣分析
  • linu 网络 :TCP粘包及UDP
  • 【C++】C++11的右值引用和移动语义
  • STAGEWISE实战指南:从集成到使用的完整解决方案
  • vscode pyqt5设置
  • 【ai编辑器】使用cursor-vip获得cursor的pro版 pro plan(mac)
  • uniapp vue3 canvas实现手写签名
  • Flask测试平台开发,登陆重构
  • (二分查找)Leetcode34. 在排序数组中查找元素的第一个和最后一个位置+74. 搜索二维矩阵
  • 并发编程——05 并发锁机制之深入理解synchronized
  • 学习数据结构(13)二叉树链式结构下
  • 线程池及线程池单例模式
  • 带动态条件的模糊查询SQL
  • DINOv2 vs DINOv3 vs CLIP:自监督视觉模型的演进与可视化对比
  • LeetCode 3446. 按对角线进行矩阵排序
  • UE5提升分辨率和帧率的方法
  • 搭建私有云3步法:cpolar简化Puter本地云端配置