Java面试设计模式案例

wen java案例 2

本文目录导读:

Java面试设计模式案例

  1. 创建型模式(高频考点)
  2. 结构型模式(中高频)
  3. 行为型模式(高频)
  4. Spring框架中的设计模式(必考)
  5. 面试准备建议

我为你整理了一份系统的Java面试设计模式案例指南,涵盖高频考点、核心代码示例和面试话术,助你从容应对。


创建型模式(高频考点)

单例模式(Singleton)- 最常考

适用场景:数据库连接池、配置管理器、线程池

面试重点:懒汉式(线程安全)、饿汉式、双重检查锁(DCL)、静态内部类、枚举

// 双重检查锁(DCL) - 面试最常问
public class Singleton {
    // volatile 防止指令重排序
    private static volatile Singleton instance;
    private Singleton() {
        // 私有构造,防止外部实例化
    }
    public static Singleton getInstance() {
        if (instance == null) {                     // 第一次检查,避免加锁
            synchronized (Singleton.class) {        // 加锁
                if (instance == null) {             // 第二次检查,防止重复创建
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}
// 静态内部类 - 推荐版(懒加载 + 线程安全)
public class Singleton2 {
    private Singleton2() {}
    private static class Holder {
        private static final Singleton2 INSTANCE = new Singleton2();
    }
    public static Singleton2 getInstance() {
        return Holder.INSTANCE;
    }
}
// 枚举版 - 最安全(防反射、防序列化攻击)
public enum Singleton3 {
    INSTANCE;
    private String config = "默认配置";
    public String getConfig() {
        return config;
    }
}

面试话术

“我们项目中的RedisConfigManager采用了双检锁单例,用volatile确保多线程下的可见性,同时通过二次判空避免了同步性能损耗,如果是防序列化破坏,我会用枚举实现,因为枚举天然防止反射和反序列化创建新实例。”


工厂方法模式(Factory Method)

适用场景:日志记录器、文件导出器、数据库连接

// 抽象产品
public interface Logger {
    void log(String message);
}
// 具体产品
public class ConsoleLogger implements Logger {
    public void log(String message) {
        System.out.println("控制台日志: " + message);
    }
}
public class FileLogger implements Logger {
    public void log(String message) {
        System.out.println("文件日志: " + message);
    }
}
// 抽象工厂
public abstract class LoggerFactory {
    public abstract Logger createLogger();
}
// 具体工厂
public class ConsoleLoggerFactory extends LoggerFactory {
    public Logger createLogger() {
        return new ConsoleLogger();
    }
}
public class FileLoggerFactory extends LoggerFactory {
    public Logger createLogger() {
        return new FileLogger();
    }
}
// 使用
public class Application {
    public static void main(String[] args) {
        LoggerFactory factory = new ConsoleLoggerFactory();
        Logger logger = factory.createLogger();
        logger.log("工厂模式示例");
    }
}

抽象工厂模式(Abstract Factory)

适用场景:跨平台UI组件(Windows/Linux按钮、菜单)

public interface Button { void click(); }
public interface TextBox { void input(); }
// Windows产品族
public class WindowsButton implements Button {
    public void click() { System.out.println("Windows按钮点击"); }
}
public class WindowsTextBox implements TextBox {
    public void input() { System.out.println("Windows文本框输入"); }
}
// Mac产品族
public class MacButton implements Button {
    public void click() { System.out.println("Mac按钮点击"); }
}
public class MacTextBox implements TextBox {
    public void input() { System.out.println("Mac文本框输入"); }
}
// 抽象工厂
public interface UIFactory {
    Button createButton();
    TextBox createTextBox();
}
// 具体工厂
public class WindowsUIFactory implements UIFactory {
    public Button createButton() { return new WindowsButton(); }
    public TextBox createTextBox() { return new WindowsTextBox(); }
}
public class MacUIFactory implements UIFactory {
    public Button createButton() { return new MacButton(); }
    public TextBox createTextBox() { return new MacTextBox(); }
}

结构型模式(中高频)

适配器模式(Adapter)

场景:新旧系统接口兼容、第三方SDK适配

// 旧接口
public interface OldPayment {
    void pay(double amount);
}
// 新支付方式 - 接口不兼容
public class WeChatPay {
    public void payByWeChat(double money) {
        System.out.println("微信支付: " + money + "元");
    }
}
// 适配器 - 让旧接口兼容新实现
public class PaymentAdapter implements OldPayment {
    private WeChatPay weChatPay;
    public PaymentAdapter(WeChatPay weChatPay) {
        this.weChatPay = weChatPay;
    }
    @Override
    public void pay(double amount) {
        weChatPay.payByWeChat(amount);  // 转换调用
    }
}
// 客户端使用
public class OrderService {
    public void checkout(OldPayment payment) {
        payment.pay(100.0);
    }
    public static void main(String[] args) {
        OrderService service = new OrderService();
        // 通过适配器使用微信支付
        service.checkout(new PaymentAdapter(new WeChatPay()));
    }
}

代理模式(Proxy)- 高频

应用场景:Spring AOP、延迟加载、权限控制

// 真实接口
public interface Database {
    void query(String sql);
}
// 真实对象
public class RealDatabase implements Database {
    public void query(String sql) {
        System.out.println("执行查询: " + sql);
    }
}
// 代理对象 - 增加缓存、权限控制
public class CacheProxy implements Database {
    private RealDatabase realDatabase;
    private Map<String, String> cache = new HashMap<>();
    public void query(String sql) {
        // 代理增强逻辑
        if (cache.containsKey(sql)) {
            System.out.println("从缓存获取: " + cache.get(sql));
            return;
        }
        if (realDatabase == null) {
            realDatabase = new RealDatabase();
        }
        realDatabase.query(sql);
        cache.put(sql, "查询结果");
    }
}

面试补充:动态代理(JDK Proxy vs CGLIB)也是高频话题,建议熟练掌握,Spring AOP底层正是基于此。


装饰器模式(Decorator)

场景:Java I/O流、Spring事务增强

public interface Coffee {
    double cost();
    String description();
}
// 基础咖啡
public class Espresso implements Coffee {
    public double cost() { return 2.0; }
    public String description() { return "浓缩咖啡"; }
}
// 装饰器基类
public abstract class CoffeeDecorator implements Coffee {
    protected Coffee coffee;
    public CoffeeDecorator(Coffee coffee) {
        this.coffee = coffee;
    }
}
// 具体装饰器 - 牛奶
public class MilkDecorator extends CoffeeDecorator {
    public MilkDecorator(Coffee coffee) { super(coffee); }
    public double cost() { return coffee.cost() + 0.5; }
    public String description() { return coffee.description() + "+牛奶"; }
}
// 使用
Coffee coffee = new Espresso();
coffee = new MilkDecorator(coffee);  // 动态添加功能
coffee = new SugarDecorator(coffee); // 再叠加糖

行为型模式(高频)

观察者模式(Observer)- 面试必问

场景:微信公众号推送、消息队列、监听器

// 观察者接口
public interface Observer {
    void update(String message);
}
// 被观察者(主题)
public class NewsPublisher {
    private List<Observer> observers = new ArrayList<>();
    private String latestNews;
    public void attach(Observer observer) {
        observers.add(observer);
    }
    public void detach(Observer observer) {
        observers.remove(observer);
    }
    public void publishNews(String news) {
        this.latestNews = news;
        notifyAllObservers();
    }
    private void notifyAllObservers() {
        for (Observer observer : observers) {
            observer.update(latestNews);
        }
    }
}
// 具体观察者
public class User implements Observer {
    private String name;
    public User(String name) { this.name = name; }
    public void update(String message) {
        System.out.println(name + "收到通知: " + message);
    }
}
// 客户端
NewsPublisher publisher = new NewsPublisher();
publisher.attach(new User("张三"));
publisher.attach(new User("李四"));
publisher.publishNews("发布Java新版本!");

策略模式(Strategy)- 高频

场景:支付方式选择、排序算法切换、优惠活动

// 策略接口
public interface PayStrategy {
    void pay(double amount);
}
// 具体策略 - 支付宝
public class AlipayStrategy implements PayStrategy {
    public void pay(double amount) {
        System.out.println("支付宝支付: " + amount + "元");
    }
}
// 具体策略 - 银行转账
public class BankTransferStrategy implements PayStrategy {
    public void pay(double amount) {
        System.out.println("银行转账: " + amount + "元");
    }
}
// 上下文(使用策略的对象)
public class PaymentContext {
    private PayStrategy strategy;
    public void setStrategy(PayStrategy strategy) {
        this.strategy = strategy;
    }
    public void executePayment(double amount) {
        strategy.pay(amount);
    }
}
// 使用 - 运行时动态换策略
PaymentContext context = new PaymentContext();
context.setStrategy(new AlipayStrategy());
context.executePayment(100);
context.setStrategy(new BankTransferStrategy());
context.executePayment(200);

面试加分:策略模式 + 工厂模式结合使用,避免客户端直接new具体策略。


模板方法模式(Template Method)

场景:Spring JdbcTemplate、工作流

// 模板 - 定义算法骨架
public abstract class Workflow {
    // 固定工作流,子类不能修改
    public final void runWorkflow() {
        validate();
        execute();
        hook();          // 钩子方法(可选)
        postProcess();
    }
    protected abstract void validate();
    protected abstract void execute();
    // 钩子 - 子类可以选择性覆盖
    protected void hook() { }
    private void postProcess() {
        System.out.println("通用后处理");
    }
}
// 具体实现
public class OrderFlow extends Workflow {
    protected void validate() { 
        System.out.println("验证订单信息"); 
    }
    protected void execute() { 
        System.out.println("处理订单业务"); 
    }
    protected void hook() {
        System.out.println("发送订单通知");
    }
}

Spring框架中的设计模式(必考)

模式 在Spring中的应用 举例
工厂模式 BeanFactory/ApplicationContext getBean() 创建对象
单例模式 默认Bean作用域 @Scope("singleton")
代理模式 AOP、声明式事务 @Transactional 默认使用CGLIB代理
模板方法 JdbcTemplate 操作数据库模板方法
观察者模式 事件驱动机制 @EventListener
策略模式 资源访问、处理器映射 HandlerMapping
适配器模式 对各种Handler适配 HandlerAdapter
装饰器模式 BeanWrapper、对Response处理 HttpHeadResponseDecorator

面试准备建议

高频追问问题

  • 单例模式为什么用volatile?(禁止指令重排序,防止拿到未初始化对象)
  • 如何销毁单例?(反射、序列化反序列化会破坏,需重写readResolve()
  • JDK Proxy和CGLIB的区别?(JDK动态代理基于接口,CGLIB基于继承,Spring默认JDK,没有接口自动用CGLIB)

必背代码清单

  • ✅ 双检锁单例(手写)
  • ✅ JDK动态代理(手写InvocationHandler)
  • ✅ 观察者模式的实现

话术技巧

  • 回答时先说应用场景,再讲设计思路,最后给核心代码(场景→思路→代码)
  • 强调“为什么用”比“怎么用”更重要
  • 结合实际项目举例,如:“我在订单系统中使用了策略模式来应对多种支付方式,避免了大量if-else”

这份资料覆盖了面试中80%以上的设计模式考点,建议你挑2-3个模式,结合自己的项目经历准备成3分钟左右的讲解稿,这样面试时能更有底气、表达更流畅,需要我针对某个具体的模式深入讲解,或者帮你准备开题话术,随时告诉我!

抱歉,评论功能暂时关闭!