引言:设计模式就像乐高积木说明书
如果你是正在准备面试的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提倡使用构造器注入?
- 符合开闭原则
- 保证对象状态完整性
- 与设计模式(如工厂模式)配合更优雅
六、互动时间:你猜对了吗?
- 为什么策略模式比if-else语句更优秀?(留言区揭晓答案)
- Spring MVC中哪个设计模式最常用?(点击右下角❤️查看源码分析)
- 观察者模式在Java中有哪些现成实现?(关注公众号获取彩蛋)
结语:掌握这些设计模式就像拥有乐高Master Builder认证,可以自由组合搭建各种Java应用。记住:每个设计模式都是解决特定问题的魔法积木,而你就是那个创造者! 下一期我们将揭秘Spring Security的魔法盾牌,记得点击订阅按钮不错过精彩内容!
今日互动:在评论区分享你最喜欢的3个设计模式,并说明使用场景