设计模式是软件工程中的智慧结晶,是解决特定问题的最佳实践模板。本文通过真实项目场景和代码示例,深入解析23种设计模式在Java开发中的实战应用,助你写出更优雅、更健壮的代码。
一、设计模式基础:为什么需要模式?
设计模式的三大分类
分类 | 核心目的 | 常用模式 |
---|---|---|
创建型 | 对象创建过程的抽象 | 工厂方法、抽象工厂、单例、建造者、原型 |
结构型 | 类和对象组合的方式 | 适配器、装饰器、代理、外观、组合、享元 |
行为型 | 对象间的通信与职责分配 | 策略、观察者、命令、状态、责任链、模板方法 |
设计模式的六大原则
- 开闭原则:对扩展开放,对修改关闭
- 里氏替换:子类可以替换父类
- 依赖倒置:面向接口编程,而非实现
- 接口隔离:多个专用接口优于单一通用接口
- 迪米特法则:减少对象间的耦合
- 单一职责:一个类只负责一个功能领域
二、创建型模式实战:优雅创建对象
1. 工厂方法模式(支付系统案例)
// 支付接口
public interface Payment {
void pay(BigDecimal amount);
}
// 具体实现
public class Alipay implements Payment {
public void pay(BigDecimal amount) {
System.out.println("支付宝支付:" + amount);
}
}
public class WechatPay implements Payment {
public void pay(BigDecimal amount) {
System.out.println("微信支付:" + amount);
}
}
// 工厂接口
public interface PaymentFactory {
Payment createPayment();
}
// 具体工厂
public class AlipayFactory implements PaymentFactory {
public Payment createPayment() {
return new Alipay();
}
}
public class WechatPayFactory implements PaymentFactory {
public Payment createPayment() {
return new WechatPay();
}
}
// 使用
public class PaymentService {
public void processPayment(PaymentFactory factory, BigDecimal amount) {
Payment payment = factory.createPayment();
payment.pay(amount);
}
}
应用场景:支付渠道扩展、数据库连接池、日志系统
2. 建造者模式(复杂对象创建)
public class Computer {
private String cpu;
private String ram;
private String ssd;
// 私有构造器
private Computer(Builder builder) {
this.cpu = builder.cpu;
this.ram = builder.ram;
this.ssd = builder.ssd;
}
public static class Builder {
private String cpu;
private String ram;
private String ssd;
public Builder cpu(String cpu) {
this.cpu = cpu;
return this;
}
public Builder ram(String ram) {
this.ram = ram;
return this;
}
public Builder ssd(String ssd) {
this.ssd = ssd;
return this;
}
public Computer build() {
return new Computer(this);
}
}
}
// 使用
Computer gamingPC = new Computer.Builder()
.cpu("Intel i9")
.ram("32GB DDR5")
.ssd("1TB NVMe")
.build();
应用场景:配置对象创建、HTTP请求构造、SQL查询构建
三、结构型模式实战:灵活组合对象
1. 适配器模式(第三方服务集成)
// 目标接口
public interface CloudStorage {
void uploadFile(String fileName);
void downloadFile(String fileName);
}
// 第三方服务(不兼容接口)
public class AWSS3Service {
public void putObject(String key) {
System.out.println("AWS S3 上传: " + key);
}
public void getObject(String key) {
System.out.println("AWS S3 下载: " + key);
}
}
// 适配器
public class S3Adapter implements CloudStorage {
private AWSS3Service s3Service;
public S3Adapter(AWSS3Service s3Service) {
this.s3Service = s3Service;
}
public void uploadFile(String fileName) {
s3Service.putObject(fileName);
}
public void downloadFile(String fileName) {
s3Service.getObject(fileName);
}
}
// 使用
CloudStorage storage = new S3Adapter(new AWSS3Service());
storage.uploadFile("report.pdf");
应用场景:旧系统整合、API兼容、设备驱动
2. 装饰器模式(Java IO扩展)
// 基础组件
public interface DataSource {
void writeData(String data);
String readData();
}
// 具体组件
public class FileDataSource implements DataSource {
private String filename;
public FileDataSource(String filename) {
this.filename = filename;
}
public void writeData(String data) {
System.out.println("写入文件: " + data);
}
public String readData() {
return "文件数据";
}
}
// 装饰器基类
public abstract class DataSourceDecorator implements DataSource {
protected DataSource wrappee;
public DataSourceDecorator(DataSource source) {
this.wrappee = source;
}
}
// 具体装饰器:加密
public class EncryptionDecorator extends DataSourceDecorator {
public EncryptionDecorator(DataSource source) {
super(source);
}
public void writeData(String data) {
String encrypted = encrypt(data);
wrappee.writeData(encrypted);
}
public String readData() {
String data = wrappee.readData();
return decrypt(data);
}
private String encrypt(String data) {
return "加密(" + data + ")";
}
private String decrypt(String data) {
return data.substring(3, data.length() - 1);
}
}
// 使用
DataSource source = new EncryptionDecorator(
new FileDataSource("data.txt")
);
source.writeData("敏感信息"); // 写入: 加密(敏感信息)
应用场景:Java IO流、Spring Security过滤器链、GUI组件增强
四、行为型模式实战:高效对象协作
1. 策略模式(电商促销系统)
// 策略接口
public interface DiscountStrategy {
BigDecimal applyDiscount(BigDecimal amount);
}
// 具体策略
public class NoDiscount implements DiscountStrategy {
public BigDecimal applyDiscount(BigDecimal amount) {
return amount;
}
}
public class PercentageDiscount implements DiscountStrategy {
private BigDecimal percentage;
public PercentageDiscount(BigDecimal percentage) {
this.percentage = percentage;
}
public BigDecimal applyDiscount(BigDecimal amount) {
return amount.multiply(BigDecimal.ONE.subtract(percentage));
}
}
public class FixedDiscount implements DiscountStrategy {
private BigDecimal discountAmount;
public FixedDiscount(BigDecimal discountAmount) {
this.discountAmount = discountAmount;
}
public BigDecimal applyDiscount(BigDecimal amount) {
return amount.subtract(discountAmount);
}
}
// 上下文
public class Order {
private BigDecimal amount;
private DiscountStrategy discountStrategy = new NoDiscount();
public void setDiscountStrategy(DiscountStrategy strategy) {
this.discountStrategy = strategy;
}
public BigDecimal calculateTotal() {
return discountStrategy.applyDiscount(amount);
}
}
// 使用
Order order = new Order();
order.setAmount(new BigDecimal("100"));
// 双11活动:75折
order.setDiscountStrategy(new PercentageDiscount(new BigDecimal("0.25")));
System.out.println("折扣价: " + order.calculateTotal()); // 75.00
// 会员日:满100减20
order.setDiscountStrategy(new FixedDiscount(new BigDecimal("20")));
System.out.println("折扣价: " + order.calculateTotal()); // 80.00
应用场景:支付方式选择、排序算法切换、游戏AI行为
2. 观察者模式(事件通知系统)
// 观察者接口
public interface EventListener {
void update(String eventType, File file);
}
// 被观察对象
public class EventManager {
private Map<String, List<EventListener>> listeners = new HashMap<>();
public EventManager(String... operations) {
for (String operation : operations) {
listeners.put(operation, new ArrayList<>());
}
}
public void subscribe(String eventType, EventListener listener) {
listeners.get(eventType).add(listener);
}
public void unsubscribe(String eventType, EventListener listener) {
listeners.get(eventType).remove(listener);
}
public void notify(String eventType, File file) {
for (EventListener listener : listeners.get(eventType)) {
listener.update(eventType, file);
}
}
}
// 具体被观察者
public class Editor {
public EventManager events;
private File file;
public Editor() {
events = new EventManager("open", "save");
}
public void openFile(String path) {
this.file = new File(path);
events.notify("open", file);
}
public void saveFile() {
if (file != null) {
events.notify("save", file);
}
}
}
// 具体观察者
public class EmailNotificationListener implements EventListener {
private String email;
public EmailNotificationListener(String email) {
this.email = email;
}
public void update(String eventType, File file) {
System.out.println("邮件通知: " + email +
" 文件 " + file.getName() + " 执行了 " + eventType + " 操作");
}
}
// 使用
Editor editor = new Editor();
editor.events.subscribe("open",
new EmailNotificationListener("admin@example.com"));
editor.events.subscribe("save",
new EmailNotificationListener("admin@example.com"));
editor.openFile("test.txt");
editor.saveFile();
应用场景:消息队列消费者、GUI事件处理、微服务状态同步
五、综合应用:电商系统中的设计模式组合
架构设计图
核心代码实现
// 外观模式:统一入口
public class ECommerceFacade {
private OrderService orderService;
private PaymentService paymentService;
private InventoryService inventoryService;
public ECommerceFacade() {
this.orderService = new OrderService();
this.paymentService = new PaymentService();
this.inventoryService = new InventoryService();
}
public void placeOrder(OrderRequest request) {
// 创建订单
Order order = orderService.createOrder(request);
// 扣减库存
inventoryService.reduceStock(order);
// 支付处理
paymentService.processPayment(order);
// 状态通知
orderService.notifyStatus(order);
}
}
// 状态模式:订单状态流转
public class Order {
private OrderState state = new NewState();
public void setState(OrderState state) {
this.state = state;
}
public void nextState() {
state.next(this);
}
public void previousState() {
state.previous(this);
}
}
public interface OrderState {
void next(Order order);
void previous(Order order);
}
public class NewState implements OrderState {
public void next(Order order) {
order.setState(new ProcessingState());
}
public void previous(Order order) {
System.out.println("初始状态");
}
}
public class ProcessingState implements OrderState {
public void next(Order order) {
order.setState(new ShippedState());
}
public void previous(Order order) {
order.setState(new NewState());
}
}
六、设计模式最佳实践与陷阱规避
1. 模式选择决策树
graph TD
A[需要解决的问题] --> B{对象创建?}
B -->|是| C[创建型模式]
B -->|否| D{对象结构?}
D -->|是| E[结构型模式]
D -->|否| F{对象交互?}
F -->|是| G[行为型模式]
C --> C1{需要解耦?}
C1 -->|是| C2[工厂/抽象工厂]
C1 -->|否| C3{需要控制实例?}
C3 -->|是| C4[单例]
E --> E1{接口不兼容?}
E1 -->|是| E2[适配器]
E1 -->|否| E3{需要增强功能?}
E3 -->|是| E4[装饰器]
G --> G1{算法切换?}
G1 -->|是| G2[策略]
G1 -->|否| G3{事件通知?}
G3 -->|是| G4[观察者]
2. 常见陷阱及解决方案
陷阱 | 后果 | 解决方案 |
---|---|---|
单例滥用 | 全局状态污染 | 依赖注入替代全局访问 |
过度使用工厂 | 代码复杂度增加 | 仅在创建逻辑复杂时使用 |
装饰器嵌套过深 | 调试困难 | 限制装饰层数(建议<5层) |
观察者循环通知 | 栈溢出 | 使用中介者模式协调 |
策略模式策略类膨胀 | 类数量爆炸 | 结合工厂方法管理策略 |
3. 现代Java中的模式演进
-
函数式编程替代部分策略模式
// 传统策略模式 Collections.sort(list, new Comparator<Integer>() { public int compare(Integer a, Integer b) { return b.compareTo(a); } }); // Lambda表达式简化 Collections.sort(list, (a, b) -> b.compareTo(a));
-
Record类简化享元模式
// 传统享元对象 public class Color { private final String name; private final int rgb; public Color(String name, int rgb) { this.name = name; this.rgb = rgb; } } // Java 14+ Record类 public record Color(String name, int rgb) {}
-
Sealed类优化状态模式
// 传统状态接口 public interface State { /* ... */ } // Java 17 Sealed类 public sealed interface State permits NewState, ProcessingState, ShippedState {}
七、设计模式在开源框架中的应用
1. Spring框架中的设计模式
模式 | 应用点 | 实现类/注解 |
---|---|---|
工厂方法 | Bean创建 | BeanFactory |
代理模式 | AOP实现 | ProxyFactoryBean |
模板方法 | JdbcTemplate | JdbcTemplate |
观察者模式 | 事件机制 | ApplicationEvent |
适配器模式 | MVC处理器适配 | HandlerAdapter |
2. MyBatis框架中的设计模式
// 建造者模式:SqlSessionFactoryBuilder
SqlSessionFactory factory = new SqlSessionFactoryBuilder()
.build(inputStream);
// 代理模式:Mapper接口代理
UserMapper mapper = session.getMapper(UserMapper.class);
// 模板方法:Executor执行流程
public abstract class BaseExecutor implements Executor {
public <E> List<E> query(...) {
// 模板方法
return doQuery(...);
}
protected abstract <E> List<E> doQuery(...);
}
八、如何避免过度设计
设计模式应用的"三不原则"
- 不要预设计:在明确需求变化点前避免提前抽象
- 不要为模式而模式:模式是手段而非目的
- 不要复杂化:简单方案能解决时不引入模式
何时应该引入设计模式?
- 系统存在多个相似变化点
- 模块间需要解耦以独立演化
- 代码出现重复的"坏味道"
- 需要提升框架扩展性
- 团队协作需要统一规范
“设计模式不是银弹,而是经验的总结。真正优秀的开发者知道何时使用模式,更知道何时不用。” —— Erich Gamma(《设计模式》作者)
结语:从模式使用者到创造者
设计模式的学习分为三个阶段:
- 认知阶段:识别代码中的模式应用
- 应用阶段:在合适场景主动应用模式
- 创造阶段:根据业务特点创新模式变体
通过本文的实战案例和场景分析,希望你能跨越从理论到实践的鸿沟,真正掌握设计模式的精髓,最终创造出适用于自己业务领域的专属模式!