设计模式 #

软件设计的最佳实践,23种经典设计模式详解


📋 目录 #


设计模式概述 #

三类设计模式 #

设计模式 (23种)

创建型 (5种)

结构型 (7种)

行为型 (11种)

单例模式

工厂模式

抽象工厂

建造者

原型

适配器

装饰器

代理

外观

桥接

组合

享元

策略 ⭐

模板方法 ⭐

观察者 ⭐

迭代器

责任链

命令

状态机 ⭐

中介者

解释器

访问者

备忘录

设计原则 #

原则 说明 简写
单一职责 类只负责一项职责 SRP
开闭原则 对扩展开放,对修改关闭 OCP
里氏替换 子类可替换父类 LSP
接口隔离 接口细化,不依赖不需要 ISP
依赖倒置 依赖抽象,不依赖具体 DIP

创建型模式 #

单例模式 #

面试高频 ⭐⭐⭐⭐⭐

目的: 确保类只有一个实例,并提供全局访问点

// 饿汉式 - 类加载时创建
public class EagerSingleton {
    private static final EagerSingleton INSTANCE = new EagerSingleton();
    
    private EagerSingleton() {}
    
    public static EagerSingleton getInstance() {
        return INSTANCE;
    }
}

// 懒汉式 - 第一次使用时创建
public class LazySingleton {
    private static volatile LazySingleton instance;
    
    private LazySingleton() {}
    
    public static LazySingleton getInstance() {
        if (instance == null) {
            synchronized (LazySingleton.class) {
                if (instance == null) {  // 双重检查
                    instance = new LazySingleton();
                }
            }
        }
        return instance;
    }
}

// 枚举方式 - 推荐线程安全
public enum EnumSingleton {
    INSTANCE;
    
    public void doSomething() {
        // 业务逻辑
    }
}

// Spring中使用
@Service
public class SingletonService {
    // Spring默认单例
}

应用场景:

  • 配置中心
  • 线程池
  • 缓存管理
  • 数据库连接池

工厂模式 #

面试高频 ⭐⭐⭐⭐

目的: 封装对象创建过程,降低耦合

// 简单工厂
public interface Payment {
    void pay(BigDecimal amount);
}

public class AlipayPayment implements Payment {
    public void pay(BigDecimal amount) {
        System.out.println("支付宝支付: " + amount);
    }
}

public class WechatPayment implements Payment {
    public void pay(BigDecimal amount) {
        System.out.println("微信支付: " + amount);
    }
}

// 工厂类
public class PaymentFactory {
    public static Payment createPayment(String type) {
        switch (type) {
            case "alipay":
                return new AlipayPayment();
            case "wechat":
                return new WechatPayment();
            default:
                throw new IllegalArgumentException("不支持的支付方式");
        }
    }
}

// 使用
Payment payment = PaymentFactory.createPayment("alipay");
payment.pay(new BigDecimal("100.00"));

应用场景:

  • 需要创建多种相似对象
  • 不想暴露创建逻辑
  • 数据库连接工厂
  • Spring Bean工厂

建造者模式 #

目的: 分步骤创建复杂对象

public class Computer {
    private String cpu;
    private String memory;
    private String storage;
    private String gpu;
    
    private Computer() {}
    
    // 建造者
    public static class Builder {
        private Computer computer = new Computer();
        
        public Builder cpu(String cpu) {
            computer.cpu = cpu;
            return this;
        }
        
        public Builder memory(String memory) {
            computer.memory = memory;
            return this;
        }
        
        public Builder storage(String storage) {
            computer.storage = storage;
            return this;
        }
        
        public Builder gpu(String gpu) {
            computer.gpu = gpu;
            return this;
        }
        
        public Computer build() {
            return computer;
        }
    }
    
    @Override
    public String toString() {
        return "Computer{" + "cpu='" + cpu + "', memory='" + memory + 
               "', storage='" + storage + "', gpu='" + gpu + "'}";
    }
}

// 使用链式调用
Computer computer = new Computer.Builder()
    .cpu("Intel i9")
    .memory("32GB DDR5")
    .storage("1TB SSD")
    .gpu("RTX 4090")
    .build();

应用场景:

  • 复杂对象构建
  • Lombok @Builder注解
  • StringBuilder(字符构建)

结构型模式 #

适配器模式 #

目的: 将一个类的接口转换成客户希望的另一个接口

// 目标接口
public interface PowerSocket {
    void provide220V();
}

// 被适配者 - 美国插座
public class USPowerSocket {
    public void provide110V() {
        System.out.println("提供110V电压");
    }
}

// 适配器
public class PowerAdapter implements PowerSocket {
    private USPowerSocket usSocket;
    
    public PowerAdapter(USPowerSocket usSocket) {
        this.usSocket = usSocket;
    }
    
    @Override
    public void provide220V() {
        System.out.println("电压转换110V → 220V");
        usSocket.provide110V();
    }
}

// 使用
USPowerSocket usSocket = new USPowerSocket();
PowerSocket adapter = new PowerAdapter(usSocket);
adapter.provide220V();  // 提供转换后的220V

应用场景:

  • Spring MVC HandlerAdapter
  • 异常处理器转换
  • 第三方API对接

装饰器模式 #

目的: 动态地给对象添加额外功能

// Component接口
public interface Coffee {
    double cost();
    String description();
}

// ConcreteComponent
public class BlackCoffee implements Coffee {
    public double cost() {
        return 10.0;
    }
    
    public String description() {
        return "黑咖啡";
    }
}

// Decorator
public abstract class CoffeeDecorator implements Coffee {
    protected Coffee coffee;
    
    public CoffeeDecorator(Coffee coffee) {
        this.coffee = coffee;
    }
}

// ConcreteDecorator
public class MilkDecorator extends CoffeeDecorator {
    public MilkDecorator(Coffee coffee) {
        super(coffee);
    }
    
    public double cost() {
        return coffee.cost() + 2.0;
    }
    
    public String description() {
        return coffee.description() + ", 牛奶";
    }
}

public class SugarDecorator extends CoffeeDecorator {
    public SugarDecorator(Coffee coffee) {
        super(coffee);
    }
    
    public double cost() {
        return coffee.cost() + 1.0;
    }
    
    public String description() {
        return coffee.description() + ", 糖";
    }
}

// 使用 - 动态组合
Coffee coffee = new BlackCoffee();
coffee = new MilkDecorator(coffee);
coffee = new SugarDecorator(coffee);

System.out.println(coffee.description());  // 黑咖啡, 牛奶, 糖
System.out.println(coffee.cost());          // 13.0

应用场景:

  • Java I/O (new BufferedReader(new FileReader(...)))
  • Spring Bean装饰

代理模式 #

面试高频 ⭐⭐⭐⭐⭐

目的: 控制对象的访问

// 接口
public interface UserService {
    User getUser(Long id);
}

// 真实对象
public class UserServiceImpl implements UserService {
    public User getUser(Long id) {
        System.out.println("查询数据库获取用户");
        return new User(id, "Tom");
    }
}

// 代理对象
public class UserServiceProxy implements UserService {
    private UserServiceImpl realService;
    
    public UserServiceProxy() {
        this.realService = new UserServiceImpl();
    }
    
    @Override
    public User getUser(Long id) {
        System.out.println("前置逻辑: 权限检查");
        User user = realService.getUser(id);
        System.out.println("后置逻辑: 记录日志");
        return user;
    }
}

// 使用
UserService proxy = new UserServiceProxy();
proxy.getUser(1L);

应用场景:

  • 远程代理 (RPC)
  • 虚拟代理 (懒加载)
  • 保护代理 (权限)
  • Spring AOP动态代理

外观模式 #

目的: 为复杂子系统提供简单接口

// 复杂子系统
class CPU {
    public void run() { System.out.println("CPU工作"); }
}

class Memory {
    public void load() { System.out.println("内存加载"); }
}

class HardDrive {
    public void read() { System.out.println("硬盘读取"); }
}

// 外观类
class ComputerFacade {
    private CPU cpu;
    private Memory memory;
    private HardDrive hardDrive;
    
    public ComputerFacade() {
        this.cpu = new CPU();
        this.memory = new Memory();
        this.hardDrive = new HardDrive();
    }
    
    public void start() {
        System.out.println("电脑启动");
        hardDrive.read();
        memory.load();
        cpu.run();
        System.out.println("启动完成");
    }
}

// 使用 - 简化接口
ComputerFacade computer = new ComputerFacade();
computer.start();

应用场景:

  • SLF4J (统一日志接口)
  • 复杂API简化
  • Spring JdbcTemplate

行为型模式 #

策略模式 #

面试高频 ⭐⭐⭐⭐⭐

目的: 定义算法族,分别封装,互相替换

// 支付策略接口
public interface PaymentStrategy {
    void pay(BigDecimal amount);
}

// 策略实现
public class AlipayStrategy implements PaymentStrategy {
    public void pay(BigDecimal amount) {
        System.out.println("支付宝支付: " + amount);
    }
}

public class WechatStrategy implements PaymentStrategy {
    public void pay(BigDecimal amount) {
        System.out.println("微信支付: " + amount);
    }
}

public class UnionPayStrategy implements PaymentStrategy {
    public void pay(BigDecimal amount) {
        System.out.println("银联支付: " + amount);
    }
}

// 上下文
public class PaymentContext {
    private PaymentStrategy strategy;
    
    public PaymentContext(PaymentStrategy strategy) {
        this.strategy = strategy;
    }
    
    public void executePayment(BigDecimal amount) {
        strategy.pay(amount);
    }
    
    public void setStrategy(PaymentStrategy strategy) {
        this.strategy = strategy;
    }
}

// 使用 - 动态切换策略
PaymentContext context = new PaymentContext(new AlipayStrategy());
context.executePayment(new BigDecimal("100.00"));

context.setStrategy(new WechatStrategy());
context.executePayment(new BigDecimal("200.00"));

应用场景:

  • 多种支付方式 ⭐
  • 多种排序算法
  • 多种压缩方式
  • Spring @Transactional 事务管理

模板方法模式 #

面试高频 ⭐⭐⭐⭐

目的: 定义算法骨架,子类实现具体步骤

// 抽象类 - 算法骨架
public abstract class DataProcessor {
    
    // 模板方法 - 定义算法流程 (final防止重写)
    public final void process() {
        loadData();
        validate();
        transform();
        save();
    }
    
    // 抽象方法 - 子类实现
    protected abstract void loadData();
    protected abstract void validate();
    protected abstract void transform();
    protected abstract void save();
    
    // 钩子方法 - 可选重写
    protected void beforeSave() {
        System.out.println("默认前置处理");
    }
}

// 具体实现
public class CSVDataProcessor extends DataProcessor {
    protected void loadData() {
        System.out.println("加载CSV数据");
    }
    
    protected void validate() {
        System.out.println("CSV数据校验");
    }
    
    protected void transform() {
        System.out.println("CSV格式转换");
    }
    
    protected void save() {
        beforeSave();
        System.out.println("保存CSV数据");
    }
}

// 使用
DataProcessor csvProcessor = new CSVDataProcessor();
csvProcessor.process();

应用场景:

  • Spring JdbcTemplate ⭐
  • Spring RestTemplate ⭐
  • Spring RedisTemplate
  • Servlet doGet/doPost

观察者模式 #

面试高频 ⭐⭐⭐⭐⭐

目的: 一对多依赖,对象状态变化通知依赖者

import java.util.ArrayList;
import java.util.List;

// 观察者接口
interface Observer {
    void update(String message);
}

// 被观察者
class Subject {
    private List<Observer> observers = new ArrayList<>();
    private String state;
    
    public void attach(Observer observer) {
        observers.add(observer);
    }
    
    public void detach(Observer observer) {
        observers.remove(observer);
    }
    
    public void setState(String state) {
        this.state = state;
        notifyObservers();
    }
    
    private void notifyObservers() {
        for (Observer observer : observers) {
            observer.update(state);
        }
    }
}

// 具体观察者
class EmailObserver implements Observer {
    public void update(String message) {
        System.out.println("邮件通知: " + message);
    }
}

class SMSObserver implements Observer {
    public void update(String message) {
        System.out.println("短信通知: " + message);
    }
}

// 使用
Subject subject = new Subject();
subject.attach(new EmailObserver());
subject.attach(new SMSObserver());

subject.setState("订单已创建");  // 所有观察者收到通知

Java内置观察者:

import java.util.Observable;
import java.util.Observer;

// 使用Java内置Observer
class MessagePublisher extends Observable {
    public void publish(String message) {
        setChanged();
        notifyObservers(message);
    }
}

class User implements Observer {
    public void update(Observable o, Object arg) {
        System.out.println("收到消息: " + arg);
    }
}

应用场景:

  • 事件总线 (EventBus)
  • 消息系统 (MQ)
  • Spring ApplicationEvent
  • 股市行情推送

状态机模式 #

目的:

持有当前状态

实现

实现

根据条件切换

根据条件切换

Context

-State state

+request()

+setState(State)

«interface»

State

+handle(Context)

ConcreteStateA

+handle(Context)

ConcreteStateB

+handle(Context)

«状态转换»

StateTransition

+condition

+targetState

示例: 订单状态机

// 状态接口
interface OrderState {
    void process(Order order);
}

// 具体状态
class CreatedState implements OrderState {
    public void process(Order order) {
        System.out.println("订单已创建");
        if (order.isPaid()) {
            order.setState(new PaidState());
        }
    }
}

class PaidState implements OrderState {
    public void process(Order order) {
        System.out.println("订单已支付");
        if (order.isShipped()) {
            order.setState(new ShippedState());
        }
    }
}

class ShippedState implements OrderState {
    public void process(Order order) {
        System.out.println("订单已发货");
        if (order.isDelivered()) {
            order.setState(new CompletedState());
        }
    }
}

class CompletedState implements OrderState {
    public void process(Order order) {
        System.out.println("订单已完成");
    }
}

// 订单类 (上下文)
class Order {
    private OrderState state = new CreatedState();
    private boolean paid = false;
    private boolean shipped = false;
    private boolean delivered = false;
    
    public void setState(OrderState state) {
        this.state = state;
    }
    
    public void process() {
        state.process(this);
    }
    
    // 订单事件触发
    public void paid() { this.paid = true; }
    public void shipped() { this.shipped = true; }
    public void delivered() { this.delivered = true; }
    
    // getters
    public boolean isPaid() { return paid; }
    public boolean isShipped() { return shipped; }
    public boolean isDelivered() { return delivered; }
}

// 使用
Order order = new Order();
order.process();          // 订单已创建

order.paid();
order.process();          // 订单已支付

order.shipped();
order.process();          // 订单已发货

order.delivered();
order.process();          // 订单已完成

创建订单

支付

发货

送达

Created

Paid

Shipped

Completed

应用场景:

  • 交易系统 ⭐
  • 订单状态管理
  • 工单流转
  • 审批流程
  • 游戏状态

常见模式对比 #

模式 目的 典型场景
工厂 创建对象 Spring BeanFactory
策略 算法替换 多种支付方式
观察者 事件通知 Spring Event
模板方法 算法骨架 JdbcTemplate
代理 控制访问 Spring AOP
装饰器 动态增强 I/O流、AOP
适配器 接口转换 HandlerAdapter
状态机 状态流转 订单状态管理

面试题汇总 #

创建型 #

  1. 单例模式的几种实现方式?
  2. 工厂模式何时使用?
  3. 建造者模式与工厂模式区别?

结构型 #

  1. 适配器模式 vs 装饰器模式?
  2. 代理模式的应用场景?
  3. Spring用了哪些设计模式?

行为型 #

  1. 策略模式与工厂模式区别?
  2. 观察者模式的实现方式?
  3. 模板方法模式的应用?

综合题 #

  1. Spring IOC用了哪些设计模式?
  2. Spring AOP用了哪些设计模式?
  3. 你在项目中用过哪些设计模式?

面试题答案详解 #

创建型 #

  1. 单例模式的几种实现方式?

答案:

实现方式 说明
饿汉式 类加载就创建,线程安全
懒汉式 第一次用才创建,有并发问题
双重检查锁定 DCL + volatile,线程安全
枚举方式 最简单,天然线程安全,推荐

代码示例:

// 1. 饿汉式
public class Singleton1 {
    private static final Singleton1 INSTANCE = new Singleton1();
    private Singleton1() {}
    public static Singleton1 getInstance() {
        return INSTANCE;
    }
}

// 2. 双重检查锁定
public class Singleton2 {
    private static volatile Singleton2 instance;
    private Singleton2() {}
    public static Singleton2 getInstance() {
        if (instance == null) {
            synchronized (Singleton2.class) {
                if (instance == null) {
                    instance = new Singleton2();
                }
            }
        }
        return instance;
    }
}

// 3. 枚举(推荐)
public enum Singleton3 {
    INSTANCE;
    public void doSomething() {}
}

  1. 工厂模式何时使用?

答案:

工厂模式适用场景:

场景 说明
创建对象逻辑复杂 非new那么简单
多种实现方式 根据条件返回不同实现
不想暴露创建细节 客户端只知道接口
解耦 创建和使用分离

示例:

// 根据类型创建不同的支付方式
PaymentFactory.create("alipay");
PaymentFactory.create("wechat");

  1. 建造者模式与工厂模式区别?

答案:

对比 工厂模式 建造者模式
关注点 创建什么对象 怎么创建对象(步骤)
复杂度 简单 复杂
产品数 多个产品 一个产品,多种配置
示例 PaymentFactory Computer.Builder

结构型 #

  1. 适配器模式 vs 装饰器模式?

答案:

对比 适配器模式 装饰器模式
目的 接口转换 增加功能
关系 不相关 → 兼容 同类增强
示例 PowerAdapter、HandlerAdapter InputStreamDecorator

  1. 代理模式的应用场景?

答案:

场景 示例
远程代理 RMI、RPC
虚拟代理 图片懒加载
保护代理 权限控制
智能引用 AOP动态代理

  1. Spring用了哪些设计模式?

答案:

模式 Spring中的应用
工厂模式 BeanFactory、ApplicationContext
单例模式 Bean默认单例
代理模式 AOP(JDK/CGLIB)
模板方法 JdbcTemplate、RestTemplate
观察者模式 ApplicationEvent、Listener
策略模式 InstantiationStrategy
装饰器模式 BeanWrapper
适配器模式 HandlerAdapter

行为型 #

  1. 策略模式与工厂模式区别?

答案:

对比 工厂模式 策略模式
目的 创建对象 选择算法
关注点 创建 行为
阶段 创建时 运行时
关系 创建 组合

策略模式结构:

Context

Strategy接口

策略实现A

策略实现B

策略实现C


  1. 观察者模式的实现方式?

答案:

方式 说明
Java内置 Observable + Observer(已过时)
自定义 Subject + Observer
事件总线 Guava EventBus、Spring Event

Spring事件示例:

@Component
public class UserRegisteredEvent extends ApplicationEvent {
    public UserRegisteredEvent(User user) {
        super(user);
    }
}

@Component
public class EmailListener {
    @EventListener
    public void onUserRegistered(UserRegisteredEvent event) {
    }
}

  1. 模板方法模式的应用?

答案:

模板方法 = 算法骨架 + 子类实现

Spring中的应用:

应用 说明
JdbcTemplate SQL执行流程
RestTemplate HTTP请求流程
AbstractRoutingDataSource DataSource路由
ApplicationContext.refresh 容器刷新流程

综合题 #

  1. Spring IOC用了哪些设计模式?

答案:

模式 说明
工厂模式 BeanFactory创建Bean
单例模式 默认Singleton作用域
装饰器模式 BeanWrapper装饰
策略模式 InstantiationStrategy创建策略
观察者模式 Bean生命周期回调
模板方法 refresh()方法

  1. Spring AOP用了哪些设计模式?

答案:

模式 说明
代理模式 JDK/CGLIB动态代理
策略模式 代理策略选择
观察者模式 AOP通知
装饰器模式 ProxyFactoryBean

  1. 你在项目中用过哪些设计模式?

答案:

回答模板:

1. 策略模式
   - 场景: 多种支付方式(Alipay/WechatPay)
   - 好处: 新增支付方式不用改原有代码

2. 模板方法
   - 场景: 不同第三方接口调用流程一致
   - 好处: 复用流程,扩展方便

3. 建造者
   - 场景: 复杂对象构建
   - 好处: 链式调用,清晰

4. 观察者模式
   - 场景: 订单创建后通知多个系统
   - 好处: 解耦

🔗 相关笔记 #


📚 扩展阅读 #

  • 《设计模式:可复用面向对象软件的基础》
  • 《Head First 设计模式》
  • 《敏捷软件开发:原则、模式与实践》

最后更新: 2026-04-29