跳过正文
  1. 文章/

2026年热门软件开发设计模式详解

·1503 字·8 分钟
sun.ao
作者
sun.ao
我是 sun.ao,一名热爱技术的程序员,专注于 AI 和数智化领域。
目录

随着云计算、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/LLMRAG, Agent, Prompt Chaining知识增强、自主决策、任务分解
数据处理Outbox, CDC数据一致性、实时同步
可靠性Retry, Bulkhead故障恢复、资源隔离
前端架构BFF, Islands客户端定制、性能优化

选择设计模式时,应遵循简单优先原则:先用最简单的方案解决问题,当遇到瓶颈时再引入复杂模式。过度设计往往比没有设计更糟糕。


参考资料
#

相关文章