Java面试第十三山!《设计模式》

news2025/3/30 15:06:24

    大家好,我是陈一。如果文章对你有帮助,请留下一个宝贵的三连哦~ 万分感谢!

一、设计模式入门指南

1. 什么是设计模式?

设计模式是可复用的解决方案模板,用于解决软件开发中常见的架构问题。如同建筑领域的经典设计图纸,它们经历了数十年的实践验证。

2. 为什么要学习?

  • 面试必考:90%的中高级Java面试涉及设计模式

  • 代码质量:减少重复代码,提升扩展性

  • 团队协作:提供统一的术语体系

  • 架构思维:培养面向对象设计能力

二、七大核心模式深度解析

1. 单例模式(Singleton)

定义:确保类只有一个实例,并提供全局访问点
场景:数据库连接池、日志记录器、配置管理

/**
 * 双重校验锁单例实现
 * 1. volatile防止指令重排序
 * 2. 双重检查保证线程安全
 */
public class DatabasePool {
    private static volatile DatabasePool instance;
    
    // 私有构造器防止外部实例化
    private DatabasePool() {
        // 初始化数据库连接
    }
    
    public static DatabasePool getInstance() {
        if (instance == null) { // 第一次检查
            synchronized (DatabasePool.class) {
                if (instance == null) { // 第二次检查
                    instance = new DatabasePool();
                }
            }
        }
        return instance;
    }
}

适用场景对比表

实现方式线程安全延迟加载序列化安全
饿汉式
双重检查锁
静态内部类
Enum实现

2. 工厂模式(Factory)

定义:将对象创建逻辑封装,客户端不直接实例化对象
场景:支付渠道选择、日志记录器切换

// 抽象产品接口
interface PaymentGateway {
    void processPayment(BigDecimal amount);
}

// 具体产品实现
class Alipay implements PaymentGateway {
    @Override
    public void processPayment(BigDecimal amount) {
        System.out.println("支付宝支付:" + amount);
    }
}

class WechatPay implements PaymentGateway {
    @Override
    public void processPayment(BigDecimal amount) {
        System.out.println("微信支付:" + amount);
    }
}

// 工厂类
public class PaymentFactory {
    public static PaymentGateway createGateway(String type) {
        switch (type.toUpperCase()) {
            case "ALIPAY":
                return new Alipay();
            case "WECHAT":
                return new WechatPay();
            default:
                throw new IllegalArgumentException("不支持的支付类型");
        }
    }
}

3. 观察者模式(Observer)

定义:定义对象间的一对多依赖关系,当一个对象状态改变时自动通知依赖对象
场景:订单状态通知、股票价格变动提醒

// 主题接口
interface OrderSubject {
    void registerObserver(OrderObserver o);
    void notifyObservers();
}

// 具体主题(被观察者)
class Order implements OrderSubject {
    private List<OrderObserver> observers = new ArrayList<>();
    private String status;

    public void setStatus(String status) {
        this.status = status;
        notifyObservers();
    }

    @Override
    public void registerObserver(OrderObserver o) {
        observers.add(o);
    }

    @Override
    public void notifyObservers() {
        observers.forEach(o -> o.update(this.status));
    }
}

// 观察者接口
interface OrderObserver {
    void update(String status);
}

// 具体观察者
class SMSNotifier implements OrderObserver {
    @Override
    public void update(String status) {
        System.out.println("短信通知:订单状态变更为 " + status);
    }
}

4. 装饰器模式(Decorator)

定义:动态地为对象添加额外职责,比继承更灵活
场景:数据流处理、IO增强

// 基础组件接口
interface Coffee {
    String getDescription();
    BigDecimal getCost();
}

// 具体组件
class SimpleCoffee implements Coffee {
    @Override
    public String getDescription() {
        return "普通咖啡";
    }

    @Override
    public BigDecimal getCost() {
        return new BigDecimal("15.00");
    }
}

// 装饰器抽象类
abstract class CoffeeDecorator implements Coffee {
    protected Coffee decoratedCoffee;

    public CoffeeDecorator(Coffee coffee) {
        this.decoratedCoffee = coffee;
    }
}

// 具体装饰器
class MilkDecorator extends CoffeeDecorator {
    public MilkDecorator(Coffee coffee) {
        super(coffee);
    }

    @Override
    public String getDescription() {
        return decoratedCoffee.getDescription() + " + 牛奶";
    }

    @Override
    public BigDecimal getCost() {
        return decoratedCoffee.getCost().add(new BigDecimal("3.00"));
    }
}

5. 策略模式(Strategy)

定义:定义算法族,使它们可以互相替换
场景:促销活动计算、排序算法切换

// 策略接口
interface DiscountStrategy {
    BigDecimal applyDiscount(BigDecimal originalPrice);
}

// 具体策略实现
class FullReductionStrategy implements DiscountStrategy {
    @Override
    public BigDecimal applyDiscount(BigDecimal price) {
        return price.compareTo(new BigDecimal("100")) > 0 
               ? price.subtract(new BigDecimal("20")) 
               : price;
    }
}

class PercentageDiscountStrategy implements DiscountStrategy {
    @Override
    public BigDecimal applyDiscount(BigDecimal price) {
        return price.multiply(new BigDecimal("0.8"));
    }
}

// 上下文类
class ShoppingCart {
    private DiscountStrategy strategy;

    public void setStrategy(DiscountStrategy strategy) {
        this.strategy = strategy;
    }

    public BigDecimal checkout(BigDecimal total) {
        return strategy.applyDiscount(total);
    }
}

6. 代理模式(Proxy)

定义:为其他对象提供代理以控制对这个对象的访问
场景:延迟加载、访问控制、日志记录

interface Image {
    void display();
}

class RealImage implements Image {
    private String filename;

    public RealImage(String filename) {
        this.filename = filename;
        loadFromDisk();
    }

    private void loadFromDisk() {
        System.out.println("加载图片: " + filename);
    }

    @Override
    public void display() {
        System.out.println("显示图片: " + filename);
    }
}

class ImageProxy implements Image {
    private RealImage realImage;
    private String filename;

    public ImageProxy(String filename) {
        this.filename = filename;
    }

    @Override
    public void display() {
        if (realImage == null) {
            realImage = new RealImage(filename);
        }
        realImage.display();
    }
}

7. 责任链模式(Chain of Responsibility)

定义:将请求的发送者和接收者解耦,使多个对象都有机会处理请求
场景:审批流程、异常处理链

abstract class Approver {
    protected Approver nextApprover;

    public void setNext(Approver approver) {
        this.nextApprover = approver;
    }

    public abstract void processRequest(PurchaseRequest request);
}

class Manager extends Approver {
    @Override
    public void processRequest(PurchaseRequest request) {
        if (request.getAmount().compareTo(new BigDecimal("1000")) < 0) {
            System.out.println("经理审批通过:" + request);
        } else if (nextApprover != null) {
            nextApprover.processRequest(request);
        }
    }
}

class Director extends Approver {
    @Override
    public void processRequest(PurchaseRequest request) {
        if (request.getAmount().compareTo(new BigDecimal("5000")) < 0) {
            System.out.println("总监审批通过:" + request);
        } else if (nextApprover != null) {
            nextApprover.processRequest(request);
        }
    }
}

三、设计模式对比速查表

模式类型适用场景关键特征
单例模式创建型全局唯一实例私有构造、静态实例
工厂模式创建型复杂对象创建封装实例化逻辑
观察者模式行为型事件通知系统发布-订阅机制
装饰器模式结构型动态功能扩展包装器嵌套
策略模式行为型算法灵活切换接口多实现
代理模式结构型访问控制/功能增强间接访问
责任链模式行为型多级处理流程链式传递

四、高频面试问题集锦

1. Spring框架中的设计模式应用

  • 工厂模式:BeanFactory

  • 代理模式:AOP实现

  • 模板方法:JdbcTemplate

  • 适配器模式:HandlerAdapter

2. 单例模式双重检查锁原理

if (instance == null) {                  // 第一次检查
    synchronized (Singleton.class) {     // 同步锁
        if (instance == null) {          // 第二次检查
            instance = new Singleton();  // 安全初始化
        }
    }
}

关键点:volatile防止指令重排序 + 双重检查减少锁竞争

3. 装饰器模式 vs 继承

维度装饰器模式继承
扩展方式运行时动态组合编译时静态绑定
灵活性可多层嵌套不同功能单一父类限制
类数量按需组合,避免类爆炸容易产生大量子类

五、实战应用技巧

  1. 模式组合:观察者+责任链实现多级审批

  2. 避免滥用:简单场景不要过度设计

  3. 重构识别:当发现多重条件判断时考虑策略模式

  4. 性能考量:代理模式会增加调用层级

真实案例:某电商系统使用装饰器模式实现多级优惠叠加

BigDecimal total = new BigDecimal("200");
Coffee coffee = new SimpleCoffee();
coffee = new MilkDecorator(coffee);    // +3元
coffee = new SugarDecorator(coffee);   // +1元
System.out.println("总价:" + coffee.getCost()); // 输出19.00

六、学习资源推荐

  1. 书籍

    • 《Head First设计模式》(图文并茂)

    • 《设计模式:可复用面向对象软件的基础》(GoF经典)

  2. 在线资源

    • Refactoring.Guru(交互式教程)

    • Java Design Patterns(官网示例)

  3. 实战训练

    • 阅读Spring框架源码

    • 重构现有项目代码

掌握设计模式的关键在于理解思想而非死记硬背。建议从简单模式入手,结合项目实际需求逐步应用。记住:没有最好的模式,只有最合适的场景


翻过这座山,他们就会听到你的故事!转发本文给需要的朋友,一起备战金三银四! 🚀

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

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

相关文章

vue 点击放大,图片预览效果

背景&#xff1a; 在使用vue框架element组件的背景下&#xff0c;我们对图片的展示需要点击放大(单张)&#xff1b;如果是多张图片&#xff0c;要支持左右滑动查看多张图片(多张)。 单张图片放大&#xff0c;el-image图片组件&#xff0c;或者原生的img标签。 多张图片放大&…

笛卡尔轨迹规划之齐次变换矩阵与欧拉角、四元数的转化

一、笛卡尔轨迹规划需求 笛卡尔轨迹规划本质就是我们对机械臂的末端位置和姿态进行规划&#xff0c;其实也就是对末端坐标系的位姿进行规划。我们清楚末端坐标系的位姿是可以用齐次变换矩阵T来表示的&#xff0c;但这样表示的话&#xff0c;并不利于我们去做规划&#xff0c;所…

NPU上如何使能pytorch图模式

1 Pytorch的compile技术 PyTorch 的 torch.compile 是一个强大的功能&#xff0c;用于优化 PyTorch 模型的性能。它通过将 PyTorch 的动态图转换为静态图&#xff0c;并利用 Just-In-Time&#xff08;JIT&#xff09;编译技术&#xff0c;显著提高模型的推理速度和训练效率。 …

进制转换(c++)

由于进制转换属于基础且比较重要&#xff0c;所以我就写一个博客方便自己复习&#xff0c;过程中如有错误&#xff0c;还请指出。 常用的进制有二进制&#xff0c;八进制&#xff0c;十进制和十六进制。 常用的进制转换就是十进制转换成其他进制和其他进制转换成十进制 我们先…

2025-03-24 学习记录--C/C++-PTA 习题7-7 字符串替换

合抱之木&#xff0c;生于毫末&#xff1b;九层之台&#xff0c;起于累土&#xff1b;千里之行&#xff0c;始于足下。&#x1f4aa;&#x1f3fb; 一、题目描述 ⭐️ 习题7-7 字符串替换 本题要求编写程序&#xff0c;将给定字符串中的大写英文字母按以下对应规则替换&#…

为什么TCP需要三次握手?一次不行吗?

文章目录 1. 三次握手的过程2. 为什么需要三次握手&#xff1f;3. 握手过程中每一步的具体作用4. 简单比喻5. 为什么是三次握手&#xff0c;而不是两次或四次&#xff1f;6. 三次握手中的序列号有什么作用&#xff1f;7. 总结 1. 三次握手的过程 三次握手是建立 TCP 连接的过程…

SpringBoot2集成Elasticsearch8(使用spring-boot-starter-data-elasticsearch)

写在前面 使用spring-boot-starter-data-elasticsearch集成Elasticsearch8&#xff1f; What? 官方写的不支持啊&#xff1f;让我们来看下官方给出的版本建议。 官方地址&#xff1a; https://docs.spring.io/spring-data/elasticsearch/reference/elasticsearch/versions.…

【平台优化】持续调度参数在高负载大集群中的影响

持续调度参数在高负载大集群中的影响 背景介绍2种调度通信方式对集群的影响社区相关的讨论结论 背景介绍 这几年经历了我们大数据的Yarn集群的几次扩容&#xff0c;集群从原先的800多台增加到1300多台到现在的1600多台&#xff0c;在集群规模不断增加的过程中&#xff0c;有遇…

ElasticSearch 可观测性最佳实践

ElasticSearch 概述 ElasticSearch 是一个开源的高扩展的分布式全文检索引擎&#xff0c;它可以近乎实时的存储、检索数据&#xff1b;本身扩展性很好&#xff0c;可以扩展到上百台服务器&#xff0c;处理 PB 级别&#xff08;大数据时代&#xff09;的数据。ES 也使用 Java 开…

(一)飞行器的姿态欧拉角, 欧拉旋转, 完全数学推导(基于坐标基的变换矩阵).(偏航角,俯仰角,横滚角)

(这篇写的全是基矢变换矩阵)不是坐标变换矩阵,坐标变换矩阵的话转置一下,之后会有推导. 是通过M转置变换到P撇点.

基于Spring Boot + Vue的银行管理系统设计与实现

基于Spring Boot Vue的银行管理系统设计与实现 一、引言 随着金融数字化进程加速&#xff0c;传统银行业务向线上化转型成为必然趋势。本文设计并实现了一套基于Spring Boot Vue的银行管理系统&#xff0c;通过模块化架构满足用户、银行职员、管理员三类角色的核心业务需求…

数据库基础知识点(系列一)

1&#xff0e;数据库的发展历史分哪几个阶段&#xff1f;各有什么特点&#xff1f; 答&#xff1a;数据库技术经历了人工管理阶段、文件系统阶段和数据库系统三个阶段。 1&#xff09;人工管理阶段 这个时期数据管理的特点是&#xff1a; 数据由计算或处理它的程序自行携带…

JVM常用概念之身份哈希码

问题 当我们调用Object.hashCode时&#xff0c;如果没有用户没有提供哈希码&#xff0c;会发生什么&#xff1f; System.identityHashCode如何工作&#xff1f;它是否获取对象地址&#xff1f; 基础知识 在 Java 中&#xff0c;每个对象都有equals和hashCode &#xff0c;即…

vue 对接 paypal 订阅和支付

一个是支付一个是订阅&#xff0c;写的时候尝试把他们放到一个里面&#xff0c;但是会报错&#xff0c;所以分开写了 我们的页面&#xff0c;前三个为订阅最后一个是支付&#xff0c;我把他们放到一个数组里面循环展示的&#xff0c;所以我们判断的时候只要判断id是否为4&#…

基于javaweb的SpringBoot实习管理系统设计与实现(源码+文档+部署讲解)

技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论…

流影---开源网络流量分析平台(一)(小白超详细)

目录 流影介绍 一、技术架构与核心技术 二、核心功能与特性 流影部署 流影介绍 一、技术架构与核心技术 模块化引擎设计 流影采用四层模块化架构&#xff1a;流量探针&#xff08;数据采集&#xff09;、网络行为分析引擎&#xff08;特征提取&#xff09;、威胁检测引擎&…

Oracle 数据库安全评估(DBSAT)简明过程

下载DBSAT 从这里下载。 实际是从MOS中下载&#xff0c;即&#xff1a;Oracle Database Security Assessment Tool (DBSAT) (Doc ID 2138254.1)。 最新版本为3.1.0 (July 2024)&#xff0c;名为dbsat.zip&#xff0c;近45MB。 $ ls -lh dbsat.zip -rw-rw-r-- 1 oracle oins…

【T2I】Divide Bind Your Attention for Improved Generative Semantic Nursing

CODE: GitHub - boschresearch/Divide-and-Bind: Official implementation of "Divide & Bind Your Attention for Improved Generative Semantic Nursing" (BMVC 2023 Oral) ABSTRACT 新兴的大规模文本到图像生成模型&#xff0c;如稳定扩散(SD)&#xff0c;已…

【2025】基于springboot+uniapp的企业培训打卡小程序设计与实现(源码、万字文档、图文修改、调试答疑)

基于 Spring Boot uniapp 的企业培训打卡小程序设计与实现 系统功能结构图如下&#xff1a; 一、课题背景 在当今快节奏的商业环境中&#xff0c;企业培训对于员工的成长和企业的发展至关重要。为了满足企业对高效培训管理和员工便捷学习的需求&#xff0c;基于 Spring Boot …

探索AI的无限可能,体验智能对话的未来,大模型 API 演示

探索AI的无限可能&#xff0c;体验智能对话的未来&#xff0c;大模型 API 演示 效果展示&#xff1a; 项目概述 这是一个基于 Vue 3 TypeScript Vite 构建的 Vista AI 演示项目&#xff0c;旨在提供一个简洁易用的界面来展示 Vista AI 大语言模型的能力。项目包含 API 演示…