随着云计算、AI 和分布式系统的普及,传统的设计模式已经不能满足现代软件开发的需求。本文将介绍2026年最热门的软件开发设计模式,并提供简洁易懂的代码实例。
一、云原生与微服务模式#
1. Sidecar 模式#
核心思想:将辅助功能(日志、监控、配置管理)作为独立进程,与主应用部署在同一主机上,共享网络和存储。
应用场景:Kubernetes 中的日志收集、服务网格代理。
// 主应用服务
public class MainApplication {
public static void main(String[] args) {
// 主业务逻辑
System.out.println("主应用启动,监听端口 8080");
// Sidecar 通过共享的网络命名空间访问
}
}
// Sidecar 进程(独立的日志收集器)
public class LogSidecar {
public static void main(String[] args) {
// 监听主应用的日志文件或端口
System.out.println("Sidecar 启动,负责日志收集和上报");
// 将日志发送到集中式日志系统
}
}Kubernetes 部署示例:
apiVersion: v1
kind: Pod
metadata:
name: app-with-sidecar
spec:
containers:
- name: main-app
image: my-app:latest
- name: log-sidecar
image: log-collector:latest # Sidecar 容器2. Circuit Breaker(熔断器)#
核心思想:当下游服务故障时,快速失败,防止级联崩溃。类似电路保险丝。
应用场景:微服务调用、外部 API 调用。
// 使用 Resilience4j 实现
import io.github.resilience4j.circuitbreaker.CircuitBreaker;
import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig;
public class PaymentService {
private final CircuitBreaker circuitBreaker;
public PaymentService() {
CircuitBreakerConfig config = CircuitBreakerConfig.custom()
.failureRateThreshold(50) // 失败率超过50%触发熔断
.waitDurationInOpenState(Duration.ofSeconds(30)) // 熔断30秒后尝试恢复
.slidingWindowSize(10) // 滑动窗口大小
.build();
this.circuitBreaker = CircuitBreaker.of("payment", config);
}
public String processPayment(String orderId) {
return circuitBreaker.executeSupplier(() -> {
// 调用下游支付服务
return callPaymentGateway(orderId);
});
}
// 熔断时的降级处理
public String processPaymentFallback(String orderId, Exception e) {
return "支付服务暂时不可用,请稍后重试";
}
}3. Saga 模式#
核心思想:将分布式事务拆分为一系列本地事务,每个事务有对应的补偿操作。失败时执行补偿回滚。
应用场景:电商下单(库存扣减 → 支付 → 物流创建)。
// 订单创建 Saga
public class OrderSaga {
private final InventoryService inventoryService;
private final PaymentService paymentService;
private final ShippingService shippingService;
public void createOrder(Order order) {
try {
// 步骤1:扣减库存
inventoryService.deductStock(order.getProductId(), order.getQuantity());
try {
// 步骤2:处理支付
paymentService.charge(order.getUserId(), order.getAmount());
try {
// 步骤3:创建物流单
shippingService.createShipment(order);
System.out.println("订单创建成功!");
} catch (Exception e) {
// 补偿步骤2:退款
paymentService.refund(order.getUserId(), order.getAmount());
throw e;
}
} catch (Exception e) {
// 补偿步骤1:恢复库存
inventoryService.restoreStock(order.getProductId(), order.getQuantity());
throw e;
}
} catch (Exception e) {
System.out.println("订单创建失败:" + e.getMessage());
}
}
}4. CQRS(命令查询职责分离)#
核心思想:读写操作使用不同的模型和数据库,优化各自的性能。
应用场景:高并发系统、复杂查询场景。
// 命令模型(写操作)
public class OrderCommandService {
private final OrderWriteRepository writeRepo;
public void createOrder(CreateOrderCommand cmd) {
Order order = new Order(cmd.getUserId(), cmd.getProducts());
writeRepo.save(order);
// 发布事件通知读模型更新
eventBus.publish(new OrderCreatedEvent(order));
}
public void updateOrderStatus(UpdateStatusCommand cmd) {
Order order = writeRepo.findById(cmd.getOrderId());
order.setStatus(cmd.getStatus());
writeRepo.save(order);
eventBus.publish(new OrderUpdatedEvent(order));
}
}
// 查询模型(读操作)
public class OrderQueryService {
private final OrderReadRepository readRepo; // 可以是不同的数据库
public OrderDTO getOrder(Long orderId) {
return readRepo.findById(orderId);
}
public List<OrderDTO> getOrdersByUser(Long userId) {
return readRepo.findByUserId(userId);
}
}
// 读模型可以是优化的视图
@Entity
@Table(name = "order_view")
public class OrderDTO {
private Long id;
private String userName; // 冗余存储,避免关联查询
private String productNames; // 冗余存储
private String status;
private LocalDateTime createdAt;
}二、AI/LLM 应用模式#
1. RAG(检索增强生成)#
核心思想:先从知识库检索相关文档,再将文档作为上下文传给 LLM,提高回答准确性。
应用场景:企业知识库问答、智能客服。
// Node.js + LangChain 实现
import { OpenAI } from "openai";
import { PineconeClient } from "@pinecone-database/pinecone";
class RAGService {
constructor() {
this.openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
this.pinecone = new PineconeClient();
}
async answer(question) {
// 1. 将问题转换为向量
const questionEmbedding = await this.openai.embeddings.create({
model: "text-embedding-3-small",
input: question
});
// 2. 从向量数据库检索相关文档
const relevantDocs = await this.pinecone
.index("knowledge-base")
.query({
vector: questionEmbedding.data[0].embedding,
topK: 3
});
// 3. 构建增强提示词
const context = relevantDocs.matches.map(m => m.metadata.text).join("\n\n");
const prompt = `
基于以下参考资料回答问题,如果资料中没有相关信息,请说明。
参考资料:
${context}
问题:${question}
回答:`;
// 4. 调用 LLM 生成回答
const response = await this.openai.chat.completions.create({
model: "gpt-4",
messages: [{ role: "user", content: prompt }]
});
return response.choices[0].message.content;
}
}2. Agent 模式#
核心思想:AI 代理能够自主决策、调用工具、执行多步任务。
应用场景:自动化工作流、智能助手。
// Node.js 实现简单的 AI Agent
class AIAgent {
constructor() {
this.tools = {
search: this.search.bind(this),
calculate: this.calculate.bind(this),
sendEmail: this.sendEmail.bind(this)
};
}
async execute(task) {
let step = 0;
let context = { task, results: [] };
while (step < 5) { // 最多5步
// 让 LLM 决定下一步行动
const decision = await this.decideAction(context);
if (decision.action === "finish") {
return decision.result;
}
// 执行工具调用
const result = await this.tools[decision.action](decision.params);
context.results.push({ action: decision.action, result });
step++;
}
return "任务执行超时";
}
async decideAction(context) {
const prompt = `
当前任务:${context.task}
已执行步骤:${JSON.stringify(context.results)}
可用工具:search, calculate, sendEmail
请决定下一步行动,返回 JSON 格式:
{"action": "工具名或finish", "params": {...}, "result": "如果是finish时的结果"}
`;
const response = await this.openai.chat.completions.create({
model: "gpt-4",
messages: [{ role: "user", content: prompt }],
response_format: { type: "json_object" }
});
return JSON.parse(response.choices[0].message.content);
}
async search(query) {
// 调用搜索 API
return `搜索结果:${query} 的相关信息...`;
}
async calculate(expression) {
return eval(expression);
}
async sendEmail(params) {
console.log(`发送邮件到 ${params.to}: ${params.subject}`);
return "邮件发送成功";
}
}
// 使用示例
const agent = new AIAgent();
const result = await agent.execute("帮我查询北京明天的天气,并发邮件给 boss@company.com");3. Prompt Chaining(提示链)#
核心思想:将复杂任务拆分为多个 LLM 调用,前一个的输出作为后一个的输入。
应用场景:内容生成流水线、代码生成。
class PromptChain {
async generateArticle(topic) {
// 步骤1:生成大纲
const outline = await this.generateOutline(topic);
// 步骤2:生成各章节内容
const sections = await this.generateSections(outline);
// 步骤3:润色和优化
const article = await this.polishArticle(sections);
// 步骤4:生成摘要
const summary = await this.generateSummary(article);
return { article, summary };
}
async generateOutline(topic) {
const response = await this.openai.chat.completions.create({
model: "gpt-4",
messages: [{
role: "user",
content: `为文章"${topic}"生成大纲,返回 JSON 数组格式`
}]
});
return JSON.parse(response.choices[0].message.content);
}
async generateSections(outline) {
const sections = [];
for (const section of outline) {
const response = await this.openai.chat.completions.create({
model: "gpt-4",
messages: [{
role: "user",
content: `根据大纲"${section.title}"撰写内容,要点:${section.points.join(",")}`
}]
});
sections.push({
title: section.title,
content: response.choices[0].message.content
});
}
return sections;
}
async polishArticle(sections) {
const content = sections.map(s => `## ${s.title}\n${s.content}`).join("\n\n");
const response = await this.openai.chat.completions.create({
model: "gpt-4",
messages: [{
role: "user",
content: `请润色以下文章,使其更加流畅:\n${content}`
}]
});
return response.choices[0].message.content;
}
async generateSummary(article) {
const response = await this.openai.chat.completions.create({
model: "gpt-4",
messages: [{
role: "user",
content: `为以下文章生成100字摘要:\n${article}`
}]
});
return response.choices[0].message.content;
}
}三、数据处理模式#
1. Outbox 模式#
核心思想:保证数据库更新和消息发送的原子性。将消息先写入 Outbox 表,再由独立进程发送。
应用场景:微服务间的事件通知。
// 订单服务
@Service
public class OrderService {
@Autowired
private OrderRepository orderRepo;
@Autowired
private OutboxRepository outboxRepo;
@Transactional
public void createOrder(Order order) {
// 1. 保存订单
orderRepo.save(order);
// 2. 将事件写入 Outbox 表(同一事务)
OutboxEvent event = new OutboxEvent();
event.setAggregateType("Order");
event.setAggregateId(order.getId());
event.setEventType("OrderCreated");
event.setPayload(objectMapper.writeValueAsString(order));
outboxRepo.save(event);
}
}
// Outbox 表结构
@Entity
@Table(name = "outbox")
public class OutboxEvent {
@Id
private UUID id;
private String aggregateType;
private String aggregateId;
private String eventType;
private String payload;
private LocalDateTime createdAt;
}
// 独立的消息发送器
@Component
public class OutboxPublisher {
@Scheduled(fixedRate = 1000)
public void publishEvents() {
List<OutboxEvent> events = outboxRepo.findTop100ByOrderByCreatedAtAsc();
for (OutboxEvent event : events) {
try {
kafkaTemplate.send(event.getAggregateType(), event.getPayload());
outboxRepo.delete(event); // 发送成功后删除
} catch (Exception e) {
log.error("发送事件失败: {}", event.getId());
}
}
}
}2. CDC(变更数据捕获)#
核心思想:实时捕获数据库变更,触发下游处理。
应用场景:数据同步、实时分析、缓存更新。
// 使用 Debezium 捕获 MySQL 变更
@Component
public class OrderCDCProcessor {
@KafkaListener(topics = "dbserver1.inventory.orders")
public void processOrderChange(ChangeEvent<String, String> event) {
JSONObject payload = new JSONObject(event.getValue());
String operation = payload.getJSONObject("payload").getString("op");
switch (operation) {
case "c": // Create
handleOrderCreated(payload);
break;
case "u": // Update
handleOrderUpdated(payload);
break;
case "d": // Delete
handleOrderDeleted(payload);
break;
}
}
private void handleOrderCreated(JSONObject payload) {
JSONObject after = payload.getJSONObject("payload").getJSONObject("after");
Long orderId = after.getLong("id");
// 更新 Elasticsearch 索引
searchService.indexOrder(orderId);
// 更新 Redis 缓存
cacheService.cacheOrder(orderId, after.toString());
// 发送通知
notificationService.notifyNewOrder(orderId);
}
}四、可靠性模式#
1. Retry with Exponential Backoff(指数退避重试)#
核心思想:失败后重试,但等待时间指数增长,避免雪崩。
public class RetryClient {
private static final int MAX_RETRIES = 5;
private static final long INITIAL_DELAY_MS = 100;
public <T> T executeWithRetry(Supplier<T> operation) {
int attempt = 0;
long delay = INITIAL_DELAY_MS;
while (attempt < MAX_RETRIES) {
try {
return operation.get();
} catch (Exception e) {
attempt++;
if (attempt >= MAX_RETRIES) {
throw new RuntimeException("重试次数耗尽", e);
}
System.out.println("第 " + attempt + " 次重试,等待 " + delay + "ms");
try {
Thread.sleep(delay);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
throw new RuntimeException("重试被中断", ie);
}
delay *= 2; // 指数增长
// 添加随机抖动,避免多个客户端同时重试
delay += (long) (delay * 0.1 * Math.random());
}
}
throw new RuntimeException("不应到达这里");
}
}
// 使用示例
RetryClient client = new RetryClient();
String result = client.executeWithRetry(() -> {
return externalApi.call(); // 可能失败的调用
});2. Bulkhead(舱壁隔离)#
核心思想:限制每个服务的资源使用,防止一个服务耗尽所有资源。
// 使用 Resilience4j 实现
import io.github.resilience4j.bulkhead.Bulkhead;
import io.github.resilience4j.bulkhead.BulkheadConfig;
@Service
public class ExternalService {
// 为不同服务设置独立的舱壁
private final Bulkhead paymentBulkhead;
private final Bulkhead notificationBulkhead;
public ExternalService() {
BulkheadConfig config = BulkheadConfig.custom()
.maxConcurrentCalls(10) // 最大并发数
.maxWaitDuration(Duration.ofSeconds(1))
.build();
this.paymentBulkhead = Bulkhead.of("payment", config);
this.notificationBulkhead = Bulkhead.of("notification", config);
}
public String callPayment(String orderId) {
return paymentBulkhead.executeSupplier(() -> {
return paymentClient.process(orderId);
});
}
public void sendNotification(String message) {
notificationBulkhead.executeRunnable(() -> {
notificationClient.send(message);
});
}
}五、前端架构模式#
1. BFF(Backend for Frontend)#
核心思想:为不同客户端(Web、Mobile、小程序)提供定制化的后端 API。
// Node.js + Express 实现
// Web 端 BFF
const webBff = express();
webBff.get('/product/:id', async (req, res) => {
const productId = req.params.id;
// 聚合多个后端服务
const [product, reviews, recommendations] = await Promise.all([
productService.getDetail(productId),
reviewService.getReviews(productId, { limit: 10 }),
recommendationService.getRelated(productId, { limit: 5 })
]);
// 为 Web 端定制响应格式
res.json({
product: {
id: product.id,
name: product.name,
price: product.price,
description: product.fullDescription, // Web 显示完整描述
images: product.highResImages // Web 使用高清图
},
reviews,
recommendations
});
});
// Mobile 端 BFF
const mobileBff = express();
mobileBff.get('/product/:id', async (req, res) => {
const productId = req.params.id;
const product = await productService.getDetail(productId);
// 为 Mobile 端定制响应格式
res.json({
product: {
id: product.id,
name: product.name,
price: product.price,
description: product.shortDescription, // Mobile 显示简短描述
thumbnail: product.thumbnailImage // Mobile 使用缩略图
}
// Mobile 端不返回评论和推荐,减少数据量
});
});2. Islands Architecture(岛屿架构)#
核心思想:静态 HTML 中嵌入交互式"岛屿",减少 JavaScript 体积。
// Astro 框架示例
// ---
// 静态页面大部分是纯 HTML
// ---
import Header from '../components/Header.astro';
import Footer from '../components/Footer.astro';
import InteractiveCounter from '../components/Counter.jsx'; // 交互式岛屿
const posts = await fetch('/api/posts').then(r => r.json());
---
<html>
<head>
<title>博客首页</title>
</head>
<body>
<Header /> <!-- 静态 -->
<main>
<!-- 静态内容,零 JS -->
<section class="posts">
{posts.map(post => (
<article>
<h2>{post.title}</h2>
<p>{post.excerpt}</p>
</article>
))}
</section>
<!-- 交互式岛屿,只有这部分会加载 JS -->
<InteractiveCounter client:visible />
</main>
<Footer /> <!-- 静态 -->
</body>
</html>
// Counter.jsx - 只有这个组件会加载 JavaScript
export default function Counter() {
const [count, setCount] = useState(0);
return (
<div className="counter">
<button onClick={() => setCount(c => c - 1)}>-</button>
<span>{count}</span>
<button onClick={() => setCount(c => c + 1)}>+</button>
</div>
);
}六、总结#
| 模式类别 | 核心模式 | 解决的问题 |
|---|---|---|
| 云原生 | Sidecar, Circuit Breaker, Saga, CQRS | 服务治理、容错、分布式事务 |
| AI/LLM | RAG, Agent, Prompt Chaining | 知识增强、自主决策、任务分解 |
| 数据处理 | Outbox, CDC | 数据一致性、实时同步 |
| 可靠性 | Retry, Bulkhead | 故障恢复、资源隔离 |
| 前端架构 | BFF, Islands | 客户端定制、性能优化 |
选择设计模式时,应遵循简单优先原则:先用最简单的方案解决问题,当遇到瓶颈时再引入复杂模式。过度设计往往比没有设计更糟糕。
