<?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>Forem: 架构师小白</title>
    <description>The latest articles on Forem by 架构师小白 (@tianxin).</description>
    <link>https://forem.com/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>Forem: 架构师小白</title>
      <link>https://forem.com/tianxin</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/tianxin"/>
    <language>en</language>
    <item>
      <title>观察者模式深度指南：构建响应式事件系统的艺术</title>
      <dc:creator>架构师小白</dc:creator>
      <pubDate>Mon, 25 May 2026 01:03:50 +0000</pubDate>
      <link>https://forem.com/tianxin/guan-cha-zhe-mo-shi-shen-du-zhi-nan-gou-jian-xiang-ying-shi-shi-jian-xi-tong-de-yi-zhu-9li</link>
      <guid>https://forem.com/tianxin/guan-cha-zhe-mo-shi-shen-du-zhi-nan-gou-jian-xiang-ying-shi-shi-jian-xi-tong-de-yi-zhu-9li</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;ul&gt;
&lt;li&gt;用户订阅了某只股票的价格变动&lt;/li&gt;
&lt;li&gt;当价格变化时，系统需要通知所有订阅的用户&lt;/li&gt;
&lt;li&gt;有的用户用手机APP看，有的用网页，还有的可能需要邮件通知&lt;/li&gt;
&lt;/ul&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;Stock&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;update_price&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;new_price&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="c1"&gt;# 每加一个通知渠道，就要修改这个类
&lt;/span&gt;        &lt;span class="k"&gt;if&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;mobile_users&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nf"&gt;send_push_notification&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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;web_users&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nf"&gt;update_web_ui&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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email_users&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nf"&gt;send_email&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;这违反了&lt;strong&gt;开闭原则&lt;/strong&gt;——每增加一种通知方式，都要修改核心类。&lt;/p&gt;

&lt;h2&gt;
  
  
  观察者模式定义
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;观察者模式（Observer Pattern）&lt;/strong&gt; 是一种行为型设计模式，定义了一种一对多的依赖关系，让多个观察者对象同时监听某一个主题对象，当主题对象的状态发生变化时，会通知所有观察者对象，使它们能够自动更新自己。&lt;/p&gt;

&lt;h3&gt;
  
  
  核心角色
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────┐      ┌─────────────────┐
│    Subject      │◄────│    Observer     │
│  (被观察者)     │     │   (观察者)      │
├─────────────────┤     ├─────────────────┤
│ +attach()      │     │ +update()      │
│ +detach()      │     └─────────────────┘
│ +notify()      │            △
└─────────────────┘            │
       ▲                       │
       │ 1:N                  │ implements
       ▼                      │
┌─────────────────┐     ┌─────────────────┐
│ ConcreteSubject │────►│ConcreteObserver│
│ (具体主题)      │     │ (具体观察者)    │
├─────────────────┤     ├─────────────────┤
│ +getState()    │     │ +update()      │
│ +setState()    │     │ +display()    │
└─────────────────┘     └─────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  类图解释
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Subject（主题/被观察者）&lt;/strong&gt;：知道所有的观察者，提供attach和detach方法&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Observer（观察者）&lt;/strong&gt;：为所有的观察者定义统一的更新接口&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ConcreteSubject&lt;/strong&gt;：维护真实状态，在状态改变时通知观察者&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ConcreteObserver&lt;/strong&gt;：实现Observer的更新接口&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Python 实现
&lt;/h2&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="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;List&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;Observer&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;update&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;message&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="bp"&gt;None&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;EmailObserver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Observer&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;email&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;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;update&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;message&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="bp"&gt;None&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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&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;message&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SMSObserver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Observer&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;phone&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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;phone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;phone&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;update&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;message&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="bp"&gt;None&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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;phone&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;message&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;# 具体观察者：APP推送
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppPushObserver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Observer&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;device_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="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;device_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;device_id&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;update&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;message&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="bp"&gt;None&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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;device_id&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;message&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Subject&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;_observers&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;Observer&lt;/span&gt;&lt;span class="p"&gt;]&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;attach&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;observer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Observer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&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;_observers&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;observer&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="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;detach&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;observer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Observer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&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;_observers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;observer&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="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;notify&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;message&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="bp"&gt;None&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;observer&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;_observers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&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;StockSubject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Subject&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;symbol&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="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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_symbol&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;symbol&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;_price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;

    &lt;span class="nd"&gt;@property&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;price&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;_price&lt;/span&gt;

    &lt;span class="nd"&gt;@price.setter&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;price&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;new_price&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="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;old_price&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;_price&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;_price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new_price&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;old_price&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;new_price&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;notify&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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_symbol&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;old_price&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;new_price&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;stock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;StockSubject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AAPL&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;email_user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;EmailObserver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user@example.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;sms_user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SMSObserver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;13800138000&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;app_user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AppPushObserver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;device123&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;stock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email_user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;stock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sms_user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;stock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app_user&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="se"&gt;\n&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="n"&gt;stock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;150.0&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="se"&gt;\n&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="n"&gt;stock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;155.0&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 plaintext"&gt;&lt;code&gt;✅ 已添加观察者
✅ 已添加观察者
✅ 已添加观察者

=== 价格第一次变更 ===
📧 发送给 user@example.com: 股票 AAPL 价格从 0.0 变更为 150.0
📱 发送给 13800138000: 股票 AAPL 价格从 0.0 变更为 150.0
🔔 推送到设备 device123: 股票 AAPL 价格从 0.0 变更为 150.0

=== 价格第二次变更 ===
📧 发送给 user@example.com: 股票 AAPL 价格从 150.0 变更为 155.0
📱 发送给 13800138000: 股票 AAPL 价格从 150.0 变更为 155.0
🔔 推送到设备 device123: 股票 AAPL 价格从 150.0 变更为 155.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BlogSubscriber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Observer&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="nb"&gt;str&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;articles&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;update&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;article&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&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;articles&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;article&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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&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;article&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;title&lt;/span&gt;&lt;span class="sh"&gt;'&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Blog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Subject&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="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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_articles&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;publish&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;title&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;content&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="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;article&lt;/span&gt; &lt;span class="o"&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;title&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;content&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;_articles&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;article&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;notify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 使用
&lt;/span&gt;&lt;span class="n"&gt;blog&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Blog&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;blog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;BlogSubscriber&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="n"&gt;blog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;BlogSubscriber&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="n"&gt;blog&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;深入理解Python装饰器&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;装饰器是Python最强大的特性之一...&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;
  
  
  2. 事件总线（Event Bus）
&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;EventBus&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="n"&gt;_instance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__new__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cls&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;cls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_instance&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;cls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_instance&lt;/span&gt; &lt;span class="o"&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;__new__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cls&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;cls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_instance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_topics&lt;/span&gt; &lt;span class="o"&gt;=&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;cls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_instance&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;subscribe&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;topic&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;callback&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Callable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&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;if&lt;/span&gt; &lt;span class="n"&gt;topic&lt;/span&gt; &lt;span class="ow"&gt;not&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;_topics&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;_topics&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&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;_topics&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;topic&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;callback&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;publish&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;topic&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;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&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;if&lt;/span&gt; &lt;span class="n"&gt;topic&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;_topics&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;callback&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;_topics&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
                &lt;span class="nf"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 使用
&lt;/span&gt;&lt;span class="n"&gt;event_bus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;EventBus&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;handle_user_registered&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="nb"&gt;dict&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;user&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="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;def&lt;/span&gt; &lt;span class="nf"&gt;handle_user_registeredAnalytics&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="nb"&gt;dict&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;user&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="n"&gt;event_bus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user.registered&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;handle_user_registered&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;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user.registered&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;handle_user_registeredAnalytics&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user.registered&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;name&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;张三&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;email&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;zhangsan@example.com&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;h2&gt;
  
  
  观察者模式 vs 发布-订阅模式
&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;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;Subject 和 Observer 直接通信&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;Java Observable/Observable&lt;/td&gt;
&lt;td&gt;Kafka、RabbitMQ&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&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;：未及时detach可能导致问题&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  实际框架中的运用
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Django Signals
&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;django.db.models.signals&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;post_save&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.dispatch&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;receiver&lt;/span&gt;

&lt;span class="nd"&gt;@receiver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;post_save&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="o"&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;def&lt;/span&gt; &lt;span class="nf"&gt;user_created_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;created&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&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;created&lt;/span&gt;&lt;span class="p"&gt;:&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;instance&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;create_default_profile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;track_registration_event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  JavaScript EventEmitter
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;EventEmitter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;events&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Stock&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;EventEmitter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;setPrice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newPrice&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;oldPrice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;newPrice&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;oldPrice&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;newPrice&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;priceChanged&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
        &lt;span class="nx"&gt;oldPrice&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="nx"&gt;newPrice&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;symbol&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;symbol&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;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stock&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;Stock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AAPL&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;stock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;priceChanged&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;价格变动:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nx"&gt;stock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setPrice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;150&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;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;：抽象Observer接口 + Subject管理&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;常见变体&lt;/strong&gt;：事件总线、信号系统&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;最佳实践&lt;/strong&gt;：确保及时detach，避免内存泄漏&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;掌握观察者模式，你就能轻松构建各种响应式、系统联动、事件驱动的应用！&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;下期预告&lt;/strong&gt;：我们将介绍与观察者模式互补的&lt;strong&gt;发布-订阅模式&lt;/strong&gt;，以及如何在大型系统中使用消息队列实现真正的解耦。&lt;/p&gt;

&lt;p&gt;如果你喜欢这篇文章，欢迎点赞、收藏、转发！关注后第一时间获取最新教程。&lt;/p&gt;

&lt;h1&gt;
  
  
  设计模式 #软件架构 #Python #后端开发
&lt;/h1&gt;

</description>
      <category>architecture</category>
      <category>python</category>
      <category>softwareengineering</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>策略模式深度指南：让算法策略自由切换的艺术</title>
      <dc:creator>架构师小白</dc:creator>
      <pubDate>Sun, 24 May 2026 01:03:11 +0000</pubDate>
      <link>https://forem.com/tianxin/ce-lue-mo-shi-shen-du-zhi-nan-rang-suan-fa-ce-lue-zi-you-qie-huan-de-yi-zhu-45dl</link>
      <guid>https://forem.com/tianxin/ce-lue-mo-shi-shen-du-zhi-nan-rang-suan-fa-ce-lue-zi-you-qie-huan-de-yi-zhu-45dl</guid>
      <description>&lt;h1&gt;
  
  
  策略模式深度指南：让算法策略自由切换的艺术
&lt;/h1&gt;

&lt;p&gt;在软件开发中，我们经常面临需要在运行时根据不同情况选择不同算法的场景。比如：电商系统针对不同用户提供不同的折扣计算方式；支付系统根据用户选择的支付渠道执行不同的支付逻辑；日志系统根据环境选择不同的日志输出方式。&lt;/p&gt;

&lt;p&gt;这些场景的共同特点是：需要在运行时动态选择算法，而不是在编译时固定。策略模式正是解决这类问题的利器。&lt;/p&gt;

&lt;h2&gt;
  
  
  什么是策略模式?
&lt;/h2&gt;

&lt;p&gt;策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列算法,并将每个算法封装起来,使它们可以互相替换。策略模式让算法的变化独立于使用算法的客户。&lt;/p&gt;

&lt;h3&gt;
  
  
  核心角色
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;策略接口(Strategy): 定义了所有具体策略的公共接口&lt;/li&gt;
&lt;li&gt;具体策略(Concrete Strategy): 实现具体的算法&lt;/li&gt;
&lt;li&gt;上下文(Context): 持有策略引用,负责调用具体算法&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  代码实现
&lt;/h2&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;List&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;DiscountStrategy&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;calculate&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;original_price&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;float&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;NoDiscount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DiscountStrategy&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;calculate&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;original_price&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;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;original_price&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;FixedAmountDiscount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DiscountStrategy&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;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="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="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;calculate&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;original_price&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;float&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;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;original_price&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;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;PercentageDiscount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DiscountStrategy&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;percentage&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="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;percentage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;percentage&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;calculate&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;original_price&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;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;original_price&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&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;percentage&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="c1"&gt;# 具体策略:阶梯折扣
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TieredDiscount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DiscountStrategy&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;tiers&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="nb"&gt;tuple&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;tiers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tiers&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;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;reverse&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&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;calculate&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;original_price&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;float&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;threshold&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;discount&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;tiers&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;original_price&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;threshold&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;original_price&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;discount&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="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;original_price&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;PriceCalculator&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;strategy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;DiscountStrategy&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;strategy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;strategy&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;set_strategy&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;strategy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;DiscountStrategy&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;strategy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;strategy&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;calculate_price&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;original_price&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;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;strategy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;calculate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;original_price&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 使用示例
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;calculator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;NoDiscount&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;No discount: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;calculate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&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="n"&gt;calculator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FixedAmountDiscount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&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;Fixed discount: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;calculate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&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="n"&gt;calculator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;PercentageDiscount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&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;Percentage discount: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;calculate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&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="n"&gt;calculator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;TieredDiscount&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="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;30&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;Tiered discount 1000: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;calculate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&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="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;Tiered discount 2500: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;calculate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2500&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;/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;/li&gt;
&lt;li&gt;消除条件语句: 避免大量的 if-else 或 switch-case&lt;/li&gt;
&lt;li&gt;运行时切换: 可以在运行时灵活更换算法&lt;/li&gt;
&lt;li&gt;提高复用性: 相关算法可以重复使用&lt;/li&gt;
&lt;/ol&gt;

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

&lt;ol&gt;
&lt;li&gt;增加类数量: 每个策略都需要一个类&lt;/li&gt;
&lt;li&gt;客户端需了解策略差异: 需要知道各策略的区别&lt;/li&gt;
&lt;li&gt;增加复杂度: 对于简单场景可能过度设计&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  实际应用场景
&lt;/h2&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;压缩算法: 根据文件类型选择 ZIP、GZIP、Bzip2 等&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;策略模式是一种强大的行为型设计模式,它将算法封装成独立的对象,使我们可以动态地选择和使用不同的算法。在面对需要多种算法或行为的场景时,考虑使用策略模式来提高代码的可维护性和灵活性。记住:封装变化是设计模式的核心思想,而策略模式正是这一思想的典型体现。&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>designpatterns</category>
      <category>python</category>
      <category>programming</category>
    </item>
    <item>
      <title>Rate Limiting Strategies Deep Dive</title>
      <dc:creator>架构师小白</dc:creator>
      <pubDate>Sat, 23 May 2026 01:07:18 +0000</pubDate>
      <link>https://forem.com/tianxin/rate-limiting-strategies-deep-dive-4e7l</link>
      <guid>https://forem.com/tianxin/rate-limiting-strategies-deep-dive-4e7l</guid>
      <description>&lt;p&gt;Rate limiting and failover strategies are essential for building resilient distributed systems. In high-traffic scenarios, services can face challenges like traffic spikes and downstream service failures. This article explores practical approaches to protect your systems.&lt;/p&gt;




&lt;h2&gt;
  
  
  WHY RATE LIMITING IS IMPORTANT
&lt;/h2&gt;

&lt;p&gt;When traffic surge occurs unexpectedly, your system may experience cascading failures, resource exhaustion, and degraded user experience. Rate limiting acts as a first line of defense.&lt;/p&gt;




&lt;h2&gt;
  
  
  SLIDING WINDOW ALGORITHM
&lt;/h2&gt;

&lt;p&gt;One popular approach is the sliding window algorithm. Instead of fixed windows, we use smaller time slices to create smoother traffic patterns.&lt;/p&gt;




&lt;h2&gt;
  
  
  TOKEN BUCKET
&lt;/h2&gt;

&lt;p&gt;The token bucket allows burst traffic while maintaining an average rate. A bucket with fixed capacity gets tokens added at a constant rate, and each request consumes tokens.&lt;/p&gt;




&lt;h2&gt;
  
  
  CIRCUIT BREAKER
&lt;/h2&gt;

&lt;p&gt;The circuit breaker pattern prevents repeated calls to failing services. When failure rate exceeds threshold, the circuit opens and returns fallback responses.&lt;/p&gt;




&lt;h2&gt;
  
  
  BEST PRACTICES
&lt;/h2&gt;

&lt;p&gt;Implement layered rate limiting across gateway, application, and service layers. Prioritize critical requests. Provide graceful error messages. Monitor and alert on limiting events.&lt;/p&gt;

</description>
      <category>engineering</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>云原生架构深度指南：构建现代化应用的实践之道</title>
      <dc:creator>架构师小白</dc:creator>
      <pubDate>Fri, 22 May 2026 01:04:45 +0000</pubDate>
      <link>https://forem.com/tianxin/yun-yuan-sheng-jia-gou-shen-du-zhi-nan-gou-jian-xian-dai-hua-ying-yong-de-shi-jian-zhi-dao-pn3</link>
      <guid>https://forem.com/tianxin/yun-yuan-sheng-jia-gou-shen-du-zhi-nan-gou-jian-xian-dai-hua-ying-yong-de-shi-jian-zhi-dao-pn3</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;strong&gt;Cloud Native&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;：应用及其依赖被打包成轻量级容器&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;微服务&lt;/strong&gt;：独立部署的小型服务&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;/ul&gt;




&lt;h2&gt;
  
  
  云原生关键技术
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. 容器技术
&lt;/h3&gt;

&lt;p&gt;容器是云原生的基础单元。Docker 将应用及其运行时环境打包：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; node:20-alpine&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; package*.json ./&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm ci &lt;span class="nt"&gt;--only&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;production
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["node", "server.js"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Kubernetes (K8s)
&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;li&gt;自愈能力&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. 服务网格
&lt;/h3&gt;

&lt;p&gt;Istio 提供微服务间通信的可观测性与安全性：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;mTLS 加密&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;Terraform 示例：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_ecs_cluster"&lt;/span&gt; &lt;span class="s2"&gt;"app_cluster"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"production-cluster"&lt;/span&gt;
  &lt;span class="nx"&gt;setting&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;name&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"containerInsights"&lt;/span&gt;
    &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"enabled"&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;ul&gt;
&lt;li&gt;小型、独立的服务&lt;/li&gt;
&lt;li&gt;单一职责&lt;/li&gt;
&lt;li&gt;API 优先设计&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  原则二：弹性优先
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# K8s 健康检查示例&lt;/span&gt;
&lt;span class="na"&gt;livenessProbe&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;httpGet&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/healthz&lt;/span&gt;
    &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8080&lt;/span&gt;
  &lt;span class="na"&gt;initialDelaySeconds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt;
  &lt;span class="na"&gt;periodSeconds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;
&lt;span class="na"&gt;readinessProbe&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;httpGet&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/ready&lt;/span&gt;
    &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8080&lt;/span&gt;
  &lt;span class="na"&gt;initialDelaySeconds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;
  &lt;span class="na"&gt;periodSeconds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5&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;分布式追踪（Jaeger）&lt;/li&gt;
&lt;li&gt;指标监控（Prometheus + Grafana）&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  原则四：自动化
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;CI/CD 流水线&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;
  
  
  Step 1: 容器化现有应用
&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;实现 graceful shutdown&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 2: 迁移到 Kubernetes
&lt;/h3&gt;

&lt;p&gt;渐进式迁移策略：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;阶段一：Lift and Shift（直接迁移）&lt;/li&gt;
&lt;li&gt;阶段二：重构（容器优化）&lt;/li&gt;
&lt;li&gt;阶段三：重写（云原生设计）&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 3: 添加可观测性
&lt;/h3&gt;

&lt;p&gt;基础监控栈：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;日志：EFK Stack&lt;/li&gt;
&lt;li&gt;指标：Prometheus&lt;/li&gt;
&lt;li&gt;链路：Jaeger&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 4: 实施 DevOps
&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;h2&gt;
  
  
  何时采用云原生？
&lt;/h2&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;li&gt;团队缺乏 Kubernetes 经验&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  总结
&lt;/h2&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;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;CNCF Cloud Native Definition&lt;/li&gt;
&lt;li&gt;Kubernetes 官方文档&lt;/li&gt;
&lt;li&gt;《Cloud Native Infrastructure》&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;💬 你对云原生有什么疑问吗？在评论区告诉我！&lt;/p&gt;

&lt;h1&gt;
  
  
  云原生 #Kubernetes #DevOps
&lt;/h1&gt;

</description>
      <category>cloudnative</category>
      <category>kubernetes</category>
      <category>devops</category>
    </item>
    <item>
      <title>代理模式深度指南：构建控制访问的艺术</title>
      <dc:creator>架构师小白</dc:creator>
      <pubDate>Thu, 21 May 2026 01:05:24 +0000</pubDate>
      <link>https://forem.com/tianxin/dai-li-mo-shi-shen-du-zhi-nan-gou-jian-kong-zhi-fang-wen-de-yi-zhu-1pie</link>
      <guid>https://forem.com/tianxin/dai-li-mo-shi-shen-du-zhi-nan-gou-jian-kong-zhi-fang-wen-de-yi-zhu-1pie</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;h2&gt;
  
  
  代理模式的组成
&lt;/h2&gt;

&lt;p&gt;代理模式包含四个核心角色：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Subject（抽象主题）&lt;/strong&gt;：定义了 RealSubject 和 Proxy 的公共接口&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RealSubject（真实主题）&lt;/strong&gt;：真正执行业务逻辑的对象&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Proxy（代理）&lt;/strong&gt;：持有 RealSubject 的引用，在需要时创建真实对象&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Client（客户端）&lt;/strong&gt;：通过 Proxy 访问真实对象&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  代理模式的类型
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. 远程代理 (Remote Proxy)
&lt;/h3&gt;

&lt;p&gt;为远程对象在本地创建一个代理，隐藏网络访问细节。适用于需要调用分布式服务的场景。&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;客户端 → 本地代理 → 网络 → 远程服务
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. 虚代理 (Virtual Proxy)
&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;VirtualProxy&lt;/span&gt; &lt;span class="n"&gt;Image&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;url&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;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;url&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;_real_image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;display&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;if&lt;/span&gt; &lt;span class="ow"&gt;not&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;_real_image&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;_real_image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RealImage&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;url&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;_real_image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;display&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. 保护代理 (Protection Proxy)
&lt;/h3&gt;

&lt;p&gt;控制对真实对象的访问权限，在调用前进行身份验证。这类似于公司门禁系统——检查访客是否有权限进入。&lt;/p&gt;

&lt;h3&gt;
  
  
  4. 智能引用代理 (Smart Reference Proxy)
&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;
  
  
  5. 缓存代理 (Cache Proxy)
&lt;/h3&gt;

&lt;p&gt;为重复访问的结果提供缓存，避免重复计算。这就像浏览器的缓存机制——首次加载后保存在本地，后续直接使用。&lt;/p&gt;

&lt;h2&gt;
  
  
  Python 实现示例
&lt;/h2&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;import&lt;/span&gt; &lt;span class="n"&gt;time&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;Image&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;display&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="c1"&gt;# 真实主题
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RealImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Image&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;filename&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;filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;filename&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;_load_from_disk&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;_load_from_disk&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="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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filename&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="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&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;加载完成!&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;display&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="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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filename&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ProxyImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Image&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;filename&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;filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;filename&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;_real_image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;display&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;if&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;_real_image&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&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;_real_image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RealImage&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;filename&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;_real_image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;display&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&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;=== 第一次显示 ===&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;img&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ProxyImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;photo.jpg&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;display&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="se"&gt;\n&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="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;display&lt;/span&gt;&lt;span class="p"&gt;()&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 plaintext"&gt;&lt;code&gt;=== 第一次显示 ===
正在加载图片: photo.jpg
加载完成!
显示图片: photo.jpg

=== 第二次显示 ===
显示图片: photo.jpg
&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;/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;h3&gt;
  
  
  2. API 限流
&lt;/h3&gt;

&lt;p&gt;在高并发系统中，使用代理实现 API 限流，保护后端服务：&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;RateLimitedProxy&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;real_service&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_requests&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;time_window&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;real_service&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;real_service&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;max_requests&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;max_requests&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;time_window&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time_window&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;requests&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;call&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;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&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;requests&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;t&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;requests&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&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;time_window&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;len&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;requests&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;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;max_requests&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;Exception&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="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;requests&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;now&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;real_service&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="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&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;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;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;p&gt;掌握代理模式，让你在设计系统时多一件利器！&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;下篇预告&lt;/strong&gt;：策略模式 (Strategy Pattern) - 让算法 interchangeable 的艺术&lt;/p&gt;

&lt;p&gt;如果你对这个系列感兴趣，欢迎关注并留言讨论你想了解的设计模式！&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;提示&lt;/strong&gt;：合理使用代理模式可以显著提升系统性能和安全性，但切记不要过度设计。只有当真正需要控制访问时，才考虑使用代理。&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>architecture</category>
      <category>designpatterns</category>
      <category>python</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>可观测性架构深度指南：让分布式系统无处藏身</title>
      <dc:creator>架构师小白</dc:creator>
      <pubDate>Tue, 19 May 2026 01:05:21 +0000</pubDate>
      <link>https://forem.com/tianxin/ke-guan-ce-xing-jia-gou-shen-du-zhi-nan-rang-fen-bu-shi-xi-tong-wu-chu-cang-shen-2dh7</link>
      <guid>https://forem.com/tianxin/ke-guan-ce-xing-jia-gou-shen-du-zhi-nan-rang-fen-bu-shi-xi-tong-wu-chu-cang-shen-2dh7</guid>
      <description>&lt;h1&gt;
  
  
  可观测性架构深度指南：让分布式系统无处藏身
&lt;/h1&gt;

&lt;p&gt;想象一下，你的系统有100台服务器、50个微服务，每秒处理数十万请求。某天用户投诉支付失败，你该从哪里查起？翻日志？登录50台机器grep？那时候用户可能已经骂娘了。&lt;/p&gt;

&lt;p&gt;这就是可观测性要解决的问题。&lt;/p&gt;

&lt;h2&gt;
  
  
  从监控到可观测性：不只是换了个词
&lt;/h2&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;可观测性（Observability）源于控制理论，指&lt;strong&gt;仅凭外部输出就能推断系统内部状态的能力&lt;/strong&gt;。对于软件系统，这意味着你不需要提前预设所有告警场景——出了问题，你能自己找到答案。&lt;/p&gt;

&lt;p&gt;可观测性有三大支柱：&lt;/p&gt;

&lt;h3&gt;
  
  
  1. 日志（Logs）：时间的印记
&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;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Processing request&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;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Payment processing completed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;extra&lt;/span&gt;&lt;span class="o"&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="n"&gt;order_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;user_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;user_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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;payment_method&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;latency_ms&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;elapsed_ms&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;service&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;payment-service&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;结构化日志（JSON格式）是现代系统的标配，方便检索和分析。&lt;/p&gt;

&lt;h3&gt;
  
  
  2. 指标（Metrics）：数字说真相
&lt;/h3&gt;

&lt;p&gt;指标是聚合后的数值，用于回答"系统健康吗"这类宏观问题。经典指标模型：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;RED方法&lt;/strong&gt;（面向服务）：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;R&lt;/strong&gt;equests：请求速率&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;E&lt;/strong&gt;rrors：错误率&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;D&lt;/strong&gt;uration：延迟分布&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;USE方法&lt;/strong&gt;（面向资源）：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;U&lt;/strong&gt;tilization：利用率&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;S&lt;/strong&gt;aturation：饱和度&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;E&lt;/strong&gt;rrors：错误数
&lt;/li&gt;
&lt;/ul&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="c1"&gt;# Prometheus指标示例
&lt;/span&gt;&lt;span class="n"&gt;REQUEST_LATENCY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Histogram&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;http_request_duration_seconds&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;HTTP request latency&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;method&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;endpoint&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;status_code&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="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/orders&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;get_orders&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;REQUEST_LATENCY&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;GET&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;endpoint&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/orders&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;200&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;time&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;h3&gt;
  
  
  3. 链路追踪（Traces）：请求的生命旅程
&lt;/h3&gt;

&lt;p&gt;链路追踪记录一个请求从发起，到经过各个服务，再到返回的完整路径。它回答的问题是：这个请求为什么慢？卡在哪一步？&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Trace: abc123
├── [10ms] API Gateway
│   └── Span: auth-verify
├── [45ms] Order Service
│   ├── Span: query-inventory  [30ms]
│   └── Span: validate-coupon  [12ms]
└── [200ms] Payment Service
    └── Span: third-party-api  [195ms] ⚠️ 卡住！
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;这就是OpenTelemetry的价值所在——统一了日志、指标、追踪的采集标准，一次接入，全链路覆盖。&lt;/p&gt;

&lt;h2&gt;
  
  
  可观测性架构设计：四个关键决策
&lt;/h2&gt;

&lt;h3&gt;
  
  
  决策一：数据采集——Agent还是SDK埋点？
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Agent方式&lt;/strong&gt;：低侵入，运维友好，但精细度有限&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SDK埋点&lt;/strong&gt;：精细可控，但需要改代码&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;两者结合&lt;/strong&gt;：核心服务SDK埋点，非核心用Agent补充&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  决策二：数据传输——同步还是异步？
&lt;/h3&gt;

&lt;p&gt;异步拉取（如Prometheus scraping）更简单，同步推送（如opentelemetry collector）更实时。根据你的SLA要求选择。&lt;/p&gt;

&lt;h3&gt;
  
  
  决策三：存储选型——时序数据库 vs 日志系统
&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;Prometheus / Thanos / M3DB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;日志存储&lt;/td&gt;
&lt;td&gt;Loki / ELK / ClickHouse&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;链路存储&lt;/td&gt;
&lt;td&gt;Jaeger / Tempo / Zipkin&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;全栈统一&lt;/td&gt;
&lt;td&gt;Grafana LGTM（Grafana+Loki+Tempo+Mimir）&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;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;先聚合后告警&lt;/strong&gt;：100个服务同时报同类错误，只出一条告警&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;分级处理&lt;/strong&gt;：P0业务故障即时通知，P3次要异常次日汇总&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;去重+静默&lt;/strong&gt;：重复告警合并，避免"狼来了"疲劳
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Alertmanager 配置示例&lt;/span&gt;
&lt;span class="na"&gt;groups&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;high_traffic_alerts&lt;/span&gt;
  &lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;alert&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;HighErrorRate&lt;/span&gt;
    &lt;span class="na"&gt;expr&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m])) &amp;gt; &lt;/span&gt;&lt;span class="m"&gt;0.05&lt;/span&gt;
    &lt;span class="na"&gt;for&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2m&lt;/span&gt;  &lt;span class="c1"&gt;# 持续2分钟才告警，避免抖动&lt;/span&gt;
    &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;severity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;critical&lt;/span&gt;
    &lt;span class="na"&gt;annotations&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;summary&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;服务&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;$labels.service&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;错误率超过5%"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  实践案例：电商下单链路可观测性设计
&lt;/h2&gt;

&lt;p&gt;以支付下单为例，设计全链路追踪：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[前端下单]
    │
[API Gateway] ── trace_id生成 ──
    │
[订单服务] ── 创建订单span ──
    │                    │
[库存服务]              │
[优惠服务]              │（并行调用）
    │                    │
[支付服务] ── 第三方支付span ──
    │
[通知服务] ── 发送通知span ──
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;关键点：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;trace_id贯穿全链路，任何日志都能通过它串联&lt;/li&gt;
&lt;li&gt;每个span记录时间、错误信息、关键参数&lt;/li&gt;
&lt;li&gt;失败请求的trace单独高亮展示&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  给工程师的建议
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;从第一天就考虑可观测性&lt;/strong&gt;——事后补救成本是设计的10倍&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;结构化日志优先&lt;/strong&gt;——这是投入产出比最高的改进&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;不要只看指标，用户体验才是终点&lt;/strong&gt;——Core Web Vitals同样重要&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;告警要少而精&lt;/strong&gt;——收到告警时心里有底，知道怎么处理&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;最后送一句话：&lt;strong&gt;好的可观测性，不是让你知道系统正在发生什么，而是让你能搞清楚任何你想知道的事情。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;学会这套架构思维，无论是排查故障、性能优化，还是容量规划，都会游刃有余。这才是高级工程师的核心竞争力。&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>devops</category>
      <category>microservices</category>
      <category>cn</category>
    </item>
    <item>
      <title>异步消息模式深度指南：构建松耦合系统的核心技术</title>
      <dc:creator>架构师小白</dc:creator>
      <pubDate>Mon, 18 May 2026 01:03:52 +0000</pubDate>
      <link>https://forem.com/tianxin/yi-bu-xiao-xi-mo-shi-shen-du-zhi-nan-gou-jian-song-ou-he-xi-tong-de-he-xin-ji-zhu-1m8g</link>
      <guid>https://forem.com/tianxin/yi-bu-xiao-xi-mo-shi-shen-du-zhi-nan-gou-jian-song-ou-he-xi-tong-de-he-xin-ji-zhu-1m8g</guid>
      <description>&lt;h1&gt;
  
  
  异步消息模式深度指南：构建松耦合系统的核心技术
&lt;/h1&gt;

&lt;p&gt;在现代分布式系统中，同步调用无处不在，但它的缺点也显而易见——系统之间强耦合，任何一个服务宕机都可能引发连锁反应。异步消息模式正是解决这个问题的经典方案。&lt;/p&gt;




&lt;h2&gt;
  
  
  什么是异步消息模式？
&lt;/h2&gt;

&lt;p&gt;异步消息模式是一种通信架构风格，允许服务之间通过消息队列或消息 broker 进行间接通信，而不是直接的 HTTP 调用。发送方将消息发布到队列，接收方从队列消费消息，双方完全不需要知道彼此的存在。&lt;/p&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;h2&gt;
  
  
  消息队列的核心组件
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. 消息（Message）
&lt;/h3&gt;

&lt;p&gt;消息是传递的基本单元，通常包含：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;消息头（Header）&lt;/strong&gt;：元数据如唯一ID、时间戳、优先级&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;消息体（Body）&lt;/strong&gt;：实际传输的业务数据&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. 主题（Topic）vs 队列（Queue）
&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;队列（Queue）&lt;/th&gt;
&lt;th&gt;主题（Topic）&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;RabbitMQ&lt;/td&gt;
&lt;td&gt;Kafka、Pulsar&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  3. Broker（消息中间件）
&lt;/h3&gt;

&lt;p&gt;常见的消息 broker 包括：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;RabbitMQ&lt;/strong&gt;：AMQP 协议，企业级特性丰富&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Apache Kafka&lt;/strong&gt;：高吞吐日志系统&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RocketMQ&lt;/strong&gt;：阿里开源，分布式事务支持&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pulsar&lt;/strong&gt;：腾讯开源，存储计算分离&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  实战：使用 RabbitMQ 实现订单流程
&lt;/h2&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;pika&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&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;publish_order_created&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="n"&gt;user_email&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;connection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pika&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;BlockingConnection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;pika&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ConnectionParameters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;localhost&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;channel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;# 声明交换机和队列
&lt;/span&gt;    &lt;span class="n"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exchange_declare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;exchange&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exchange_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;durable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;queue_declare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;queue&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;order_notifications&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;durable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;queue_bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;exchange&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;queue&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;order_notifications&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;routing_key&lt;/span&gt;&lt;span class="o"&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;created&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# 发布消息
&lt;/span&gt;    &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&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="n"&gt;order_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;user_email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;user_email&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;items&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="n"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;basic_publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;exchange&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;routing_key&lt;/span&gt;&lt;span class="o"&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;created&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;pika&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;BasicProperties&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;delivery_mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# 持久化
&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="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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;consume_notifications&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;connection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pika&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;BlockingConnection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pika&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ConnectionParameters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;localhost&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;channel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;channel&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;callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&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;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;send_email&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;user_email&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;order&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="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="n"&gt;ch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;basic_ack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;delivery_tag&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;delivery_tag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;basic_qos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prefetch_count&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="n"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;basic_consume&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;queue&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;order_notifications&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;on_message_callback&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start_consuming&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;/p&gt;

&lt;h3&gt;
  
  
  2. 工作队列模式
&lt;/h3&gt;

&lt;p&gt;多个worker竞争处理任务，实现负载均衡。&lt;/p&gt;

&lt;h3&gt;
  
  
  3. 路由模式
&lt;/h3&gt;

&lt;p&gt;根据消息内容或规则分发到不同队列。&lt;/p&gt;

&lt;h3&gt;
  
  
  4. 死信队列（DLQ）
&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;/li&gt;
&lt;li&gt;配置publisher confirm&lt;/li&gt;
&lt;li&gt;使用事务（性能折中）&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  消息重复怎么处理？
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;幂等性设计：业务ID去重&lt;/li&gt;
&lt;li&gt;至少一次投递 + 幂等消费&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  顺序如何保证？
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;单队列顺序：按业务key分片&lt;/li&gt;
&lt;li&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;消息 TTL 和清理策略&lt;/li&gt;
&lt;li&gt;背压（Backpressure）机制&lt;/li&gt;
&lt;/ul&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;/p&gt;

</description>
      <category>architecture</category>
      <category>backend</category>
      <category>distributedsystems</category>
      <category>systemdesign</category>
    </item>
    <item>
      <title>管道模式深度指南：构建可组合的数据处理流水线</title>
      <dc:creator>架构师小白</dc:creator>
      <pubDate>Thu, 07 May 2026 01:02:36 +0000</pubDate>
      <link>https://forem.com/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://forem.com/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://forem.com/tianxin/she-ji-mo-shi-yu-yuan-ze-gou-jian-ke-kuo-zhan-dai-ma-de-jing-dian-zhi-dao-317c</link>
      <guid>https://forem.com/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://forem.com/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://forem.com/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://forem.com/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://forem.com/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://forem.com/tianxin/cang-chu-mo-shi-shen-du-zhi-nan-gou-jian-shu-ju-fang-wen-chou-xiang-de-yi-zhu-5f6h</link>
      <guid>https://forem.com/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>
  </channel>
</rss>
