《设计模式实战指南:工厂模式 vs 单例模式,面试官问这题我直接拿下!》

引言:设计模式就像乐高积木说明书

如果你是正在准备面试的Java开发者,一定被面试官问过这样的问题:"说说工厂模式和单例模式的区别?"。今天我们就来一场"设计模式寻宝游戏",用乐高积木的比喻,带你玩转工厂模式、单例模式、策略模式等高频面试考点。记住:每个设计模式都是解决特定问题的魔法积木,学会它们就能像搭积木一样优雅地构建系统!


一、工厂模式:乐高工厂的生产流水线

1. 工厂模式的核心思想

// 抽象产品:乐高积木基类 
public abstract class LegoBrick {
    public abstract void assemble();
}
 
// 具体产品:乐高城市系列积木 
public class CityLego extends LegoBrick {
    @Override 
    public void assemble() {
        System.out.println(" 正在组装城市警车");
    }
}
 
// 具体产品:乐高星球大战系列积木 
public class StarWarsLego extends LegoBrick {
    @Override 
    public void assemble() {
        System.out.println(" 正在组装千年隼号");
    }
}
 
// 工厂类:乐高生产中心 
public class LegoFactory {
    public LegoBrick createLego(String type) {
        if ("city".equals(type)) {
            return new CityLego();
        } else if ("starwars".equals(type)) {
            return new StarWarsLego();
        }
        throw new IllegalArgumentException("未知积木类型");
    }
}
  • 比喻:就像乐高工厂根据订单生产不同类型的积木,工厂模式将对象创建逻辑集中管理
  • 核心价值:解耦客户端与具体产品类,符合开闭原则(对扩展开放,对修改关闭)

2. Spring源码中的工厂模式

查看BeanFactory接口:

public interface BeanFactory {
    Object getBean(String name) throws BeansException;
    // ...其他工厂方法 
}
  • 工厂模式升级版:Spring通过BeanFactory实现对象创建与管理的工业化生产

二、单例模式:全球限量版乐高套装

1. 单例模式的实现方式

// 饿汉式:出生就准备好所有零件 
public class LegoCollector {
    private static final LegoCollector INSTANCE = new LegoCollector();
    
    private LegoCollector() {}
    
    public static LegoCollector getInstance() {
        return INSTANCE;
    }
}
 
// 懒汉式:按需组装零件 
public class LegoCollector {
    private static LegoCollector instance;
    
    private LegoCollector() {}
    
    public static synchronized LegoCollector getInstance() {
        if (instance == null) {
            instance = new LegoCollector();
        }
        return instance;
    }
}
  • 比喻:就像乐高全球限量版套装,确保整个系统只有一个实例存在
  • 经典应用场景:数据库连接池、日志记录器、配置管理者

2. 双重校验锁的源码级优化

// 线程安全的懒汉式 
public class LegoCollector {
    private volatile static LegoCollector instance;
    
    private LegoCollector() {}
    
    public static LegoCollector getInstance() {
        if (instance == null) {
            synchronized (LegoCollector.class)  {
                if (instance == null) {
                    instance = new LegoCollector();
                }
            }
        }
        return instance;
    }
}
  • volatile关键字:防止指令重排序,保证可见性
  • 同步块优化:减少同步范围,提升并发性能

三、策略模式:乐高积木的组装策略

1. 策略模式的实现

// 策略接口:组装策略 
public interface AssemblyStrategy {
    void assemble();
}
 
// 具体策略:快速组装模式 
public class QuickAssembly implements AssemblyStrategy {
    @Override 
    public void assemble() {
        System.out.println(" 使用说明书快速组装");
    }
}
 
// 具体策略:创意自由组装模式 
public class CreativeAssembly implements AssemblyStrategy {
    @Override 
    public void assemble() {
        System.out.println(" 自由发挥创意组装");
    }
}
 
// 上下文类:组装大师 
public class LegoMaster {
    private AssemblyStrategy strategy;
    
    public void setStrategy(AssemblyStrategy strategy) {
        this.strategy  = strategy;
    }
    
    public void assemble() {
        strategy.assemble(); 
    }
}
  • 比喻:就像乐高提供不同组装策略,策略模式让算法灵活切换
  • Spring Security源码AuthenticationManager就是策略模式的典型应用

四、实战场景:电商系统中的设计模式

场景1:支付方式工厂

// 抽象支付方式 
public interface PaymentStrategy {
    void pay(double amount);
}
 
// 支付宝支付 
public class AlipayStrategy implements PaymentStrategy {
    @Override 
    public void pay(double amount) {
        System.out.println(" 正在通过支付宝支付:" + amount);
    }
}
 
// 工厂类 
public class PaymentFactory {
    public PaymentStrategy createPayment(String type) {
        if ("alipay".equals(type)) {
            return new AlipayStrategy();
        }
        // 其他支付方式...
        return null;
    }
}
  • 设计模式组合技:工厂模式 + 策略模式,实现支付方式的灵活扩展

场景2:订单状态管理(状态模式)

// 订单状态接口 
public interface OrderState {
    void handle(Order order);
}
 
// 已支付状态 
public class PaidState implements OrderState {
    @Override 
    public void handle(Order order) {
        System.out.println(" 订单已支付,准备发货");
        order.setState(new  ShippedState());
    }
}
  • 比喻:就像乐高积木的状态转换,状态模式让对象行为随状态改变而改变

五、面试题终极攻略

1. 如何区分工厂模式和抽象工厂模式?

  • 工厂模式:生产单一产品族(如乐高城市系列)
  • 抽象工厂模式:生产多个产品族(如乐高同时生产城市系列、星球大战系列、好朋友系列)

2. 单例模式的线程安全实现有哪些方式?

  • 饿汉式
  • 懒汉式(同步方法/同步代码块)
  • 双重校验锁
  • 静态内部类方式(推荐)

3. 为什么Spring提倡使用构造器注入?

  • 符合开闭原则
  • 保证对象状态完整性
  • 与设计模式(如工厂模式)配合更优雅

六、互动时间:你猜对了吗?

  1. 为什么策略模式比if-else语句更优秀?(留言区揭晓答案)
  2. Spring MVC中哪个设计模式最常用?(点击右下角❤️查看源码分析)
  3. 观察者模式在Java中有哪些现成实现?(关注公众号获取彩蛋)

结语:掌握这些设计模式就像拥有乐高Master Builder认证,可以自由组合搭建各种Java应用。记住:每个设计模式都是解决特定问题的魔法积木,而你就是那个创造者! 下一期我们将揭秘Spring Security的魔法盾牌,记得点击订阅按钮不错过精彩内容!

今日互动:在评论区分享你最喜欢的3个设计模式,并说明使用场景