<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: 架构师小白</title>
    <description>The latest articles on DEV Community by 架构师小白 (@tianxin).</description>
    <link>https://dev.to/tianxin</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3824850%2Fd2237655-84d6-4050-ade4-4acffe96bf30.png</url>
      <title>DEV Community: 架构师小白</title>
      <link>https://dev.to/tianxin</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tianxin"/>
    <language>en</language>
    <item>
      <title>管道模式深度指南：构建可组合的数据处理流水线</title>
      <dc:creator>架构师小白</dc:creator>
      <pubDate>Thu, 07 May 2026 01:02:36 +0000</pubDate>
      <link>https://dev.to/tianxin/guan-dao-mo-shi-shen-du-zhi-nan-gou-jian-ke-zu-he-de-shu-ju-chu-li-liu-shui-xian-2bek</link>
      <guid>https://dev.to/tianxin/guan-dao-mo-shi-shen-du-zhi-nan-gou-jian-ke-zu-he-de-shu-ju-chu-li-liu-shui-xian-2bek</guid>
      <description>&lt;h1&gt;
  
  
  管道模式深度指南：构建可组合的数据处理流水线
&lt;/h1&gt;

&lt;h2&gt;
  
  
  什么是管道模式？
&lt;/h2&gt;

&lt;p&gt;管道模式（Pipeline Pattern）是一种将数据处理任务分解为多个独立步骤的设计模式。每个步骤作为一个独立的处理单元，数据像水流一样依次通过各个管道进行处理。&lt;/p&gt;

&lt;h2&gt;
  
  
  核心概念
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. 处理器（Handler）
&lt;/h3&gt;

&lt;p&gt;每个处理步骤都是一个独立的功能单元，只负责单一的转换或处理逻辑。&lt;/p&gt;

&lt;h3&gt;
  
  
  2. 管道（Pipeline）
&lt;/h3&gt;

&lt;p&gt;将多个处理器串联起来，形成一个完整的数据处理流程。&lt;/p&gt;

&lt;h3&gt;
  
  
  3. 上下文（Context）
&lt;/h3&gt;

&lt;p&gt;在处理过程中传递的数据对象，包含输入、处理中的状态和最终结果。&lt;/p&gt;

&lt;h2&gt;
  
  
  代码示例
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Pipeline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;handlers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;  &lt;span class="c1"&gt;# 支持链式调用
&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;handler&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  实际应用场景
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;数据清洗&lt;/strong&gt;：ETL流程中的数据转换&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;请求处理&lt;/strong&gt;：HTTP请求的层层过滤&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;图像处理&lt;/strong&gt;：滤镜链、格式转换&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;函数式编程&lt;/strong&gt;：map-reduce操作&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  优势
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;职责单一&lt;/strong&gt;：每个处理器只做一件事&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;可复用&lt;/strong&gt;：处理器可以在不同管道中重用&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;易测试&lt;/strong&gt;：每个处理器可独立测试&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;可扩展&lt;/strong&gt;：新增步骤只需添加处理器&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  总结
&lt;/h2&gt;

&lt;p&gt;管道模式是构建复杂数据处理系统的利器，它让代码更清晰、更易维护。将复杂任务分解为简单步骤，是架构设计的重要思想。&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>dataengineering</category>
      <category>python</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>设计模式与原则：构建可扩展代码的经典之道</title>
      <dc:creator>架构师小白</dc:creator>
      <pubDate>Wed, 06 May 2026 01:03:19 +0000</pubDate>
      <link>https://dev.to/tianxin/she-ji-mo-shi-yu-yuan-ze-gou-jian-ke-kuo-zhan-dai-ma-de-jing-dian-zhi-dao-317c</link>
      <guid>https://dev.to/tianxin/she-ji-mo-shi-yu-yuan-ze-gou-jian-ke-kuo-zhan-dai-ma-de-jing-dian-zhi-dao-317c</guid>
      <description>&lt;h1&gt;
  
  
  设计模式与原则：构建可扩展代码的经典之道
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;软件设计是一门艺术，而设计模式和原则是这门艺术的语法。它们不是教条，而是经过时间检验的智慧结晶。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  为什么设计模式重要？
&lt;/h2&gt;

&lt;p&gt;想象一下，你在盖房子。每一块砖自己堆叠，最终只能是一堵墙。但如果你懂得使用不同的砌法——砖混结构、框架结构、钢结构——你就能建出摩天大楼。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;设计模式&lt;/strong&gt;就是这样一套"建筑语法"。它们是：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;已解决的问题&lt;/strong&gt; — 前人已经踩过的坑，总结出的解决方案&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;通用的词汇&lt;/strong&gt; — 让你和团队高效沟通&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;经过验证的实践&lt;/strong&gt; — 无数项目验证过的最佳实践&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  核心设计原则：SOLID
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;原则&lt;/th&gt;
&lt;th&gt;全称&lt;/th&gt;
&lt;th&gt;解释&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;S&lt;/td&gt;
&lt;td&gt;单一职责&lt;/td&gt;
&lt;td&gt;一个类只做一件事&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;O&lt;/td&gt;
&lt;td&gt;开闭原则&lt;/td&gt;
&lt;td&gt;对扩展开放，对修改封闭&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;L&lt;/td&gt;
&lt;td&gt;里氏替换&lt;/td&gt;
&lt;td&gt;子类可以替换父类&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;I&lt;/td&gt;
&lt;td&gt;接口隔离&lt;/td&gt;
&lt;td&gt;不要依赖不需要的接口&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;D&lt;/td&gt;
&lt;td&gt;依赖倒置&lt;/td&gt;
&lt;td&gt;依赖抽象而非具体&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  23种经典设计模式
&lt;/h2&gt;

&lt;p&gt;分为三类：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;创建型&lt;/strong&gt;（5种）：Singleton、Factory、Abstract Factory、Builder、Prototype&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;结构型&lt;/strong&gt;（7种）：Adapter、Bridge、Composite、Decorator、Facade、Flyweight、Proxy&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;行为型&lt;/strong&gt;（11种）：Chain of Responsibility、Command、Iterator、Mediator、Memento、Observer、State、Strategy、Template Method、Visitor&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  最常用的5种模式
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. 单例模式（Singleton）
&lt;/h3&gt;

&lt;p&gt;确保一个类只有一个实例。适用：配置管理、日志、连接池。&lt;/p&gt;

&lt;h3&gt;
  
  
  2. 工厂方法模式（Factory Method）
&lt;/h3&gt;

&lt;p&gt;定义创建对象的接口，让子类决定实例化哪个类。适用：支付方式、通知渠道。&lt;/p&gt;

&lt;h3&gt;
  
  
  3. 观察者模式（Observer）
&lt;/h3&gt;

&lt;p&gt;定义一对多依赖，当对象变化时通知所有依赖者。适用：事件系统、消息推送。&lt;/p&gt;

&lt;h3&gt;
  
  
  4. 装饰器模式（Decorator）
&lt;/h3&gt;

&lt;p&gt;动态添加职责。适用：中间件、拦截器、日志。&lt;/p&gt;

&lt;h3&gt;
  
  
  5. 策略模式（Strategy）
&lt;/h3&gt;

&lt;p&gt;定义一系列算法，封装起来使它们可以互换。适用：压缩算法、排序算法。&lt;/p&gt;

&lt;h2&gt;
  
  
  如何选择正确的模式？
&lt;/h2&gt;

&lt;h3&gt;
  
  
  问自己三个问题
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;你在解决什么问题？&lt;/strong&gt; 创建/结构/行为&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;问题会变化吗？&lt;/strong&gt; 会变化用策略、装饰器&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;代码会膨胀吗？&lt;/strong&gt; 会膨胀→分解职责&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  反模式警告
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;不要为了用模式而用模式。如果一行代码能解决，不要用五个类。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  实践建议
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;从问题出发&lt;/strong&gt; — 遇到问题→思考是否已有模式→没有再创新&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;小步重构&lt;/strong&gt; — 先写能工作的代码→识别重复→提炼模式&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;团队共识&lt;/strong&gt; — 在团队内建立模式语言&lt;/li&gt;
&lt;/ol&gt;




&lt;blockquote&gt;
&lt;p&gt;Design is not just what it looks like and feels like. Design is how it works. — Steve Jobs&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Happy Coding! 🚀&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>design</category>
      <category>python</category>
      <category>beginners</category>
    </item>
    <item>
      <title>微内核架构深度指南：构建可扩展系统的核心艺术</title>
      <dc:creator>架构师小白</dc:creator>
      <pubDate>Tue, 05 May 2026 01:03:48 +0000</pubDate>
      <link>https://dev.to/tianxin/wei-nei-he-jia-gou-shen-du-zhi-nan-gou-jian-ke-kuo-zhan-xi-tong-de-he-xin-yi-zhu-clc</link>
      <guid>https://dev.to/tianxin/wei-nei-he-jia-gou-shen-du-zhi-nan-gou-jian-ke-kuo-zhan-xi-tong-de-he-xin-yi-zhu-clc</guid>
      <description>&lt;h1&gt;
  
  
  微内核架构深度指南：构建可扩展系统的核心艺术
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;微内核架构（Microkernel Architecture）是一种经典且强大的架构模式，它将核心系统功能与可选功能分离，让系统具备前所未有的灵活性。本文将深入探讨微内核架构的核心概念、设计原理和实践要点。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  什么是微内核架构？
&lt;/h2&gt;

&lt;p&gt;微内核架构是一种将核心功能与扩展功能分离的架构模式。系统的核心部分（内核）只包含最基本的功能，如进程调度、内存管理和基础通信机制。其他功能（如文件系统、网络协议、设备驱动等）作为可选模块（插件）在内核之外实现。&lt;/p&gt;

&lt;h2&gt;
  
  
  核心组成
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. 核心内核（Core Kernel）
&lt;/h3&gt;

&lt;p&gt;核心内核只包含最基本的功能：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;基础进程管理&lt;/strong&gt; - 进程创建、调度、销毁&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;基础内存管理&lt;/strong&gt; - 虚拟内存、内存分配&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;基础通信机制&lt;/strong&gt; - 进程间通信（IPC）基础&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;安全基础&lt;/strong&gt; - 权限检查和访问控制&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. 插件系统（Plugin System）
&lt;/h3&gt;

&lt;p&gt;插件是可选的扩展功能模块：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;文件系统&lt;/strong&gt; - 各种文件系统实现&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;设备驱动&lt;/strong&gt; - 硬件设备驱动&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;网络协议&lt;/strong&gt; - TCP/IP、UDP 等协议栈&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;服务组件&lt;/strong&gt; - 业务功能模块&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. 通信总线（Communication Bus）
&lt;/h3&gt;

&lt;p&gt;连接内核和插件的桥梁：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;事件通道&lt;/strong&gt; - 插件间通信&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;服务注册&lt;/strong&gt; - 插件发现机制&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;生命周期管理&lt;/strong&gt; - 插件加载/卸载&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  微内核架构的优势
&lt;/h2&gt;

&lt;h3&gt;
  
  
  高度灵活性
&lt;/h3&gt;

&lt;p&gt;新功能 → 只需开发新插件 → 无需修改核心&lt;/p&gt;

&lt;p&gt;系统可以动态加载/卸载功能模块，而无需修改核心代码。&lt;/p&gt;

&lt;h3&gt;
  
  
  系统稳定性
&lt;/h3&gt;

&lt;p&gt;核心崩溃 → 整个系统崩溃&lt;br&gt;
插件崩溃 → 仅该插件不可用&lt;/p&gt;

&lt;p&gt;核心保持 minimal，极小化的代码意味着更少的 bug 和更高的稳定性。&lt;/p&gt;

&lt;h3&gt;
  
  
  可测试性
&lt;/h3&gt;

&lt;p&gt;单元测试 → 插件独立测试&lt;br&gt;
集成测试 → 插件组合测试&lt;/p&gt;

&lt;p&gt;每个插件可以独立开发和测试，降低了测试复杂度。&lt;/p&gt;

&lt;h3&gt;
  
  
  可扩展性
&lt;/h3&gt;

&lt;p&gt;按需加载 → 资源按需使用&lt;br&gt;
动态扩展 → 运行时扩展&lt;/p&gt;

&lt;p&gt;系统可以根据需求动态添加新功能。&lt;/p&gt;

&lt;h2&gt;
  
  
  适用场景
&lt;/h2&gt;

&lt;h3&gt;
  
  
  理想场景
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;IDE/编辑器&lt;/strong&gt; - VS Code、IntelliJ IDEA 使用插件架构&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;浏览器&lt;/strong&gt; - Chrome、Firefox 的扩展系统&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;服务器软件&lt;/strong&gt; - Kubernetes、Docker 的插件生态&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;桌面应用&lt;/strong&gt; - 设计软件、游戏的可扩展模块&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  不适合场景
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;资源受限环境&lt;/strong&gt; - 嵌入式系统（插件开销太大）&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;实时性要求高&lt;/strong&gt; - 延迟成本高的场景&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;功能高度耦合&lt;/strong&gt; - 模块间强依赖的场景&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  实际案例
&lt;/h2&gt;

&lt;h3&gt;
  
  
  VS Code 的插件架构
&lt;/h3&gt;

&lt;p&gt;VS Code 的微内核架构设计：&lt;/p&gt;

&lt;p&gt;核心内核:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;编辑器核心&lt;/li&gt;
&lt;li&gt;语言服务接口&lt;/li&gt;
&lt;li&gt;调试协议&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;插件系统:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;语言扩展 (Python, Go, Java...)&lt;/li&gt;
&lt;li&gt;主题插件&lt;/li&gt;
&lt;li&gt;格式化插件&lt;/li&gt;
&lt;li&gt;调试适配器&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Kubernetes 的插件系统
&lt;/h3&gt;

&lt;p&gt;Kubernetes 通过 CRD（Custom Resource Definitions）实现插件化：&lt;/p&gt;

&lt;p&gt;核心 API: Pod, Service, Deployment&lt;br&gt;
自定义资源: 通过 CRD 扩展&lt;br&gt;
存储插件: CSI (Container Storage Interface)&lt;br&gt;
网络插件: CNI (Container Network Interface)&lt;/p&gt;

&lt;h2&gt;
  
  
  实现要点
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. 明确的边界
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 定义清晰的插件接口&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Plugin&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PluginContext&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nf"&gt;shutdown&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. 沙箱隔离
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 插件在独立沙箱中运行&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PluginSandbox&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;plugin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Plugin&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// 限制系统调用&lt;/span&gt;
    &lt;span class="c1"&gt;// 限制文件系统访问&lt;/span&gt;
    &lt;span class="c1"&gt;// 限制网络访问&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. 版本兼容性
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 声明式版本约束&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;PluginManifest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;apiVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// 核心 API 版本要求&lt;/span&gt;
  &lt;span class="nl"&gt;dependencies&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. 热加载支持
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 动态加载/卸载&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PluginManager&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pluginPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Plugin&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;unload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pluginId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;reload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pluginId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  最佳实践
&lt;/h2&gt;

&lt;h3&gt;
  
  
  推荐做法
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;保持核心 minimal&lt;/strong&gt; - 内核越简单越好&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;清晰的接口定义&lt;/strong&gt; - 稳定的 API 是关键&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;版本向后兼容&lt;/strong&gt; - 避免破坏性变更&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;完善的错误处理&lt;/strong&gt; - 插件错误不应影响核心&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;安全沙箱&lt;/strong&gt; - 保护系统不受恶意插件影响&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  避免做法
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;在核心中添加小功能&lt;/strong&gt; - 违反 minimal 原则&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;频繁变更 API&lt;/strong&gt; - 破坏插件兼容性&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;跳过错误处理&lt;/strong&gt; - 插件崩溃不能导致系统崩溃&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;忽视安全性&lt;/strong&gt; - 插件具有系统级权限&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  总结
&lt;/h2&gt;

&lt;p&gt;微内核架构是一种强大的设计模式，特别适合需要高度可扩展性的系统。通过将核心功能与扩展功能分离，我们可以获得：&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;价值&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;灵活性&lt;/td&gt;
&lt;td&gt;动态添加/移除功能&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;稳定性&lt;/td&gt;
&lt;td&gt;核心 minimal，更少 bug&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;可测试性&lt;/td&gt;
&lt;td&gt;独立测试各组件&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;可扩展性&lt;/td&gt;
&lt;td&gt;按需扩展系统能力&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;核心原则：&lt;strong&gt;最小化核心，最大化扩展&lt;/strong&gt;。&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;思考：你的系统真的需要微内核架构吗？如果插件化带来的复杂度超过其价值，考虑更简单的模块化方案。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;如果对你有帮助，欢迎关注、点赞、评论！一起探讨软件架构之美&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>microservices</category>
      <category>programming</category>
    </item>
    <item>
      <title>服务发现模式深度指南：构建微服务动态注册的艺术</title>
      <dc:creator>架构师小白</dc:creator>
      <pubDate>Mon, 04 May 2026 01:03:03 +0000</pubDate>
      <link>https://dev.to/tianxin/fu-wu-fa-xian-mo-shi-shen-du-zhi-nan-gou-jian-wei-fu-wu-dong-tai-zhu-ce-de-yi-zhu-47hb</link>
      <guid>https://dev.to/tianxin/fu-wu-fa-xian-mo-shi-shen-du-zhi-nan-gou-jian-wei-fu-wu-dong-tai-zhu-ce-de-yi-zhu-47hb</guid>
      <description>&lt;h1&gt;
  
  
  服务发现模式深度指南：构建微服务动态注册的艺术
&lt;/h1&gt;

&lt;p&gt;在微服务架构中，服务实例的网络位置并非固定不变。它们会因部署、升级、故障或自动扩缩容而动态变化。如何让服务消费者能够动态地感知到这些变化，就成了微服务架构中必须解决的核心问题之一。&lt;strong&gt;服务发现模式&lt;/strong&gt;正是为解决这一问题而生的架构模式。&lt;/p&gt;

&lt;h2&gt;
  
  
  为什么需要服务发现？
&lt;/h2&gt;

&lt;p&gt;传统的单体应用中，所有组件部署在同一台服务器上，网络位置固定，我们可以通过配置文件来管理服务地址。但在微服务环境中，这一套就行不通了：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;动态扩缩容&lt;/strong&gt;：根据负载动态增加或减少服务实例&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;容器化部署&lt;/strong&gt;：容器可能被调度到任何可用的节点上&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;滚动更新&lt;/strong&gt;：新版本部署时会有新旧版本并存的情况&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;故障恢复&lt;/strong&gt;：故障实例被替换，新实例启动&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;想象一下，如果没有服务发现，你的订单服务需要知道用户服务、商品服务、支付服务等十几个服务的地址，而这些地址随时可能变化。这显然是不现实的。&lt;/p&gt;

&lt;h2&gt;
  
  
  服务发现的核心机制
&lt;/h2&gt;

&lt;p&gt;服务发现本质上是一个注册与查询的过程：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;服务注册&lt;/strong&gt;：服务实例启动时向注册中心注册自己的地址&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;心跳保活&lt;/strong&gt;：定期发送心跳证明自己还活着&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;服务查询&lt;/strong&gt;：消费者从注册中心查询可用的服务实例&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;健康检查&lt;/strong&gt;：注册中心定期检查服务实例的健康状态&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  两种服务发现策略
&lt;/h2&gt;

&lt;h3&gt;
  
  
  客户端服务发现
&lt;/h3&gt;

&lt;p&gt;客户端服务发现是指服务消费者自己负责从注册中心获取服务列表，并选择具体的实例。这种方式的典型代表是 &lt;strong&gt;Eureka&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;工作流程：&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;服务实例启动时向 Eureka Server 注册&lt;/li&gt;
&lt;li&gt;客户端定期从 Eureka 获取服务列表&lt;/li&gt;
&lt;li&gt;客户端使用负载均衡算法选择具体实例&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;优点：&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;架构简单，不需要额外的代理层&lt;/li&gt;
&lt;li&gt;延迟低，直接通信&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;缺点：&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;客户端需要实现服务发现逻辑，多语言支持成本高&lt;/li&gt;
&lt;li&gt;客户端负担重，需要处理负载均衡、重试等逻辑&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  服务端服务发现
&lt;/h3&gt;

&lt;p&gt;服务端服务发现是指通过一个代理层（如负载均衡器）来协调服务发现。客户端只需要知道代理层的地址，剩下的事情由代理层处理。典型代表包括 &lt;strong&gt;Envoy&lt;/strong&gt;、&lt;strong&gt;nginx&lt;/strong&gt;、&lt;strong&gt;Kubernetes DNS&lt;/strong&gt; 等。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;工作流程：&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;服务实例向注册中心注册&lt;/li&gt;
&lt;li&gt;代理层订阅服务变化&lt;/li&gt;
&lt;li&gt;客户端请求发送到代理层&lt;/li&gt;
&lt;li&gt;代理层转发到具体实例&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;优点：&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;客户端无感知，专注于业务逻辑&lt;/li&gt;
&lt;li&gt;多语言友好&lt;/li&gt;
&lt;li&gt;中央式管理，安全策略容易实施&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;缺点：&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;增加了一层转发，有额外延迟&lt;/li&gt;
&lt;li&gt;代理层可能成为单点故障&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  注册中心的关键特性
&lt;/h2&gt;

&lt;p&gt;选择注册中心时，需要关注以下几个关键特性：&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;高可用&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;注册中心本身不能有单点故障&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;一致性&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;需要保证服务列表的一致性&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;健康检查&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;能够检测实例的健康状态&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;TTL控制&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;过期服���需要及时清理&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;多租户&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;支持不同环境/团队的隔离&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  实践中的关键考量
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. 健康检查策略
&lt;/h3&gt;

&lt;p&gt;健康检查有多种方式：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;心跳&lt;/strong&gt;：实例定期发送心跳&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HTTP探测&lt;/strong&gt;：注册中心定期请求健康检查端点&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;进程检测&lt;/strong&gt;：检测进程是否存活&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;建议结合使用多种健康检查方式，提高检测的准确性。&lt;/p&gt;

&lt;h3&gt;
  
  
  2. 保护机制
&lt;/h3&gt;

&lt;p&gt;在服务启动、关闭时需要特别注意：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;启动预热&lt;/strong&gt;：新实例启动后不要立即接收大量流量，让其有个预热过程&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;优雅关闭&lt;/strong&gt;：关闭前先停止接收新请求，处理完现有请求后再退出&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;金丝雀发布&lt;/strong&gt;：先用少量流量验证新版本&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. 安全考量
&lt;/h3&gt;

&lt;p&gt;服务发现也涉及安全问题：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;注册认证&lt;/strong&gt;：只有授权的服务才能注册&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;访问控制&lt;/strong&gt;：消费者只能发现需要的服务&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;传输加密&lt;/strong&gt;：注册通信使用 TLS 加密&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  常见注册中心对比
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;注册中心&lt;/th&gt;
&lt;th&gt;类型&lt;/th&gt;
&lt;th&gt;特点&lt;/th&gt;
&lt;th&gt;适用场景&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Eureka&lt;/td&gt;
&lt;td&gt;客户端发现&lt;/td&gt;
&lt;td&gt;AP 模型，支持自我保护&lt;/td&gt;
&lt;td&gt;Spring Cloud&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Consul&lt;/td&gt;
&lt;td&gt;客户端/服务端&lt;/td&gt;
&lt;td&gt;支持多数据中心，ACL&lt;/td&gt;
&lt;td&gt;混合云环境&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;etcd&lt;/td&gt;
&lt;td&gt;服务端发现&lt;/td&gt;
&lt;td&gt;强一致性，Kubernetes 内置&lt;/td&gt;
&lt;td&gt;K8s 生态&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Zookeeper&lt;/td&gt;
&lt;td&gt;服务端发现&lt;/td&gt;
&lt;td&gt;成熟稳定，写入性能有限&lt;/td&gt;
&lt;td&gt;大规模集群&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  总结
&lt;/h2&gt;

&lt;p&gt;服务发现是微服务架构的基础设施之一。选择合适的服务发现策略需要综合考虑团队技术栈、运维复杂度、扩展性需求等因素。&lt;/p&gt;

&lt;p&gt;对于初创团队，建议从 Kubernetes DNS 开始，利用云原生能力快速构建服务发现基础设施。随着系统规模增长，再根据实际需求引入更复杂的解决方案。&lt;/p&gt;

</description>
      <category>架构</category>
      <category>微服务</category>
      <category>服务发现</category>
      <category>分布式系统</category>
    </item>
    <item>
      <title>仓储模式深度指南：构建数据访问抽象的艺术</title>
      <dc:creator>架构师小白</dc:creator>
      <pubDate>Sun, 03 May 2026 01:03:33 +0000</pubDate>
      <link>https://dev.to/tianxin/cang-chu-mo-shi-shen-du-zhi-nan-gou-jian-shu-ju-fang-wen-chou-xiang-de-yi-zhu-5f6h</link>
      <guid>https://dev.to/tianxin/cang-chu-mo-shi-shen-du-zhi-nan-gou-jian-shu-ju-fang-wen-chou-xiang-de-yi-zhu-5f6h</guid>
      <description>&lt;h1&gt;
  
  
  仓储模式深度指南：构建数据访问抽象的艺术
&lt;/h1&gt;

&lt;p&gt;在软件开发中，数据访问往往是业务逻辑与持久化层之间的桥梁。直接操作数据库代码散落在业务各处，会导致难以维护的紧耦合。仓储模式（Repository Pattern）正是为解决这一问题而生的经典架构模式。&lt;/p&gt;




&lt;h2&gt;
  
  
  什么是仓储模式？
&lt;/h2&gt;

&lt;p&gt;仓储模式是一种抽象数据访问层的模式。它在业务逻辑层与数据源之间引入了一个中间层，统一管理数据的增删改查操作，使业务层完全不关心数据来自哪里——可能是MySQL、MongoDB、Redis，甚至是外部API。&lt;/p&gt;

&lt;h2&gt;
  
  
  核心概念
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. 接口契约
&lt;/h3&gt;

&lt;p&gt;仓储模式的核心是定义统一的接口：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;abc&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ABC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;abstractmethod&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;TypeVar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Generic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;

&lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;TypeVar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;T&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Repository&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ABC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Generic&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;]):&lt;/span&gt;
    &lt;span class="nd"&gt;@abstractmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;find_by_id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;find_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. 实现解耦
&lt;/h3&gt;

&lt;p&gt;同一接口可以有多个实现：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserRepositoryMySQL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UserRepository&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;find_by_id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="n"&gt;cursor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SELECT * FROM users WHERE id = ?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,))&lt;/span&gt;
        &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetchone&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_row&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  为什么需要仓储模式？
&lt;/h2&gt;

&lt;h3&gt;
  
  
  单一职责
&lt;/h3&gt;

&lt;p&gt;业务逻辑只需关心"如何用数据"，不关心"数据从哪来"。&lt;/p&gt;

&lt;h3&gt;
  
  
  可测试性
&lt;/h3&gt;

&lt;p&gt;通过Mock仓储实现，可以在不连接数据库的情况下测试业务逻辑。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MockUserRepository&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UserRepository&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;find_by_id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  灵活切换数据源
&lt;/h3&gt;

&lt;p&gt;需要从MySQL迁移到PostgreSQL？只需要新增一个实现类，业务代码无需改动。&lt;/p&gt;

&lt;h2&gt;
  
  
  仓储模式 vs DAO
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特征&lt;/th&gt;
&lt;th&gt;仓储模式&lt;/th&gt;
&lt;th&gt;DAO&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;抽象层级&lt;/td&gt;
&lt;td&gt;领域模型&lt;/td&gt;
&lt;td&gt;数据表&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;关注点&lt;/td&gt;
&lt;td&gt;业务对象&lt;/td&gt;
&lt;td&gt;数据操作&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;粒度&lt;/td&gt;
&lt;td&gt;粗粒度&lt;/td&gt;
&lt;td&gt;细粒度&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;仓储模式更面向业务，DAO更面向数据库。实际项目中，两者常配合使用。&lt;/p&gt;

&lt;h2&gt;
  
  
  实践建议
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;一个聚合根一个仓储&lt;/strong&gt;——如Order和OrderItem属于同一个仓储&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;避免事务泄漏&lt;/strong&gt;——事务应在应用服务层管理&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;适度抽象&lt;/strong&gt;——小型项目可直接省略，过度工程反而增加复杂度&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  总结
&lt;/h2&gt;

&lt;p&gt;仓储模式是实现数据访问层抽象的利器，它让业务代码与数据源解耦，提升了系统的可维护性和可测试性。在微服务架构、DDD实践中，仓储模式仍是数据层的首选抽象方式。&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>backend</category>
      <category>python</category>
      <category>design</category>
    </item>
    <item>
      <title>分层架构深度指南：构建可维护软件的核心基石</title>
      <dc:creator>架构师小白</dc:creator>
      <pubDate>Sat, 02 May 2026 01:06:12 +0000</pubDate>
      <link>https://dev.to/tianxin/fen-ceng-jia-gou-shen-du-zhi-nan-gou-jian-ke-wei-hu-ruan-jian-de-he-xin-ji-shi-2a9</link>
      <guid>https://dev.to/tianxin/fen-ceng-jia-gou-shen-du-zhi-nan-gou-jian-ke-wei-hu-ruan-jian-de-he-xin-ji-shi-2a9</guid>
      <description>&lt;h1&gt;
  
  
  分层架构深度指南：构建可维护软件的核心基石
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;分层架构（Layered Architecture）是最经典也是最广泛使用的架构模式之一。无论是小型应用还是企业级系统，理解分层架构都能帮助你构建更清晰、可维护的代码。&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  什么是分层架构？
&lt;/h2&gt;

&lt;p&gt;分层架构将应用程序按照职责划分为多个层次，每个层次只关注自己的职责。经典的的三层架构包括：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;表现层（Presentation Layer）&lt;/strong&gt; - 负责用户界面和用户交互&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;业务逻辑层（Business Logic Layer）&lt;/strong&gt; - 负责核心业务逻辑和规则&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;数据访问层（Data Access Layer）&lt;/strong&gt; - 负责数据存储和检索&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  为什么使用分层架构？
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. 关注点分离
&lt;/h3&gt;

&lt;p&gt;每个层次只关注自己的职责，代码更容易理解和维护。&lt;/p&gt;

&lt;h3&gt;
  
  
  2. 可测试性
&lt;/h3&gt;

&lt;p&gt;业务逻辑可以在没有 UI 和数据库的情况下进行单元测试。&lt;/p&gt;

&lt;h3&gt;
  
  
  3. 可替换性
&lt;/h3&gt;

&lt;p&gt;可以替换某一层的实现而不影响其他层。例如，可以从 MySQL 切换到 PostgreSQL 而不需要修改业务逻辑。&lt;/p&gt;

&lt;h3&gt;
  
  
  4. 团队协作
&lt;/h3&gt;

&lt;p&gt;不同团队可以并行开发不同层次。&lt;/p&gt;




&lt;h2&gt;
  
  
  分层架构的演进
&lt;/h2&gt;

&lt;h3&gt;
  
  
  两层架构
&lt;/h3&gt;

&lt;p&gt;客户端 + 服务器直接通信，数据处理逻辑通常放在客户端或服务器端。&lt;/p&gt;

&lt;h3&gt;
  
  
  三层架构
&lt;/h3&gt;

&lt;p&gt;表现层 + 业务逻辑层 + 数据层，这是最经典的分层模式。&lt;/p&gt;

&lt;h3&gt;
  
  
  四层架构
&lt;/h3&gt;

&lt;p&gt;在三层基础上增加&lt;strong&gt;企业服务层（Enterprise Service Layer）&lt;/strong&gt;，用于跨业务逻辑的编排。&lt;/p&gt;

&lt;h3&gt;
  
  
  五层架构
&lt;/h3&gt;

&lt;p&gt;在四层基础上增加&lt;strong&gt;集成层（Integration Layer）&lt;/strong&gt;，用于外部系统集成。&lt;/p&gt;




&lt;h2&gt;
  
  
  实践建议
&lt;/h2&gt;

&lt;h3&gt;
  
  
  好实践
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;保持层次清晰&lt;/strong&gt; - 每个层次应该有明确的职责&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;单向依赖&lt;/strong&gt; - 只能是上层依赖下层，下层不能依赖上层&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;接口隔离&lt;/strong&gt; - 层与层之间通过接口通信，降低耦合&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;业务逻辑集中&lt;/strong&gt; - 核心业务逻辑应该在业务逻辑层，而不是表现层&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  常见错误
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;层次混乱&lt;/strong&gt; - 在表现层写业务逻辑，在业务逻辑层直接操作数据库&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;循环依赖&lt;/strong&gt; - 层次之间形成循环依赖，导致代码难以维护&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;过度分层&lt;/strong&gt; - 创建太多不必要的层次，增加复杂性&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;跳过层次&lt;/strong&gt; - 为了方便直接跨层调用，破坏分层结构&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  总结
&lt;/h2&gt;

&lt;p&gt;分层架构虽然简单，但它分而治之的核心思想是所有架构模式的基础。掌握分层架构，能够帮助你更好地理解微服务架构、整洁架构等更复杂的架构模式。&lt;/p&gt;




&lt;p&gt;&lt;em&gt;如果你觉得这篇文章有帮助，欢迎评论交流你的看法！&lt;/em&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>architecture</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>事件溯源模式深度指南：构建可追踪系统的艺术</title>
      <dc:creator>架构师小白</dc:creator>
      <pubDate>Thu, 30 Apr 2026 01:03:55 +0000</pubDate>
      <link>https://dev.to/tianxin/shi-jian-su-yuan-mo-shi-shen-du-zhi-nan-gou-jian-ke-zhui-zong-xi-tong-de-yi-zhu-2mbd</link>
      <guid>https://dev.to/tianxin/shi-jian-su-yuan-mo-shi-shen-du-zhi-nan-gou-jian-ke-zhui-zong-xi-tong-de-yi-zhu-2mbd</guid>
      <description>&lt;h1&gt;
  
  
  事件溯源模式深度指南：构建可追踪系统的艺术
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;在分布式系统和微服务架构中，如何确保数据的完整可追溯？事件溯源（Event Sourcing）提供了一种全新的思路——不仅仅存储当前状态，而是记录导致状态变更的每一个事件。本文将深入探讨事件溯源的核心概念、实现方式以及在实际项目中的应用。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  什么是事件溯源？
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;事件溯源（Event Sourcing）&lt;/strong&gt; 是一种架构模式，它不直接存储对象的当前状态，而是存储导致状态变化的一系列事件。通过重放（replay）这些事件，可以重建任何时刻的状态。&lt;/p&gt;

&lt;h3&gt;
  
  
  核心思想
&lt;/h3&gt;

&lt;p&gt;传统方式 vs 事件溯源：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;传统方式&lt;/strong&gt;：直接存储最终状态（如 &lt;code&gt;User { name: "张三", balance: 100 }&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;事件溯源&lt;/strong&gt;：存储所有变更事件（如 &lt;code&gt;UserCreated&lt;/code&gt;, &lt;code&gt;DepositMade&lt;/code&gt;, &lt;code&gt;WithdrawalMade&lt;/code&gt;）
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# 传统方式：直接存储状态
当前状态: { 账户ID: 001, 余额: 1000元 }

# 事件溯源：存储事件序列
事件1: 账户开立 → 余额: 0元
事件2: 存款1000元 → 余额: 1000元  
事件3: 取款200元 → 余额: 800元
事件4: 存款200元 → 余额: 1000元 (当前)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  事件溯源的核心优势
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. 完整的审计追踪
&lt;/h3&gt;

&lt;p&gt;每一个状态变更都有据可查，满足审计合规要求。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 事件存储示例
&lt;/span&gt;&lt;span class="n"&gt;events&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;OrderCreated&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;orderId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ORD-001&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;amount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PaymentReceived&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;orderId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ORD-001&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;amount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;OrderShipped&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;orderId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ORD-001&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;OrderDelivered&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;orderId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ORD-001&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;# 可以精确知道订单的完整生命周期
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. 时间旅行（Time Travel）
&lt;/h3&gt;

&lt;p&gt;支持任意时间点的状态回溯，无需额外存储快照。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 重放事件重建历史状态
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;replay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;events&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;until_timestamp&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;initial_state&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;events&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timestamp&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;until_timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;apply_event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;

&lt;span class="c1"&gt;# 查看三个月前的订单状态
&lt;/span&gt;&lt;span class="n"&gt;old_state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;replay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;all_events&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;three_months_ago&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. 天然支持事件驱动
&lt;/h3&gt;

&lt;p&gt;事件本身可以作为消息发布，触发其他服务。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 事件发布示例
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EventStore&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;events&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;event_bus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# 发布到消息队列
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. 解决并发冲突
&lt;/h3&gt;

&lt;p&gt;乐观锁的增强版：通过事件合并解决冲突。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 冲突解决策略
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;resolve_conflict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;local_event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;remote_event&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;local_event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;remote_event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Withdrawal&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# 两只信用卡取款，先到先得
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;local_event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;remote_event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  事件溯源的挑战与应对
&lt;/h2&gt;

&lt;h3&gt;
  
  
  挑战1：事件存储膨胀
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;问题&lt;/strong&gt;：长期运行系统的事件表可能非常大&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;解决方案&lt;/strong&gt;：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;定期创建快照（Snapshot）&lt;/li&gt;
&lt;li&gt;归档历史事件到冷存储&lt;/li&gt;
&lt;li&gt;使用压缩算法
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Snapshot&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_snapshot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;event_count&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;event_count&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="c1"&gt;# 每10000个事件创建快照
&lt;/span&gt;            &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;snapshots&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;state&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;event_count&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;event_count&lt;/span&gt;
            &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  挑战2：事件变更（Event Schema Evolution）
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;问题&lt;/strong&gt;：业务需求变化导致事件结构需要修改&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;解决方案&lt;/strong&gt;：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;版本化事件Schema&lt;/li&gt;
&lt;li&gt;实现事件转换器（Upcaster）
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 事件版本兼容
&lt;/span&gt;&lt;span class="n"&gt;V1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;OrderCreated&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;order_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;123&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;V2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;OrderCreated&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;order_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;123&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;customer_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;C001&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;upcast_v1_to_v2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;customer_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;unknown&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  挑战3：最终一致性
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;问题&lt;/strong&gt;：状态需要通过事件重放，无法立即读取&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;解决方案&lt;/strong&gt;：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;引入投影（Projection）生成读模型&lt;/li&gt;
&lt;li&gt;使用CQRS分离读写&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  事件溯源的最佳实践
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. 事件命名规范
&lt;/h3&gt;

&lt;p&gt;使用清晰的命名：&lt;code&gt;[Entity][Action](PastTense)&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 好的事件命名
&lt;/span&gt;&lt;span class="n"&gt;UserRegistered&lt;/span&gt;
&lt;span class="n"&gt;AccountActivated&lt;/span&gt;
&lt;span class="n"&gt;OrderCancelled&lt;/span&gt;
&lt;span class="n"&gt;PaymentProcessed&lt;/span&gt;

&lt;span class="c1"&gt;# 不好的命名
&lt;/span&gt;&lt;span class="n"&gt;UserAction1&lt;/span&gt;  &lt;span class="c1"&gt;# 模糊
&lt;/span&gt;&lt;span class="n"&gt;EventA&lt;/span&gt;       &lt;span class="c1"&gt;# 无意义
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. 事件设计原则
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;不可变性&lt;/strong&gt;：事件一旦创建就不能修改&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;自包含&lt;/strong&gt;：包含重建状态所需的全部信息&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;原子性&lt;/strong&gt;：每个事件对应一个原子操作&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. 技术选型建议
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;场景&lt;/th&gt;
&lt;th&gt;推荐方案&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;简单实现&lt;/td&gt;
&lt;td&gt;EventStore + MongoDB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;高性能&lt;/td&gt;
&lt;td&gt;Apache Kafka / Pulsar&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;分布式&lt;/td&gt;
&lt;td&gt;EventstoreDB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;云原生&lt;/td&gt;
&lt;td&gt;AWS DynamoDB Streams&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  事件溯源 vs CRDT
&lt;/h2&gt;

&lt;p&gt;很多同学会混淆事件溯源和CRDT（无冲突复制数据类型）：&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;事件溯源&lt;/th&gt;
&lt;th&gt;CRDT&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;同步方式&lt;/td&gt;
&lt;td&gt;重放事件&lt;/td&gt;
&lt;td&gt;合并操作&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;冲突解决&lt;/td&gt;
&lt;td&gt;业务决定&lt;/td&gt;
&lt;td&gt;自动合并&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;适用场景&lt;/td&gt;
&lt;td&gt;审计、时序&lt;/td&gt;
&lt;td&gt;协作编辑&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  总结
&lt;/h2&gt;

&lt;p&gt;事件溯源不仅仅是一种存储方式，更是一种&lt;strong&gt;思维方式的转变&lt;/strong&gt;：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;从是什么到怎么做&lt;/strong&gt;：记录变化而非状态&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;从覆盖到追加&lt;/strong&gt;：保留历史，可追溯&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;从同步到异步&lt;/strong&gt;：事件驱动，松耦合&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;适合场景：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;审计合规要求高的系统&lt;/li&gt;
&lt;li&gt;需要完整历史追溯的金融系统&lt;/li&gt;
&lt;li&gt;复杂的业务流程管理&lt;/li&gt;
&lt;li&gt;需要支持时间旅行的调试场景&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;不适合场景：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;简单的CRUD应用&lt;/li&gt;
&lt;li&gt;对延迟敏感的场景&lt;/li&gt;
&lt;li&gt;事件量巨大的物联网场景&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;下次当你需要设计一个需要可追溯的系统时，不妨考虑一下事件溯源——它可能是你最好的选择。&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;strong&gt;参考阅读&lt;/strong&gt;：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;《 Patterns of Enterprise Application Architecture 》&lt;/li&gt;
&lt;li&gt;EventstoreDB 官方文档&lt;/li&gt;
&lt;li&gt;CQRS and Event Sourcing by Martin Fowler&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>architecture</category>
      <category>design</category>
      <category>microservices</category>
      <category>coding</category>
    </item>
    <item>
      <title>适配器模式深度指南：让不兼容接口和谐共存的艺术</title>
      <dc:creator>架构师小白</dc:creator>
      <pubDate>Tue, 28 Apr 2026 01:05:06 +0000</pubDate>
      <link>https://dev.to/tianxin/gua-pei-qi-mo-shi-shen-du-zhi-nan-rang-bu-jian-rong-jie-kou-he-xie-gong-cun-de-yi-zhu-f1n</link>
      <guid>https://dev.to/tianxin/gua-pei-qi-mo-shi-shen-du-zhi-nan-rang-bu-jian-rong-jie-kou-he-xie-gong-cun-de-yi-zhu-f1n</guid>
      <description>&lt;h1&gt;
  
  
  适配器模式深度指南：让不兼容接口和谐共存的艺术
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;在软件开发中，我们经常会遇到这样的困境：现有的类库、第三方组件或遗留系统的接口与我们需要的不兼容。直接修改源代码可能不现实，甚至会带来风险。这时，适配器模式（Adapter Pattern）就是我们解决问题的利器。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  什么是适配器模式？
&lt;/h2&gt;

&lt;p&gt;适配器模式是一种&lt;strong&gt;结构型设计模式&lt;/strong&gt;，它的核心思想是：&lt;strong&gt;将一个类的接口转换成客户端所期望的另一个接口&lt;/strong&gt;。适配器让原本接口不兼容的类可以协同工作。&lt;/p&gt;

&lt;h3&gt;
  
  
  生活中的适配器
&lt;/h3&gt;

&lt;p&gt;其实适配器在我们生活中无处不在：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;手机充电器&lt;/strong&gt;：220V 交流电 → 5V 直流电（电源适配器）&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HDMI 转 VGA&lt;/strong&gt;：数字信号 → 模拟信号（视频转换器）&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;蓝牙耳机适配器&lt;/strong&gt;：让不支持蓝牙的设备也能使用蓝牙耳机&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;这些适配器的共同特点是：&lt;strong&gt;它们不改变被适配对象的本质，只是让它们能够适应新的环境&lt;/strong&gt;。&lt;/p&gt;

&lt;h2&gt;
  
  
  适配器模式的结构
&lt;/h2&gt;

&lt;p&gt;适配器模式主要有两种实现方式：&lt;/p&gt;

&lt;h3&gt;
  
  
  1. 类适配器（通过继承）
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 目标接口
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Target: Default behavior&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;# 被适配者（Adaptee）
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Adaptee&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;specific_request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.eetpadA eht fo roivaheb laicepS&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;# 类适配器
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ClassAdapter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Adaptee&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Target&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# 反转字符串来模拟适配
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ClassAdapter: (TRANSLATED) &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;specific_request&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="si"&gt;::&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. 对象适配器（通过组合）
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 对象适配器 - 更常用、更灵活
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ObjectAdapter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Target&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;adaptee&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Adaptee&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_adaptee&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;adaptee&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ObjectAdapter: (TRANSLATED) &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_adaptee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;specific_request&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="si"&gt;::&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  实战案例
&lt;/h2&gt;

&lt;h3&gt;
  
  
  案例一：集成第三方支付系统
&lt;/h3&gt;

&lt;p&gt;假设我们定义了一个统一的支付接口：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;abc&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ABC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;abstractmethod&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PaymentGateway&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ABC&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nd"&gt;@abstractmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;pay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;

    &lt;span class="nd"&gt;@abstractmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;refund&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;transaction_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;现在需要集成一个旧的第三方支付系统：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LegacyPaymentSystem&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;make_payment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount_cents&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# 旧系统使用分作为单位
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;TXN-&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;amount_cents&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;-&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;currency&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process_refund&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;

&lt;span class="c1"&gt;# 创建适配器
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LegacyPaymentAdapter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PaymentGateway&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_legacy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LegacyPaymentSystem&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;pay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# 转换：元 → 分
&lt;/span&gt;        &lt;span class="n"&gt;amount_cents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;transaction_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_legacy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;make_payment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount_cents&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CNY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;success&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;transaction_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;transaction_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;amount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;refund&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;transaction_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# 提取订单信息并退款
&lt;/span&gt;        &lt;span class="n"&gt;success&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_legacy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;process_refund&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;transaction_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;success&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;success&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  案例二：数据格式转换
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;xml.etree&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ElementTree&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;ET&lt;/span&gt;

&lt;span class="c1"&gt;# 旧的 XML 数据源
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;XMLDataSource&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;?xml version=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1.0&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;?&amp;gt;
        &amp;lt;user&amp;gt;
            &amp;lt;name&amp;gt;张三&amp;lt;/name&amp;gt;
            &amp;lt;email&amp;gt;zhangsan@example.com&amp;lt;/email&amp;gt;
        &amp;lt;/user&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

&lt;span class="c1"&gt;# 目标接口：JSON 格式
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;JSONDataSource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ABC&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nd"&gt;@abstractmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_json_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="c1"&gt;# XML 转 JSON 适配器
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;XMLToJSONAdapter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;JSONDataSource&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;xml_source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;XMLDataSource&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_xml_source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;xml_source&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_json_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;xml_str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_xml_source&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_data&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ET&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromstring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;xml_str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;email&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;email&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  适配器模式的优缺点
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ✅ 优点
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;单一职责原则&lt;/strong&gt;：将接口转换逻辑分离到适配器中&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;开闭原则&lt;/strong&gt;：在不修改原有代码的情况下集成新组件&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;提高复用性&lt;/strong&gt;：让现有的类能够适应新的需求&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;解耦&lt;/strong&gt;：客户端与具体实现解耦&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  ❌ 缺点
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;增加复杂性&lt;/strong&gt;：引入额外的适配器层&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;性能开销&lt;/strong&gt;：每次调用都有转换成本&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;过度使用风险&lt;/strong&gt;：不要滥用适配器，优先考虑重构接口&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  适配器 vs 装饰器 vs 桥接模式
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;模式&lt;/th&gt;
&lt;th&gt;目的&lt;/th&gt;
&lt;th&gt;关系&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;适配器&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;让不兼容的接口变得兼容&lt;/td&gt;
&lt;td&gt;转换已有接口&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;装饰器&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;动态添加职责&lt;/td&gt;
&lt;td&gt;增强功能&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;桥接&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;分离抽象与实现&lt;/td&gt;
&lt;td&gt;解耦维度&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  最佳实践
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;优先使用对象适配器&lt;/strong&gt;：通过组合实现，更灵活&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;适配器应该是透明的&lt;/strong&gt;：客户端不应该感知适配器的存在&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;考虑使用依赖注入&lt;/strong&gt;：让适配器更容易测试&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;不要滥用&lt;/strong&gt;：如果可以修改接口，优先重构而非添加适配器&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  总结
&lt;/h2&gt;

&lt;p&gt;适配器模式是解决接口不兼容问题的经典方案，它就像现实世界中的各种转换器，让不同的系统能够协同工作。在实际开发中，当我们需要在不修改现有代码的前提下集成新的组件或服务时，适配器模式是一个非常实用的选择。&lt;/p&gt;

&lt;p&gt;记住：&lt;strong&gt;适配器是桥梁，让不兼容变成可能&lt;/strong&gt;。&lt;/p&gt;




&lt;p&gt;&lt;em&gt;本文是软件架构系列文章的一部分，欢迎关注更多设计模式的深度指南。&lt;/em&gt;&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>python</category>
      <category>coding</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Strangler Fig 模式：渐进式遗留系统迁移的艺术</title>
      <dc:creator>架构师小白</dc:creator>
      <pubDate>Sun, 26 Apr 2026 01:03:29 +0000</pubDate>
      <link>https://dev.to/tianxin/strangler-fig-mo-shi-jian-jin-shi-yi-liu-xi-tong-qian-yi-de-yi-zhu-13n</link>
      <guid>https://dev.to/tianxin/strangler-fig-mo-shi-jian-jin-shi-yi-liu-xi-tong-qian-yi-de-yi-zhu-13n</guid>
      <description>&lt;h1&gt;
  
  
  Strangler Fig 模式：渐进式遗留系统迁移的艺术
&lt;/h1&gt;

&lt;p&gt;在软件工程的漫长历史中，每个开发者都会面临一个令人头疼的问题：如何处理一个庞大的遗留系统？&lt;/p&gt;

&lt;p&gt;无论是老旧的单体应用、过时的技术栈，还是充满技术债务的代码库，迁移都是一项充满风险的任务。而 &lt;strong&gt;Strangler Fig 模式&lt;/strong&gt;（扼杀榕模式）正是解决这一问题的优雅方案。&lt;/p&gt;




&lt;h2&gt;
  
  
  什么是 Strangler Fig 模式？
&lt;/h2&gt;

&lt;p&gt;Strangler Fig（榕树）是一种热带植物，它的种子可以在其他树木上发芽，随着根系生长，最终会"绞杀"并取代原来的树木。软件架构中的 Strangler Fig 模式正是借鉴了这一自然现象：&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;逐步将一个遗留系统替换为现代化系统，而不是一次性重写。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  核心思想
&lt;/h2&gt;

&lt;p&gt;传统的迁移方式有两种极端：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Big Bang 重写&lt;/strong&gt; —— 一次性重写整个系统&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;风险极高：需要长时间闭网，新旧系统功能差异大&lt;/li&gt;
&lt;li&gt;业务停摆：用户和业务团队需要等待很长时间&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;完全保留遗留系统&lt;/strong&gt; —— 继续维护老系统&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;技术债务累积：维护成本越来越高&lt;/li&gt;
&lt;li&gt;人才流失：熟悉老技术的人越来越少&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Strangler Fig 模式给出了第三种路：&lt;strong&gt;渐进式迁移&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  实施步骤
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. 识别边界
&lt;/h3&gt;

&lt;p&gt;首先，识别遗留系统的边界和模块。将系统拆分为：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;核心业务逻辑&lt;/li&gt;
&lt;li&gt;周边功能（认证、报表、通知等）&lt;/li&gt;
&lt;li&gt;数据存储层&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. 建立代理（Facade）
&lt;/h3&gt;

&lt;p&gt;在遗留系统前面部署一个&lt;strong&gt;代理层&lt;/strong&gt;，负责：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;请求路由：新功能 → 新系统，传统功能 → 遗留系统&lt;/li&gt;
&lt;li&gt;协议转换：统一外部调用接口&lt;/li&gt;
&lt;li&gt;数据聚合：合并新旧系统的返回结果&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. 逐个迁移
&lt;/h3&gt;

&lt;p&gt;每次只迁移一个功能模块：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;在代理层添加新功能的路由&lt;/li&gt;
&lt;li&gt;在新系统中实现该功能&lt;/li&gt;
&lt;li&gt;验证新功能工作正常&lt;/li&gt;
&lt;li&gt;关闭遗留系统中对应的功能&lt;/li&gt;
&lt;li&gt;重复下一个功能&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  4. 移除遗留
&lt;/h3&gt;

&lt;p&gt;当所有功能都迁移完成后，移除遗留系统和代理层。&lt;/p&gt;




&lt;h2&gt;
  
  
  实际应用场景
&lt;/h2&gt;

&lt;h3&gt;
  
  
  场景一：前端框架迁移
&lt;/h3&gt;

&lt;p&gt;将 jQuery + Backbone 的前端迁移到 React + TypeScript：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;第一步：使用微前端框架（如 Single-SPA）同时运行新旧前端&lt;/li&gt;
&lt;li&gt;第二步：逐个页面迁移到新框架&lt;/li&gt;
&lt;li&gt;第三步：旧页面逐渐萎缩，直到完全移除&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  场景二：后端服务拆分
&lt;/h3&gt;

&lt;p&gt;将 Java EE 单体应用拆分为 Go 微服务：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;使用 API 网关作为代理&lt;/li&gt;
&lt;li&gt;逐步将 API 迁移到新服务&lt;/li&gt;
&lt;li&gt;最终停止旧应用的相应模块&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  场景三：数据库迁移
&lt;/h3&gt;

&lt;p&gt;从 Oracle 迁移到 PostgreSQL：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;部署双写机制（新旧数据库同时写入）&lt;/li&gt;
&lt;li&gt;逐步将读请求切换到新数据库&lt;/li&gt;
&lt;li&gt;验证数据一致性后移除双写&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  关键成功因素
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. 增量交付
&lt;/h3&gt;

&lt;p&gt;每个迁移周期要足够短（1-4周），保持业务价值的持续交付。&lt;/p&gt;

&lt;h3&gt;
  
  
  2. 功能对等
&lt;/h3&gt;

&lt;p&gt;新功能必须完全覆盖旧功能的所有行为，包括边界情况和错误处理。&lt;/p&gt;

&lt;h3&gt;
  
  
  3. 数据一致性
&lt;/h3&gt;

&lt;p&gt;在双写期间，必须保证数据一致性，使用以下策略：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;事件溯源：记录所有变更事件&lt;/li&gt;
&lt;li&gt;影子模式：新旧系统同时响应请求，比较结果&lt;/li&gt;
&lt;li&gt;逐步切换：先切换读，再切换写&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. 回滚能力
&lt;/h3&gt;

&lt;p&gt;每个迁移步骤都必须能够快速回滚，保持业务连续性。&lt;/p&gt;

&lt;h3&gt;
  
  
  5. 监控告警
&lt;/h3&gt;

&lt;p&gt;建立完善的监控体系，及时发现迁移过程中的问题。&lt;/p&gt;




&lt;h2&gt;
  
  
  优势与挑战
&lt;/h2&gt;

&lt;h3&gt;
  
  
  优势
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;降低风险&lt;/strong&gt;：每次只迁移一小部分&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;持续交付&lt;/strong&gt;：业务功能不中断&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;团队学习&lt;/strong&gt;：团队在新系统中学习新技术&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;业务验证&lt;/strong&gt;：可以随时收集用户反馈&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  挑战
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;需要同时维护两套系统&lt;/li&gt;
&lt;li&gt;双写功能会带来性能开销&lt;/li&gt;
&lt;li&gt;数据一致性需要额外处理&lt;/li&gt;
&lt;li&gt;需要深入理解遗留系统的业务逻辑&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  总结
&lt;/h2&gt;

&lt;p&gt;Strangler Fig 模式是处理遗留系统迁移的终极利器。它教会我们：&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;不要试图一口吃成一个胖子，而是要像榕树一样，慢慢地、稳健地取代旧系统。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;在技术快速迭代的今天，每个系统都可能在未来成为遗留系统。掌握这种渐进式迁移的艺术，才能让我们的系统永远保持活力。&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>systems</category>
      <category>migration</category>
    </item>
    <item>
      <title>SOLID原则：构建可维护软件的五大黄金法则</title>
      <dc:creator>架构师小白</dc:creator>
      <pubDate>Sat, 25 Apr 2026 01:06:26 +0000</pubDate>
      <link>https://dev.to/tianxin/solidyuan-ze-gou-jian-ke-wei-hu-ruan-jian-de-wu-da-huang-jin-fa-ze-kdn</link>
      <guid>https://dev.to/tianxin/solidyuan-ze-gou-jian-ke-wei-hu-ruan-jian-de-wu-da-huang-jin-fa-ze-kdn</guid>
      <description>&lt;h1&gt;
  
  
  SOLID原则：构建可维护软件的五大黄金法则
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 SOLID原则是面向对象设计的五大核心原则，掌握它们让你的代码更易维护、更易扩展&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  写在前面
&lt;/h2&gt;

&lt;p&gt;你是否遇到过这样的情况：代码写着写着就变成了"面条式"代码，牵一发而动全身？或者明明只是修改一个小功能，却要改遍整个项目？这很可能是因为代码违背了一些基本的软件设计原则。&lt;/p&gt;

&lt;p&gt;今天我要和你分享软件工程领域最重要的五大设计原则——&lt;strong&gt;SOLID原则&lt;/strong&gt;。这五个原则由Robert C. Martin（也就是著名的"Bob大叔"）提出，至今仍是软件架构领域的基石。&lt;/p&gt;




&lt;h2&gt;
  
  
  S — 单一职责原则（Single Responsibility Principle）
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;一个类应该只有一个变化的原因&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  什么是"变化的原因"？
&lt;/h3&gt;

&lt;p&gt;想象你正在写一个用户管理的模块：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ❌ 违反单一职责原则
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;save_to_database&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# 保存用户到数据库
&lt;/span&gt;        &lt;span class="k"&gt;pass&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;send_welcome_email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# 发送欢迎邮件
&lt;/span&gt;        &lt;span class="k"&gt;pass&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;generate_report&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# 生成用户报告
&lt;/span&gt;        &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;这个类承担了太多职责：数据存储、邮件发送、报表生成。当任何一方面需求变化时，都需要修改这个类。&lt;/p&gt;

&lt;h3&gt;
  
  
  正确的做法
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ✅ 单一职责，各司其职
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserRepository&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EmailService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;send_welcome&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserReportGenerator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  好处
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;更易理解&lt;/strong&gt;：每个类职责明确&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;更易测试&lt;/strong&gt;：每个类可以独立测试&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;更易修改&lt;/strong&gt;：变化只会影响特定类&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  O — 开闭原则（Open-Closed Principle）
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;软件实体应该对扩展开放，对修改关闭&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  核心思想
&lt;/h3&gt;

&lt;p&gt;想象你在开发一个支付系统：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ❌ 违反开闭原则
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PaymentProcessor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process_payment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;payment_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;payment_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;alipay&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="c1"&gt;# 处理支付宝
&lt;/span&gt;            &lt;span class="k"&gt;pass&lt;/span&gt;
        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;payment_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;wechat&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="c1"&gt;# 处理微信支付
&lt;/span&gt;            &lt;span class="k"&gt;pass&lt;/span&gt;
        &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;payment_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bank_card&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="c1"&gt;# 处理银行卡
&lt;/span&gt;            &lt;span class="k"&gt;pass&lt;/span&gt;
        &lt;span class="c1"&gt;# 每增加一种支付方式，都需要修改这个类！
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  正确的做法
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ✅ 对扩展开放
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;abc&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ABC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;abstractmethod&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PaymentMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ABC&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nd"&gt;@abstractmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;pay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Alipay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PaymentMethod&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;pay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;使用支付宝支付 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; 元&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WechatPay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PaymentMethod&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;pay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;使用微信支付 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; 元&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PaymentProcessor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;payment_method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;PaymentMethod&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;payment_method&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 新增支付方式时，无需修改现有代码
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BankCard&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PaymentMethod&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;pay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;使用银行卡支付 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; 元&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  好处
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;新功能可以通过添加新代码实现&lt;/li&gt;
&lt;li&gt;现有代码保持稳定&lt;/li&gt;
&lt;li&gt;系统更易扩展和维护&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  L — 里氏替换原则（Liskov Substitution Principle）
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;子类必须能够替换其父类而不改变程序正确性&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  理解里氏替换
&lt;/h3&gt;

&lt;p&gt;这个原则有点抽象，但非常重要。简单来说：&lt;strong&gt;任何父类出现的地方，都可以用子类无缝替换&lt;/strong&gt;。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ❌ 违反里氏替换原则
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Rectangle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;area&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Square&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Rectangle&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;side&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;super&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;side&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;side&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;set_width&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;  &lt;span class="c1"&gt;# 正方形特殊处理
&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;set_height&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;calculate_area&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rectangle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Rectangle&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;rectangle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_width&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;rectangle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_height&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;rectangle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;area&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c1"&gt;# 期望返回20
&lt;/span&gt;
&lt;span class="c1"&gt;# 测试
&lt;/span&gt;&lt;span class="n"&gt;square&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Square&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;calculate_area&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;square&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  &lt;span class="c1"&gt;# 返回16，不是20！违反了预期
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  正确的做法
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ✅ 遵循里氏替换原则
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Shape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ABC&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nd"&gt;@abstractmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;area&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Rectangle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Shape&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_width&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_height&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;area&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_width&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_height&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Square&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Shape&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;side&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_side&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;side&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;area&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_side&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_side&lt;/span&gt;

&lt;span class="c1"&gt;# 现在可以安全替换
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;calculate_total_area&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;shapes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Shape&lt;/span&gt;&lt;span class="p"&gt;]):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;area&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;shapes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  I — 接口隔离原则（Interface Segregation Principle）
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;不应该强迫客户依赖它不使用的方法&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  问题所在
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ❌ 违反接口隔离原则
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Machine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ABC&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nd"&gt;@abstractmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;

    &lt;span class="nd"&gt;@abstractmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;scan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;

    &lt;span class="nd"&gt;@abstractmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fax&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AllInOnePrinter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Machine&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;pass&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;scan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;pass&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fax&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SimplePrinter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Machine&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;pass&lt;/span&gt;
    &lt;span class="c1"&gt;# 强迫实现不需要的功能！
&lt;/span&gt;    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;scan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; 
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;NotImplementedError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;扫描不支持&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fax&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; 
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;NotImplementedError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;传真不支持&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  正确的做法
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ✅ 接口隔离
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Printer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ABC&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nd"&gt;@abstractmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Scanner&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ABC&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nd"&gt;@abstractmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;scan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FaxMachine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ABC&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nd"&gt;@abstractmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fax&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="c1"&gt;# 按需组合
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AllInOneMachine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Printer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Scanner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FaxMachine&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;pass&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;scan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;pass&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fax&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SimplePrinter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Printer&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  D — 依赖倒置原则（Dependency Inversion Principle）
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;高层模块不应该依赖低层模块，两者都应该依赖抽象&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  错误示范
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ❌ 违反依赖倒置原则
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MySQLDatabase&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;连接MySQL数据库&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;执行SQL: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;database&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MySQLDatabase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c1"&gt;# 强耦合！
&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SELECT * FROM users WHERE id=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  正确的做法
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ✅ 依赖抽象
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;abc&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ABC&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Database&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ABC&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nd"&gt;@abstractmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;

    &lt;span class="nd"&gt;@abstractmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MySQLDatabase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Database&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;连接MySQL数据库&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;执行SQL: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PostgreSQLDatabase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Database&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;连接PostgreSQL数据库&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;执行SQL: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;database&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Database&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;  &lt;span class="c1"&gt;# 依赖抽象，不依赖具体
&lt;/span&gt;        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;database&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;database&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SELECT * FROM users WHERE id=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 轻松切换数据库
&lt;/span&gt;&lt;span class="n"&gt;mysql_service&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;UserService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MySQLDatabase&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="n"&gt;postgres_service&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;UserService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;PostgreSQLDatabase&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  总结
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;原则&lt;/th&gt;
&lt;th&gt;核心思想&lt;/th&gt;
&lt;th&gt;好处&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;S&lt;/strong&gt; 单一职责&lt;/td&gt;
&lt;td&gt;一个类只做一件事&lt;/td&gt;
&lt;td&gt;易维护、易测试&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;O&lt;/strong&gt; 开闭原则&lt;/td&gt;
&lt;td&gt;对扩展开放，对修改关闭&lt;/td&gt;
&lt;td&gt;易扩展、稳定&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;L&lt;/strong&gt; 里氏替换&lt;/td&gt;
&lt;td&gt;子类可替换父类&lt;/td&gt;
&lt;td&gt;正确性保证&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;I&lt;/strong&gt; 接口隔离&lt;/td&gt;
&lt;td&gt;按需使用接口&lt;/td&gt;
&lt;td&gt;精简依赖&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;D&lt;/strong&gt; 依赖倒置&lt;/td&gt;
&lt;td&gt;依赖抽象而非具体&lt;/td&gt;
&lt;td&gt;解耦、可替换&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  写在最后
&lt;/h3&gt;

&lt;p&gt;SOLID原则不是教条，而是&lt;strong&gt;经过实践验证的指导方针&lt;/strong&gt;。在实际项目中，不需要死板地追求完美遵循每一个原则，而是要理解背后的思想，根据具体场景做出合理的权衡。&lt;/p&gt;

&lt;p&gt;好的架构是演化出来的，而不是一步到位的。从今天开始，在你的代码中有意识地思考这些原则，你会发现代码质量在悄悄提升！&lt;/p&gt;




&lt;p&gt;💬 &lt;strong&gt;你在项目中遇到过哪些因为违反SOLID原则导致的问题？欢迎在评论区分享！&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>software</category>
      <category>architecture</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>装饰器模式深度指南：让对象能力动态扩展的艺术</title>
      <dc:creator>架构师小白</dc:creator>
      <pubDate>Fri, 24 Apr 2026 01:04:23 +0000</pubDate>
      <link>https://dev.to/tianxin/zhuang-shi-qi-mo-shi-shen-du-zhi-nan-rang-dui-xiang-neng-li-dong-tai-kuo-zhan-de-yi-zhu-5175</link>
      <guid>https://dev.to/tianxin/zhuang-shi-qi-mo-shi-shen-du-zhi-nan-rang-dui-xiang-neng-li-dong-tai-kuo-zhan-de-yi-zhu-5175</guid>
      <description>&lt;h1&gt;
  
  
  装饰器模式深度指南：让对象能力动态扩展的艺术
&lt;/h1&gt;

&lt;h2&gt;
  
  
  引言
&lt;/h2&gt;

&lt;p&gt;在软件开发的日常中，我们经常遇到这样的需求：需要为某个对象添加新的功能，但又不希望修改原有的类结构。传统的做法是通过继承子类来扩展功能，但这种方式会导致类爆炸问题——每增加一种功能组合，就需要创建一个新的子类。&lt;/p&gt;

&lt;p&gt;装饰器模式（Decorator Pattern）提供了一种灵活的替代方案：它允许在运行时动态地给对象添加额外的功能，相比继承更加灵活且易于扩展。本文将深入探讨装饰器模式的原理、实现方式以及在实际开发中的应用。&lt;/p&gt;




&lt;h2&gt;
  
  
  什么是装饰器模式？
&lt;/h2&gt;

&lt;p&gt;装饰器模式是一种结构型设计模式，它允许通过将对象包装在装饰器对象中来动态地给对象添加额外的能力。这种模式比通过继承来扩展功能更加灵活，因为可以在运行时决定需要添加哪些功能。&lt;/p&gt;

&lt;h3&gt;
  
  
  核心思想
&lt;/h3&gt;

&lt;p&gt;装饰器模式的核心思想可以概括为：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;包装而非继承&lt;/strong&gt;：不通过创建子类来扩展功能，而是将原始对象包装在一个装饰器中&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;动态组合&lt;/strong&gt;：可以在运行时决定需要添加哪些装饰器，实现功能的动态组合&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;单个类替代多个子类&lt;/strong&gt;：用多个小的装饰器类替代大量可能的功能组合子类&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  装饰器模式的结构
&lt;/h2&gt;

&lt;h3&gt;
  
  
  组成元素
&lt;/h3&gt;

&lt;p&gt;装饰器模式由以下几个核心组件构成：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;组件接口（Component）&lt;/strong&gt;：定义对象应该具有的基本行为&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;具体组件（Concrete Component）&lt;/strong&gt;：实现组件接口的对象，是可以被装饰的基本对象&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;装饰器基类（Decorator）&lt;/strong&gt;：持有一个组件实例的引用，并实现了组件接口&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;具体装饰器（Concrete Decorator）&lt;/strong&gt;：为组件添加新的功能&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  类图关系
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌──────────────────┐        ┌──────────────────┐
│   &amp;lt;&amp;lt;interface&amp;gt;&amp;gt;  │        │     Decorator    │
│    Component      │────────│                  │
├──────────────────┤        ├──────────────────┤
│ + operation()    │        │ - component      │
└──────────────────┘        │ + operation()    │
        ▲                    └──────────────────┘
        │                           ▲
        │                           │
        │                ┌──────────┴──────────┐
        │                │                         │
┌──────────────────┐  ┌──────────────────────────┐
│ConcreteComponent│  │  ConcreteDecorator       │
├──────────────────┤  ├──────────────────────────┤
│ + operation()    │  │ + operation()           │
└──────────────────┘  │   (调用component同时添加新功能)│
                      └──────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Python 实现示例
&lt;/h2&gt;

&lt;p&gt;让我们通过一个实际的例子来理解装饰器模式的实现。假设我们需要构建一个咖啡订购系统：&lt;/p&gt;

&lt;h3&gt;
  
  
  基础版本（不使用装饰器）
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;abc&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ABC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;abstractmethod&lt;/span&gt;

&lt;span class="c1"&gt;# 组件接口
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Coffee&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ABC&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nd"&gt;@abstractmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_cost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;

    &lt;span class="nd"&gt;@abstractmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_description&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="c1"&gt;# 具体组件
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SimpleCoffee&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Coffee&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_cost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mf"&gt;10.0&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_description&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Simple Coffee&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  装饰器实现
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 装饰器基类
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CoffeeDecorator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Coffee&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;coffee&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Coffee&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_coffee&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;coffee&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_cost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_coffee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_cost&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_description&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_coffee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_description&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# 具体装饰器 - 牛奶
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MilkDecorator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CoffeeDecorator&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_cost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_coffee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_cost&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_description&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_coffee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_description&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;, Milk&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;# 具体装饰器 - 糖
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SugarDecorator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CoffeeDecorator&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_cost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_coffee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_cost&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_description&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_coffee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_description&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;, Sugar&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;# 具体装饰器 - 奶油
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WhipDecorator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CoffeeDecorator&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_cost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_coffee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_cost&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;3.0&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_description&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_coffee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_description&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;, Whipped Cream&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  使用示例
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 基础咖啡
&lt;/span&gt;&lt;span class="n"&gt;coffee&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SimpleCoffee&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;coffee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_description&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: $&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;coffee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_cost&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# 输出: Simple Coffee: $10.0
&lt;/span&gt;
&lt;span class="c1"&gt;# 咖啡 + 牛奶
&lt;/span&gt;&lt;span class="n"&gt;coffee_with_milk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MilkDecorator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SimpleCoffee&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;coffee_with_milk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_description&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: $&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;coffee_with_milk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_cost&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# 输出: Simple Coffee, Milk: $12.0
&lt;/span&gt;
&lt;span class="c1"&gt;# 咖啡 + 牛奶 + 糖 + 奶油
&lt;/span&gt;&lt;span class="n"&gt;rich_coffee&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;WhipDecorator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nc"&gt;SugarDecorator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nc"&gt;MilkDecorator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SimpleCoffee&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;rich_coffee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_description&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: $&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;rich_coffee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_cost&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# 输出: Simple Coffee, Milk, Sugar, Whipped Cream: $16.0
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Java 实现示例
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 组件接口&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;Coffee&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="nf"&gt;getCost&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getDescription&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// 具体组件&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SimpleCoffee&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Coffee&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="nf"&gt;getCost&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mf"&gt;10.0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getDescription&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Simple Coffee"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// 装饰器基类&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CoffeeDecorator&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Coffee&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="nc"&gt;Coffee&lt;/span&gt; &lt;span class="n"&gt;coffee&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;CoffeeDecorator&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Coffee&lt;/span&gt; &lt;span class="n"&gt;coffee&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;coffee&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;coffee&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="nf"&gt;getCost&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;coffee&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getCost&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getDescription&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;coffee&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getDescription&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// 具体装饰器 - 牛奶&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MilkDecorator&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;CoffeeDecorator&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;MilkDecorator&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Coffee&lt;/span&gt; &lt;span class="n"&gt;coffee&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;super&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;coffee&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="nf"&gt;getCost&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;coffee&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getCost&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getDescription&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;coffee&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getDescription&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;", Milk"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  装饰器模式 vs 继承
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;继承&lt;/th&gt;
&lt;th&gt;装饰器&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;扩展时机&lt;/td&gt;
&lt;td&gt;编译时&lt;/td&gt;
&lt;td&gt;运行时&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;类数量&lt;/td&gt;
&lt;td&gt;可能爆炸&lt;/td&gt;
&lt;td&gt;线性增长&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;功能组合&lt;/td&gt;
&lt;td&gt;固定&lt;/td&gt;
&lt;td&gt;可动态组合&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;修改原有类&lt;/td&gt;
&lt;td&gt;需要&lt;/td&gt;
&lt;td&gt;不需要&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;代码复用&lt;/td&gt;
&lt;td&gt;一般&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  继承方式的问题
&lt;/h3&gt;

&lt;p&gt;如果使用继承来实现咖啡系统：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 每个组合都需要一个类
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CoffeeWithMilk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Coffee&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CoffeeWithSugar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Coffee&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CoffeeWithMilkAndSugar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Coffee&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CoffeeWithMilkAndWhip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Coffee&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;span class="c1"&gt;# ... 组合数量呈指数增长
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;当有 n 种配料时，需要 2^n 个子类，这就是"类爆炸"问题。&lt;/p&gt;




&lt;h2&gt;
  
  
  装饰器模式的实际应用
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Java I/O 类库
&lt;/h3&gt;

&lt;p&gt;Java 的 I/O 类库是装饰器模式最著名的应用之一：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 基础组件&lt;/span&gt;
&lt;span class="nc"&gt;InputStream&lt;/span&gt; &lt;span class="n"&gt;inputStream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FileInputStream&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"file.txt"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// 装饰器 - 添加缓冲功能&lt;/span&gt;
&lt;span class="nc"&gt;BufferedInputStream&lt;/span&gt; &lt;span class="n"&gt;bufferedStream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;BufferedInputStream&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inputStream&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// 装饰器 - 添加行号功能&lt;/span&gt;
&lt;span class="nc"&gt;LineNumberInputStream&lt;/span&gt; &lt;span class="n"&gt;lineNumberStream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;LineNumberInputStream&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bufferedStream&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. 缓存层
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CacheDecorator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Cache&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Cache&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ttl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3600&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_cache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cache&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_ttl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ttl&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  装饰器模式的优缺点
&lt;/h2&gt;

&lt;h3&gt;
  
  
  优点
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;灵活性高&lt;/strong&gt;：可以在运行时添加或移除功能&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;避免类爆炸&lt;/strong&gt;：用多个小类替代大量子类&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;单一职责&lt;/strong&gt;：每个装饰器只负责一个功能&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;可组合性&lt;/strong&gt;：可以自由组合装饰器&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;符合开闭原则&lt;/strong&gt;：扩展而非修改&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  缺点
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;调试困难&lt;/strong&gt;：多层包装使得调试复杂&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;初始化代码复杂&lt;/strong&gt;：需要构建长链&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;可能引入过多小类&lt;/strong&gt;：如果装饰器设计不当&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;顺序敏感&lt;/strong&gt;：装饰器的顺序影响最终结果&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  使用注意事项
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. 保持装饰器顺序正确
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 注意：装饰器顺序可能影响结果
&lt;/span&gt;&lt;span class="n"&gt;coffee&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SugarDecorator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MilkDecorator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SimpleCoffee&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. 使用工厂方法简化创建
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CoffeeFactory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nd"&gt;@staticmethod&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_latte&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;WhipDecorator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MilkDecorator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SimpleCoffee&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. 考虑性能影响
&lt;/h3&gt;

&lt;p&gt;多层装饰器可能带来性能开销，在性能敏感的场景需要评估。&lt;/p&gt;




&lt;h2&gt;
  
  
  总结
&lt;/h2&gt;

&lt;p&gt;装饰器模式是一种强大的设计模式，它提供了一种灵活的扩展对象功能的方式。通过本文的学习，你应该能够理解装饰器模式的核心原理，并实现基本的装饰器结构。&lt;/p&gt;

&lt;p&gt;相比继承，装饰器模式提供了更高的灵活性和可维护性，是每个开发者都应该掌握的重要技能。&lt;/p&gt;




&lt;h2&gt;
  
  
  参考资料
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;《设计模式：可复用面向对象软件的基础》- Erich Gamma 等&lt;/li&gt;
&lt;li&gt;《Head First Design Patterns》- Eric Freeman 等&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>designpatterns</category>
      <category>python</category>
      <category>java</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Saga模式深度指南：分布式事务的协调艺术</title>
      <dc:creator>架构师小白</dc:creator>
      <pubDate>Thu, 23 Apr 2026 01:06:02 +0000</pubDate>
      <link>https://dev.to/tianxin/sagamo-shi-shen-du-zhi-nan-fen-bu-shi-shi-wu-de-xie-diao-yi-zhu-71a</link>
      <guid>https://dev.to/tianxin/sagamo-shi-shen-du-zhi-nan-fen-bu-shi-shi-wu-de-xie-diao-yi-zhu-71a</guid>
      <description>&lt;h1&gt;
  
  
  Saga模式深度指南：分布式事务的协调艺术
&lt;/h1&gt;

&lt;p&gt;在微服务架构中，分布式事务是一个永恒的挑战。当一个业务操作跨越多个服务时，如何保证数据的一致性？传统的事务机制（如两阶段提交）在分布式环境中往往不切实际。这时，&lt;strong&gt;Saga模式&lt;/strong&gt;应运而生，成为处理分布式事务的主流方案。&lt;/p&gt;

&lt;h2&gt;
  
  
  什么是Saga模式？
&lt;/h2&gt;

&lt;p&gt;Saga模式将一个长期事务拆分为多个&lt;strong&gt;本地事务&lt;/strong&gt;，每个服务负责自己的本地事务。各个服务通过&lt;strong&gt;消息队列&lt;/strong&gt;或&lt;strong&gt;事件流&lt;/strong&gt;进行通信，共同完成一个完整的业务操作。&lt;/p&gt;

&lt;p&gt;与传统的ACID事务不同，Saga采用&lt;strong&gt;最终一致性&lt;/strong&gt;的策略：允许子系统在中间状态短暂不一致，但通过补偿机制最终达到一致状态。&lt;/p&gt;

&lt;h2&gt;
  
  
  Saga的两种实现方式
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. 编排式（Choreography）
&lt;/h3&gt;

&lt;p&gt;各服务通过发布/订阅事件来协调工作。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;优点&lt;/strong&gt;：简单、去中心化&lt;br&gt;&lt;br&gt;
&lt;strong&gt;缺点&lt;/strong&gt;：容易形成循环依赖，事务复杂时难以追踪&lt;/p&gt;
&lt;h3&gt;
  
  
  2. 指挥式（Orchestration）
&lt;/h3&gt;

&lt;p&gt;由一个中央协调器（Orchestrator）统一调度各服务。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;优点&lt;/strong&gt;：清晰可控、易于调试&lt;br&gt;&lt;br&gt;
&lt;strong&gt;缺点&lt;/strong&gt;：协调器可能成为单点故障&lt;/p&gt;
&lt;h2&gt;
  
  
  补偿机制： Saga的核心
&lt;/h2&gt;

&lt;p&gt;Saga的精髓在于&lt;strong&gt;补偿&lt;/strong&gt;。当某个步骤失败时，必须&lt;strong&gt;回滚&lt;/strong&gt;之前已完成的操作。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 伪代码示例
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_orderSaga&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;order_service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;inventory_service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reserve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;payment_service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;charge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;shipping_service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ship&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;shipping_service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cancel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;payment_service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;refund&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;inventory_service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;release&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;order_service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cancel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Saga vs 两阶段提交
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特性&lt;/th&gt;
&lt;th&gt;Saga&lt;/th&gt;
&lt;th&gt;2PC&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;阻塞性&lt;/td&gt;
&lt;td&gt;非阻塞&lt;/td&gt;
&lt;td&gt;阻塞&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;性能&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;td&gt;低&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;一致性&lt;/td&gt;
&lt;td&gt;最终一致&lt;/td&gt;
&lt;td&gt;强一致&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;复杂度&lt;/td&gt;
&lt;td&gt;中等&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;适用场景&lt;/td&gt;
&lt;td&gt;跨服务长事务&lt;/td&gt;
&lt;td&gt;短小事务&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  实践建议
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;幂等性设计&lt;/strong&gt;：确保每个操作可以安全重试&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;超时机制&lt;/strong&gt;：设置合理的超时时间，避免无限等待&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;监控告警&lt;/strong&gt;：建立Saga执行状态的监控体系&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;补偿逻辑先行&lt;/strong&gt;：设计时就考虑好补偿方案&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  总结
&lt;/h2&gt;

&lt;p&gt;Saga模式是分布式系统中的&lt;strong&gt;时间换空间&lt;/strong&gt;策略：用最终一致性换取系统的高可用和性能。在微服务架构中，它已成为处理跨服务事务的&lt;strong&gt;首选方案&lt;/strong&gt;。掌握Saga模式，是成为合格架构师的必经之路。&lt;/p&gt;




&lt;p&gt;&lt;em&gt;本文是「架构进阶」系列文章&lt;/em&gt;&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>microservices</category>
      <category>designpatterns</category>
      <category>backend</category>
    </item>
  </channel>
</rss>
