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

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

一、设计模式入门指南

1. 什么是设计模式?

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

2. 为什么要学习?

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

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

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

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

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

1. 单例模式(Singleton)

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

java 复制代码
/**
 * 双重校验锁单例实现
 * 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)

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

java 复制代码
// 抽象产品接口
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)

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

java 复制代码
// 主题接口
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增强

java 复制代码
// 基础组件接口
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)

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

java 复制代码
// 策略接口
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)

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

java 复制代码
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)

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

java 复制代码
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. 单例模式双重检查锁原理

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

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

3. 装饰器模式 vs 继承

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

五、实战应用技巧

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

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

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

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

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

java 复制代码
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框架源码

    • 重构现有项目代码

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


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

相关推荐
uhakadotcom7 分钟前
WebAssembly反爬虫技术:隐藏核心逻辑和加密数据
后端·面试·github
暗诺星刻17 分钟前
Java 记忆链表,LinkedList 的升级版
java·链表·arraylist·linkedlist·记忆链表
程序猿大波20 分钟前
基于Java,SpringBoot,Vue,UniAPP智能停车场微信小程序管理系统设计
java·vue.js·spring boot
鸭梨大大大21 分钟前
LinkedList与链表
java·数据结构·链表
青木川崎25 分钟前
java基础之windows电脑基础命令
java·开发语言·windows
无眠_32 分钟前
Spring Boot Bean 的生命周期管理:从创建到销毁
java·spring boot·后端
夏季疯1 小时前
学习笔记:黑马程序员JavaWeb开发教程(2025.3.21)
java·笔记·学习
江节胜-胜行全栈AI3 小时前
Java-腾讯云短信模板兼容阿里云短信模板-短信模板参数生成
java·阿里云·腾讯云
TFHoney8 小时前
Java面试第十一山!《SpringCloud框架》
java·spring cloud·面试
日暮南城故里9 小时前
Java学习------初识JVM体系结构
java·jvm·学习