Java设计模式基础问答

面试过程中会让你介绍你项目或实习中使用的设计模式,你该如何说明


工厂模式

工厂模式是把对象创建的逻辑封装到一个工厂类里面,我们用工厂类来创建对象

为什么需要工厂类(优点):

  1. 可以集中管理对象的创建规则。例如要求这个对象必须经过xx校验,写到工厂类里好过每一次使用这个类的时候再检验一轮
  2. 提高代码可维护性和拓展性。工厂类可以通过接口或抽象类定义创建方法,允许在不修改现有代码的情况下添加新的产品类型
  3. 简化复杂对象创建逻辑,优化代码冗余。对象的创建过程可能涉及复杂的初始化步骤(如参数校验、依赖注入、资源配置等),这些逻辑分散在业务代码中会导致代码冗余和可读性下降
  4. 对象逻辑变动时,无需修改具体业务,只需修改工厂类。将对象创建逻辑封装在工厂类中,业务代码只需通过工厂获取对象,无需关心具体实现。即使后续对象的创建方式变化,只需修改工厂类,而不影响业务逻辑

缺点:

  1. 过度设计问题。在需求简单且变化不大的场景下使用工厂模式,可能导致 "设计过度",增加维护成本
  2. 子类膨胀问题。工厂方法模式中,每新增一种产品就需要新增一个具体工厂类,导致子类数量过多,增加系统负担

什么业务场景使用工厂模式:

  1. 对象要进行大量的校验逻辑或创建逻辑非常复杂。例如Sqlsession需要url,账号,密码,数据库类型等
  2. 一个类有多个子类,且该类适用于多个不同的场景。例如这是一个创建游戏角色的工厂类,有射手,战士,刺客等

Spring:

Datasource,使用工厂模式创建不同类型的数据源,客户端只需依赖 DataSource 接口,无需关心具体实现

可通过配置动态切换数据源(如从 HikariCP 切换到 Druid)


策略模式

策略模式是策略接口来定义统一行为的,具体的策略细节由子类来实现

可以将策略理解成方法,也就是方法类

例如你可以定义一个队列Queue,Queue的基本方法是add()和remove(),这个就是队列的基本行为。其他的优先队列等他会有Queue的基本行为,然后再进行拓展。

为什么需要策略模式(优点):

  1. 当前业务有统一的基础方法
  2. 策略模式切换灵活,可在基类基础上应对不同的场景
  3. 避免大量的if-else,代码可读性更强

缺点:

  1. 策略过多时会增加维护成本
  2. 简单策略导致的资源浪费,策略细节必须由子类来实现,所以即使是很简单的实现类也要弄多一个子类

什么业务场景使用策略模式:

业务有共同的行为,例如飞书通知和钉钉通知这种IM通知,一般来说都会定义一个接口有notify()基本方法来进行通知,这是他们的基本方法,其他方法自己在子类进行自定义增强

Spring:

TransationalManager事务管理器有

getTransational(),commit(),rollback()三种方法

它的子实现类有JPA事务和JDBC事务


责任链模式

责任链模式是让我们的一个请求,沿着一个链条从前往后进行处理

将多个处理者连成一条链,并沿着这条链传递请求,直到有对象处理它为止

优点:

  1. 解耦,降低耦合度,只需将实现类提交到责任链中
  2. 责任链动态调整机制,无需修改原有的代码,只需要修改责任链就可以达到业务修改
  3. 适用于串行,层次化处理逻辑

缺点:

  1. 配置失败可能会导致请求漏处理风险
  2. 处理链过长导致的性能下降问题
  3. 引入过多的类和对象增加系统复杂度
  4. 循环引用问题

什么业务场景使用责任链模式:

  1. 大量的if-else复杂逻辑处理,串行处理
  2. 处理逻辑可以复用,并且可以组合链节点应对不同业务的场景

Spring:

Spring的过滤器filter和拦截器interceptor用到了责任链模式

先进入DispatcherServlet拦截器-preHandler请求先处理-postHandler处理视图渲染前逻辑-afterCompletion请求后处理


单例模式

保证一类对象只有一个实例,防止创建多个实例,导致资源占用,使用对象不一致等问题

为什么需要单例模式:

  1. 全局状态管理,系统中需要维护一个全局状态(如配置信息、计数器),确保不同模块访问的是同一状态。例如日志管理器,配置管理器,Spring默认是单例-RedisTemplate-KafkaTemplate
  2. 需要为多个模块提供统一的资源访问入口。数据库连接池,线程池
  3. 适用于可复用场景,避免重复创造类。创建实例需要消耗大量资源,单例可减少开销
  4. 保证多线程下的线程安全和状态同步。如全局计数器和序列化生成器保证并发安全

缺点:

  1. 违反单一职责和开闭职责,单例类既负责创建又承担业务逻辑,单例类通常难以扩展,若需修改行为,可能需要直接修改单例类代码
  2. 若单例创建未正确处理线程安全,可能导致多实例问题。如双重检查锁定未使用 volatile
  3. 内存泄漏问题。单例持有的资源若未正确释放,会导致内存泄漏

什么业务场景使用单例模式:

  1. 需要有一个全局统一的实例,而不是多实例。如日志管理器,数据库连接池,线程池
  2. 需要保证多线程下的线程安全问题。如全局计数器

Spring:

Spring的Bean默认是单例模式,如RedisTemplate和KafkaTemplate等

相关推荐
叶 落10 分钟前
ubuntu 安装 JDK8
java·ubuntu·jdk·安装·java8
爱学习的白杨树13 分钟前
Sentinel介绍
java·开发语言
Frankabcdefgh19 分钟前
Python基础数据类型与运算符全面解析
开发语言·数据结构·python·面试
XW21 分钟前
java mcp client调用 (modelcontextprotocol)
java·llm
kaiaaaa23 分钟前
算法训练第十五天
开发语言·python·算法
哆啦A梦的口袋呀35 分钟前
基于Python学习《Head First设计模式》第十章 状态模式
学习·设计模式
南玖i1 小时前
vue3 + ant 实现 tree默认展开,筛选对应数据打开,简单~直接cv
开发语言·前端·javascript
南枝异客1 小时前
三数之和-力扣
开发语言·javascript·数据结构·算法·leetcode·排序算法
保持学习ing1 小时前
SpringBoot前后台交互 -- 登录功能实现(拦截器+异常捕获器)
java·spring boot·后端·ssm·交互·拦截器·异常捕获器
gadiaola1 小时前
【JVM面试篇】高频八股汇总——类加载和类加载器
java·jvm·面试