<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>简单易懂の现代魔法</title>
  
  
  <link href="https://galudisu.info/atom.xml" rel="self"/>
  
  <link href="https://galudisu.info/"/>
  <updated>2026-05-05T16:04:07.854Z</updated>
  <id>https://galudisu.info/</id>
  
  <author>
    <name>barudisshu</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>Leetcode Practice</title>
    <link href="https://galudisu.info/2026/05/03/algorithm/leetcode/Leetcode-Practice/"/>
    <id>https://galudisu.info/2026/05/03/algorithm/leetcode/Leetcode-Practice/</id>
    <published>2026-05-03T09:01:40.000Z</published>
    <updated>2026-05-05T16:04:07.854Z</updated>
    
    <content type="html"><![CDATA[<table><thead><tr><th style="text-align:left">Name</th><th style="text-align:left">Grade</th></tr></thead><tbody><tr><td style="text-align:left"><a href="/2025/05/02/algorithm/leetcode/trapping-rain-water/">42. Trapping Rain Water</a></td><td style="text-align:left">Hard</td></tr><tr><td style="text-align:left"><a href="/2025/05/02/algorithm/leetcode/unique-binary-search/">96. Unique Binary Search Trees</a></td><td style="text-align:left">Medium</td></tr><tr><td style="text-align:left"><a href="/2025/05/02/algorithm/leetcode/russian-doll-envelopes/">354. Russian Doll Envelopes</a></td><td style="text-align:left">Hard</td></tr><tr><td style="text-align:left"><a href="/2025/05/02/algorithm/leetcode/cherry-pickup/">741. Cherry Pickup</a></td><td style="text-align:left">Hard</td></tr><tr><td style="text-align:left"><a href="/2025/05/02/algorithm/leetcode/cheapest-flights-within-k-stops/">787. Cheapest Flights Within K Stops</a></td><td style="text-align:left">Medium</td></tr><tr><td style="text-align:left"><a href="/2025/05/02/algorithm/leetcode/shortest-path-visiting-all-nodes/">847. Shortest Path Visiting All Nodes</a></td><td style="text-align:left">Hard</td></tr><tr><td style="text-align:left"><a href="/2025/05/02/algorithm/leetcode/reducing-dishes/">1402. Reducing Dishes</a></td><td style="text-align:left">Hard</td></tr><tr><td style="text-align:left"><a href="/2025/05/02/algorithm/leetcode/number-of-ways-of-cutting-a-pizza/">1444. Number of Ways of Cutting a Pizza</a></td><td style="text-align:left">Hard</td></tr><tr><td style="text-align:left"><a href="/2025/05/02/algorithm/leetcode/minimum-cost-to-reach-destination-in-time/">1928. Minimum Cost to Reach Destination</a></td><td style="text-align:left">Hard</td></tr><tr><td style="text-align:left"><a href="/2025/05/02/algorithm/leetcode/fair-distribution-of-cookies/">2305. Fair Distribution of Cookies</a></td><td style="text-align:left">Medium</td></tr></tbody></table><span id="more"></span>]]></content>
    
    
    <summary type="html">&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style=&quot;text-align:left&quot;&gt;Name&lt;/th&gt;
&lt;th style=&quot;text-align:left&quot;&gt;Grade&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;/2025/05/02/algorithm/leetcode/trapping-rain-water/&quot;&gt;42. Trapping Rain Water&lt;/a&gt;&lt;/td&gt;
&lt;td style=&quot;text-align:left&quot;&gt;Hard&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;/2025/05/02/algorithm/leetcode/unique-binary-search/&quot;&gt;96. Unique Binary Search Trees&lt;/a&gt;&lt;/td&gt;
&lt;td style=&quot;text-align:left&quot;&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;/2025/05/02/algorithm/leetcode/russian-doll-envelopes/&quot;&gt;354. Russian Doll Envelopes&lt;/a&gt;&lt;/td&gt;
&lt;td style=&quot;text-align:left&quot;&gt;Hard&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;/2025/05/02/algorithm/leetcode/cherry-pickup/&quot;&gt;741. Cherry Pickup&lt;/a&gt;&lt;/td&gt;
&lt;td style=&quot;text-align:left&quot;&gt;Hard&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;/2025/05/02/algorithm/leetcode/cheapest-flights-within-k-stops/&quot;&gt;787. Cheapest Flights Within K Stops&lt;/a&gt;&lt;/td&gt;
&lt;td style=&quot;text-align:left&quot;&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;/2025/05/02/algorithm/leetcode/shortest-path-visiting-all-nodes/&quot;&gt;847. Shortest Path Visiting All Nodes&lt;/a&gt;&lt;/td&gt;
&lt;td style=&quot;text-align:left&quot;&gt;Hard&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;/2025/05/02/algorithm/leetcode/reducing-dishes/&quot;&gt;1402. Reducing Dishes&lt;/a&gt;&lt;/td&gt;
&lt;td style=&quot;text-align:left&quot;&gt;Hard&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;/2025/05/02/algorithm/leetcode/number-of-ways-of-cutting-a-pizza/&quot;&gt;1444. Number of Ways of Cutting a Pizza&lt;/a&gt;&lt;/td&gt;
&lt;td style=&quot;text-align:left&quot;&gt;Hard&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;/2025/05/02/algorithm/leetcode/minimum-cost-to-reach-destination-in-time/&quot;&gt;1928. Minimum Cost to Reach Destination&lt;/a&gt;&lt;/td&gt;
&lt;td style=&quot;text-align:left&quot;&gt;Hard&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align:left&quot;&gt;&lt;a href=&quot;/2025/05/02/algorithm/leetcode/fair-distribution-of-cookies/&quot;&gt;2305. Fair Distribution of Cookies&lt;/a&gt;&lt;/td&gt;
&lt;td style=&quot;text-align:left&quot;&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</summary>
    
    
    <content src="https://galudisu.info/%3Ctable%3E%3Cthead%3E%3Ctr%3E%3Cth%20style=%22text-align:left%22%3EName%3C/th%3E%3Cth%20style=%22text-align:left%22%3EGrade%3C/th%3E%3C/tr%3E%3C/thead%3E%3Ctbody%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%3Ca%20href=%22/2025/05/02/algorithm/leetcode/trapping-rain-water/%22%3E42.%20Trapping%20Rain%20Water%3C/a%3E%3C/td%3E%3Ctd%20style=%22text-align:left%22%3EHard%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%3Ca%20href=%22/2025/05/02/algorithm/leetcode/unique-binary-search/%22%3E96.%20Unique%20Binary%20Search%20Trees%3C/a%3E%3C/td%3E%3Ctd%20style=%22text-align:left%22%3EMedium%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%3Ca%20href=%22/2025/05/02/algorithm/leetcode/russian-doll-envelopes/%22%3E354.%20Russian%20Doll%20Envelopes%3C/a%3E%3C/td%3E%3Ctd%20style=%22text-align:left%22%3EHard%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%3Ca%20href=%22/2025/05/02/algorithm/leetcode/cherry-pickup/%22%3E741.%20Cherry%20Pickup%3C/a%3E%3C/td%3E%3Ctd%20style=%22text-align:left%22%3EHard%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%3Ca%20href=%22/2025/05/02/algorithm/leetcode/cheapest-flights-within-k-stops/%22%3E787.%20Cheapest%20Flights%20Within%20K%20Stops%3C/a%3E%3C/td%3E%3Ctd%20style=%22text-align:left%22%3EMedium%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%3Ca%20href=%22/2025/05/02/algorithm/leetcode/shortest-path-visiting-all-nodes/%22%3E847.%20Shortest%20Path%20Visiting%20All%20Nodes%3C/a%3E%3C/td%3E%3Ctd%20style=%22text-align:left%22%3EHard%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%3Ca%20href=%22/2025/05/02/algorithm/leetcode/reducing-dishes/%22%3E1402.%20Reducing%20Dishes%3C/a%3E%3C/td%3E%3Ctd%20style=%22text-align:left%22%3EHard%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%3Ca%20href=%22/2025/05/02/algorithm/leetcode/number-of-ways-of-cutting-a-pizza/%22%3E1444.%20Number%20of%20Ways%20of%20Cutting%20a%20Pizza%3C/a%3E%3C/td%3E%3Ctd%20style=%22text-align:left%22%3EHard%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%3Ca%20href=%22/2025/05/02/algorithm/leetcode/minimum-cost-to-reach-destination-in-time/%22%3E1928.%20Minimum%20Cost%20to%20Reach%20Destination%3C/a%3E%3C/td%3E%3Ctd%20style=%22text-align:left%22%3EHard%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%3Ca%20href=%22/2025/05/02/algorithm/leetcode/fair-distribution-of-cookies/%22%3E2305.%20Fair%20Distribution%20of%20Cookies%3C/a%3E%3C/td%3E%3Ctd%20style=%22text-align:left%22%3EMedium%3C/td%3E%3C/tr%3E%3C/tbody%3E%3C/table%3E%3Cspan%20id=%22more%22%3E%3C/span%3E" type="image"/>
    
    
    
    <category term="leetcode" scheme="https://galudisu.info/tags/leetcode/"/>
    
  </entry>
  
  <entry>
    <title>Ubuntu 安装ollama 在本地执行 zeroclaw 助手服务(二)</title>
    <link href="https://galudisu.info/2026/02/16/ollama/ubuntu-ollama-zeroclaw-install-two/"/>
    <id>https://galudisu.info/2026/02/16/ollama/ubuntu-ollama-zeroclaw-install-two/</id>
    <published>2026-02-16T04:30:04.000Z</published>
    <updated>2026-04-14T19:59:30.857Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>Ollama 官网有提供了openclaw的方案，一身反骨的我们决定用zeroclaw，一个rust版的更轻量级的替换方案。</p></blockquote><h3 id="前提准备"><a class="header-anchor" href="#前提准备">¶</a>前提准备</h3><p>首先你得安装rust语言，</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">sudo apt-get update -y</span><br><span class="line">sudo apt-get install rustc cargo -y</span><br></pre></td></tr></table></figure><p>或者按照官方的指示从脚本安装：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">curl --proto &#x27;=https&#x27; --tlsv1.2 -sSf https://sh.rustup.rs | sh</span><br><span class="line">source $HOME/cargo/env</span><br><span class="line">rustup update</span><br></pre></td></tr></table></figure><p>如网速较慢可以切换<a href="https://mirrors.tuna.tsinghua.edu.cn/help/rustup/">国内mirrors</a>.</p><h3 id="构建zeroclaw-助手"><a class="header-anchor" href="#构建zeroclaw-助手">¶</a>构建zeroclaw 助手</h3><p>直接从<a href="https://github.com/theonlyhennygod/zeroclaw">github</a>拷贝，按照README.md指示执行即可。</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">git clone https://github.com/theonlyhennygod/zeroclaw.git</span><br><span class="line">cd zeroclaw</span><br><span class="line">cargo build --release</span><br><span class="line">cargo install --path .</span><br><span class="line">...</span><br></pre></td></tr></table></figure><p>执行<code>zeroclaw onboard</code>后会生成配置<code>~/.zeroclaw/config.toml</code></p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">zeroclaw onboard</span><br></pre></td></tr></table></figure><p><img src="/img/ollama/zeroclaw-onboard.png" alt="zero-onboard"></p><h3 id="将zeroClaw集成到本地的ollama"><a class="header-anchor" href="#将zeroClaw集成到本地的ollama">¶</a>将zeroClaw集成到本地的ollama</h3><p>修改<code>config.toml</code>以指定provider，譬如上一篇文章用了llama3.2，</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">zeroclaw onboard --interactive</span><br></pre></td></tr></table></figure><ol><li>选择<code>Local / private(Ollama - no API key needed)</code>，因为穷…</li><li>选择已经安装好的模型<br><img src="/img/ollama/zeroclaw-model.png" alt="zeroclaw-model"></li><li>如果想代理到公网可以用cloudflare的zero trust</li></ol><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">zeroclaw agent -m &quot;Hello, are you running on Ollama?&quot;</span><br></pre></td></tr></table></figure><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">zeroclaw status</span><br></pre></td></tr></table></figure><p><img src="/img/ollama/zeroclaw-agent.png" alt="agent"></p><p>emmmm… 还是有很多bug，估计过短时间就好了。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;Ollama 官网有提供了openclaw的方案，一身反骨的我们决定用zeroclaw，一个rust版的更轻量级的替换方案。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;前提准备&quot;&gt;&lt;a class=&quot;header-anchor&quot; href</summary>
      
    
    
    <content src="https://galudisu.info/%3Cblockquote%3E%3Cp%3EOllama%20%E5%AE%98%E7%BD%91%E6%9C%89%E6%8F%90%E4%BE%9B%E4%BA%86openclaw%E7%9A%84%E6%96%B9%E6%A1%88%EF%BC%8C%E4%B8%80%E8%BA%AB%E5%8F%8D%E9%AA%A8%E7%9A%84%E6%88%91%E4%BB%AC%E5%86%B3%E5%AE%9A%E7%94%A8zeroclaw%EF%BC%8C%E4%B8%80%E4%B8%AArust%E7%89%88%E7%9A%84%E6%9B%B4%E8%BD%BB%E9%87%8F%E7%BA%A7%E7%9A%84%E6%9B%BF%E6%8D%A2%E6%96%B9%E6%A1%88%E3%80%82%3C/p%3E%3C/blockquote%3E%3Ch3%20id=%22%E5%89%8D%E6%8F%90%E5%87%86%E5%A4%87%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E5%89%8D%E6%8F%90%E5%87%86%E5%A4%87%22%3E%C2%B6%3C/a%3E%E5%89%8D%E6%8F%90%E5%87%86%E5%A4%87%3C/h3%3E%3Cp%3E%E9%A6%96%E5%85%88%E4%BD%A0%E5%BE%97%E5%AE%89%E8%A3%85rust%E8%AF%AD%E8%A8%80%EF%BC%8C%3C/p%3E%3Cfigure%20class=%22highlight%20shell%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3Esudo%20apt-get%20update%20-y%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3Esudo%20apt-get%20install%20rustc%20cargo%20-y%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Cp%3E%E6%88%96%E8%80%85%E6%8C%89%E7%85%A7%E5%AE%98%E6%96%B9%E7%9A%84%E6%8C%87%E7%A4%BA%E4%BB%8E%E8%84%9A%E6%9C%AC%E5%AE%89%E8%A3%85%EF%BC%9A%3C/p%3E%3Cfigure%20class=%22highlight%20shell%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3Ecurl%20--proto%20&amp;#x27;=https&amp;#x27;%20--tlsv1.2%20-sSf%20https:/sh.rustup.rs%20|%20sh%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3Esource%20$HOME/cargo/env%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3Erustup%20update%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Cp%3E%E5%A6%82%E7%BD%91%E9%80%9F%E8%BE%83%E6%85%A2%E5%8F%AF%E4%BB%A5%E5%88%87%E6%8D%A2%3Ca%20href=%22https:/mirrors.tuna.tsinghua.edu.cn/help/rustup/%22%3E%E5%9B%BD%E5%86%85mirrors%3C/a%3E.%3C/p%3E%3Ch3%20id=%22%E6%9E%84%E5%BB%BAzeroclaw-%E5%8A%A9%E6%89%8B%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E6%9E%84%E5%BB%BAzeroclaw-%E5%8A%A9%E6%89%8B%22%3E%C2%B6%3C/a%3E%E6%9E%84%E5%BB%BAzeroclaw%20%E5%8A%A9%E6%89%8B%3C/h3%3E%3Cp%3E%E7%9B%B4%E6%8E%A5%E4%BB%8E%3Ca%20href=%22https:/github.com/theonlyhennygod/zeroclaw%22%3Egithub%3C/a%3E%E6%8B%B7%E8%B4%9D%EF%BC%8C%E6%8C%89%E7%85%A7README.md%E6%8C%87%E7%A4%BA%E6%89%A7%E8%A1%8C%E5%8D%B3%E5%8F%AF%E3%80%82%3C/p%3E%3Cfigure%20class=%22highlight%20shell%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3Egit%20clone%20https:/github.com/theonlyhennygod/zeroclaw.git%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3Ecd%20zeroclaw%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3Ecargo%20build%20--release%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3Ecargo%20install%20--path%20.%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E...%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Cp%3E%E6%89%A7%E8%A1%8C%3Ccode%3Ezeroclaw%20onboard%3C/code%3E%E5%90%8E%E4%BC%9A%E7%94%9F%E6%88%90%E9%85%8D%E7%BD%AE%3Ccode%3E~/.zeroclaw/config.toml%3C/code%3E%3C/p%3E%3Cfigure%20class=%22highlight%20shell%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3Ezeroclaw%20onboard%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Cp%3E%3Cimg%20src=%22/img/ollama/zeroclaw-onboard.png%22%20alt=%22zero-onboard%22%3E%3C/p%3E%3Ch3%20id=%22%E5%B0%86zeroClaw%E9%9B%86%E6%88%90%E5%88%B0%E6%9C%AC%E5%9C%B0%E7%9A%84ollama%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E5%B0%86zeroClaw%E9%9B%86%E6%88%90%E5%88%B0%E6%9C%AC%E5%9C%B0%E7%9A%84ollama%22%3E%C2%B6%3C/a%3E%E5%B0%86zeroClaw%E9%9B%86%E6%88%90%E5%88%B0%E6%9C%AC%E5%9C%B0%E7%9A%84ollama%3C/h3%3E%3Cp%3E%E4%BF%AE%E6%94%B9%3Ccode%3Econfig.toml%3C/code%3E%E4%BB%A5%E6%8C%87%E5%AE%9Aprovider%EF%BC%8C%E8%AD%AC%E5%A6%82%E4%B8%8A%E4%B8%80%E7%AF%87%E6%96%87%E7%AB%A0%E7%94%A8%E4%BA%86llama3.2%EF%BC%8C%3C/p%3E%3Cfigure%20class=%22highlight%20shell%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3Ezeroclaw%20onboard%20--interactive%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Col%3E%3Cli%3E%E9%80%89%E6%8B%A9%3Ccode%3ELocal%20/%20private(Ollama%20-%20no%20API%20key%20needed)%3C/code%3E%EF%BC%8C%E5%9B%A0%E4%B8%BA%E7%A9%B7%E2%80%A6%3C/li%3E%3Cli%3E%E9%80%89%E6%8B%A9%E5%B7%B2%E7%BB%8F%E5%AE%89%E8%A3%85%E5%A5%BD%E7%9A%84%E6%A8%A1%E5%9E%8B%3Cbr%3E%3Cimg%20src=%22/img/ollama/zeroclaw-model.png%22%20alt=%22zeroclaw-model%22%3E%3C/li%3E%3Cli%3E%E5%A6%82%E6%9E%9C%E6%83%B3%E4%BB%A3%E7%90%86%E5%88%B0%E5%85%AC%E7%BD%91%E5%8F%AF%E4%BB%A5%E7%94%A8cloudflare%E7%9A%84zero%20trust%3C/li%3E%3C/ol%3E%3Cfigure%20class=%22highlight%20shell%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3Ezeroclaw%20agent%20-m%20&amp;quot;Hello,%20are%20you%20running%20on%20Ollama?&amp;quot;%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Cfigure%20class=%22highlight%20shell%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3Ezeroclaw%20status%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Cp%3E%3Cimg%20src=%22/img/ollama/zeroclaw-agent.png%22%20alt=%22agent%22%3E%3C/p%3E%3Cp%3Eemmmm%E2%80%A6%20%E8%BF%98%E6%98%AF%E6%9C%89%E5%BE%88%E5%A4%9Abug%EF%BC%8C%E4%BC%B0%E8%AE%A1%E8%BF%87%E7%9F%AD%E6%97%B6%E9%97%B4%E5%B0%B1%E5%A5%BD%E4%BA%86%E3%80%82%3C/p%3E" type="image"/>
    
    
    
    <category term="ollama" scheme="https://galudisu.info/tags/ollama/"/>
    
    <category term="llama3" scheme="https://galudisu.info/tags/llama3/"/>
    
    <category term="openclaw" scheme="https://galudisu.info/tags/openclaw/"/>
    
    <category term="zeroclaw" scheme="https://galudisu.info/tags/zeroclaw/"/>
    
  </entry>
  
  <entry>
    <title>Ubuntu 安装ollama 在本地执行 zeroclaw 助手服务(一)</title>
    <link href="https://galudisu.info/2026/02/16/ollama/ubuntu-ollama-zeroclaw-install-one/"/>
    <id>https://galudisu.info/2026/02/16/ollama/ubuntu-ollama-zeroclaw-install-one/</id>
    <published>2026-02-16T04:20:04.000Z</published>
    <updated>2026-04-14T19:59:30.880Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>现在的AI技术发展真是一日千里，在目前企业庞大的资金博弈的前提下，拼的是谁的能耗成本更低、速度更快、效率更高、迭代更友好，谁率先打破摩尔定律，谁将会成为事实上的标准。作为普通程序员只能被动作为旁观者参与其中。先让子弹飞一会。</p></blockquote><span id="more"></span><h3 id="Ollama-介绍"><a class="header-anchor" href="#Ollama-介绍">¶</a>Ollama 介绍</h3><p><a href="https://ollama.com">Ollama</a>是一个专注于大语言模型(LLM, Large Language Models)应用的开源方案，旨在帮助开发者轻松部署和使用私有的大型语言模型，而无需依赖外部的云端服务或外部API，这些模型不仅仅只有包括Meta Llama Model，也提供其他一些Open LLM Model，像是Llama 3.3，Phi 3，Mistral，Gemma 2。该方案的核心目的是提供高效、安全、可控的LLM推论环境建制。大致上有以下特性：</p><h4 id="采用本地机器运行"><a class="header-anchor" href="#采用本地机器运行">¶</a>采用本地机器运行</h4><p>Ollama支持在自己的设备上载入模型，无需将数据上传至云端，确保数据隐私与安全。</p><p>通过优化模型运行效率，即使在资源有限的设备上也能流畅进行推论。</p><h4 id="开源与可定制化"><a class="header-anchor" href="#开源与可定制化">¶</a>开源与可定制化</h4><p>Ollama是一个采用MIT License的开源方案，允许开发者根据自己的需求进行修改与扩展。开发者可以将其与其他应用整合，创建自定义的AI解决方案。</p><h4 id="支持跨平台"><a class="header-anchor" href="#支持跨平台">¶</a>支持跨平台</h4><p>提供针对对中操作系统(如Windows、macOS和Linux)的支持，使其能够适应不同的开发环境。</p><h4 id="提供API开发与整合"><a class="header-anchor" href="#提供API开发与整合">¶</a>提供API开发与整合</h4><p>提供简单易用的API和工具，帮助开发者快速集成语言模型功能到他们的应用中。</p><h4 id="隐私与安全性"><a class="header-anchor" href="#隐私与安全性">¶</a>隐私与安全性</h4><p>由于所有运算都在本地完成，无需依赖外部服务器，数据泄露的风险大大降低。</p><p>Ollama 的出现满足了对数据敏感性高或对云端依赖性有限的应用需求，如企业内部工具、教育应用或个人隐私保护需求。如果需要更深入的技术细节或具体的使用案例，可以参考该专案的<a href="ollama.com/blog">官方文档</a>或<a href="https://github.com/ollama/ollama">Github</a>页面。</p><h3 id="Ubuntu-Linux-安装Ollama"><a class="header-anchor" href="#Ubuntu-Linux-安装Ollama">¶</a>Ubuntu Linux 安装Ollama</h3><p>Ubuntu可通过官方标准脚本进行安装，方法如下：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">sudo apt-get update -y</span><br><span class="line">sudo apt-get install curl -y</span><br><span class="line">sudo curl -fsSL https://ollama.com/install.sh | sh</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_">&gt;</span><span class="language-bash">&gt;&gt; Installing ollama to /usr/local</span></span><br><span class="line"><span class="meta prompt_">&gt;</span><span class="language-bash">&gt;&gt; Downloading ollama-linux-amd64.tar.zst</span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment">####################################################################### 100.0%</span></span></span><br><span class="line"><span class="meta prompt_">&gt;</span><span class="language-bash">&gt;&gt; Creating ollama user...</span></span><br><span class="line"><span class="meta prompt_">&gt;</span><span class="language-bash">&gt;&gt; Adding ollama user to render group...</span></span><br><span class="line"><span class="meta prompt_">&gt;</span><span class="language-bash">&gt;&gt; Adding ollama user to video group...</span></span><br><span class="line"><span class="meta prompt_">&gt;</span><span class="language-bash">&gt;&gt; Adding current user to ollama group...</span></span><br><span class="line"><span class="meta prompt_">&gt;</span><span class="language-bash">&gt;&gt; Creating ollama systemd service...</span></span><br><span class="line"><span class="meta prompt_">&gt;</span><span class="language-bash">&gt;&gt; Enabling and starting ollama service...</span></span><br><span class="line">Created symlink /etc/systemd/system/default.target.wants/ollama.service → /etc/systemd/system/ollama.service.</span><br><span class="line"><span class="meta prompt_">&gt;</span><span class="language-bash">&gt;&gt; Downloading ollama-linux-amd64-rocm.tar.zst</span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash"><span class="comment">####################################################################### 100.0%</span></span></span><br><span class="line"><span class="meta prompt_">&gt;</span><span class="language-bash">&gt;&gt; The Ollama API is now available at 127.0.0.1:11434.</span></span><br><span class="line"><span class="meta prompt_">&gt;</span><span class="language-bash">&gt;&gt; Install complete. Run <span class="string">&quot;ollama&quot;</span> from the <span class="built_in">command</span> line.</span></span><br><span class="line"><span class="meta prompt_">&gt;</span><span class="language-bash">&gt;&gt; AMD GPU ready.</span></span><br></pre></td></tr></table></figure><h4 id="启动Ollama服务"><a class="header-anchor" href="#启动Ollama服务">¶</a>启动Ollama服务</h4><p>脚本执行完成服务已注册入systemd并启动，执行如下命令查看模型列表：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ollama list</span><br></pre></td></tr></table></figure><h4 id="Ollama-pull-下载-llama-3-2-3b模型"><a class="header-anchor" href="#Ollama-pull-下载-llama-3-2-3b模型">¶</a>Ollama pull 下载 llama 3.2 3b模型</h4><p>上面的服务不能关掉，然后按照官方的doc介绍，执行<code>ollama pull llama3.2</code>就会下载模型了，需要2GB左右的磁盘空间，不指定版本的话预设是3b的模型，可以单用CPU执行，如果有GPU的话大约需要4GB的VRAM即可，下载完成后的画面如下：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ollama pull llama3.2</span><br></pre></td></tr></table></figure><p><img src="/img/ollama/llama-3-2.png" alt="llama-3-2.png"></p><p>完成以后也可以透过<code>ollama list</code>列出可用的模型，概念与Docker Image一样，</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ollama list</span><br></pre></td></tr></table></figure><p><img src="/img/ollama/model-list.png" alt="model-list.png"></p><h3 id="通过提示词调用Ollama-LL推理"><a class="header-anchor" href="#通过提示词调用Ollama-LL推理">¶</a>通过提示词调用Ollama LL推理</h3><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">ollama run llama3.2</span><br><span class="line"><span class="meta prompt_">&gt;</span><span class="language-bash">&gt;&gt; 您是Ollama方面的大语言模型专家，请给一位刚入门的小白讲解如何使用Ollama</span></span><br><span class="line">好的！我是Ollama的语言模型专家，现在让我们来了解一下如何使用Ollama：</span><br><span class="line"></span><br><span class="line">**1. 什么是Ollama？**</span><br><span class="line"></span><br><span class="line">Ollama是一种深度学习模型，尤其适合自然languageprocessing（NLP）任务，如问答、翻译、语义分析等。它能够理解和生成人类语言。</span><br><span class="line"></span><br><span class="line">**2. 如何进入Ollama的环境？**</span><br><span class="line"></span><br><span class="line">你需要一个计算机或移动设备，并安装了Python和TensorFlow或PyTorch等深度学习框架。在终端或命令行模式下输入以下命令</span><br><span class="line">...</span><br><span class="line">...</span><br></pre></td></tr></table></figure><h3 id="通过Rest-API呼叫Ollama-LLM推理"><a class="header-anchor" href="#通过Rest-API呼叫Ollama-LLM推理">¶</a>通过Rest API呼叫Ollama LLM推理</h3><p>如果你需要集成到第三方服务中(如alibaba cloud nacos)，Ollama可以直接通过Rest API 指定Model进行推论，通过CURL调用：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">curl http://127.0.0.1:11434/api/generate -d &#x27;&#123;</span><br><span class="line">&quot;model&quot;: &quot;llama3.2&quot;,</span><br><span class="line">&quot;stream&quot;: false,</span><br><span class="line">&quot;prompt&quot;: &quot;您是Ollama方面的大语言模型专家，请给一位刚入门的小白讲解如何使用Ollama&quot;</span><br><span class="line">&#125;&#x27;</span><br></pre></td></tr></table></figure><p>也可以通过对话的方式进行</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">curl http://127.0.0.1:11434/api/chat -d &#x27;&#123;</span><br><span class="line">&quot;model&quot;: &quot;llama3.2&quot;,</span><br><span class="line">&quot;stream&quot;: false,</span><br><span class="line">&quot;messages&quot;: [&#123;&quot;role&quot;:&quot;user&quot;,&quot;content&quot;:&quot;您是Ollama方面的大语言模型专家，请给一位刚入门的小白讲解如何使用Ollama&quot;&#125;]</span><br><span class="line">&#125;&#x27;</span><br></pre></td></tr></table></figure><p><img src="/img/ollama/chat.png" alt="chat.png"></p><h3 id="Ollama执行llama-3-2-3b在GPU的耗能情况"><a class="header-anchor" href="#Ollama执行llama-3-2-3b在GPU的耗能情况">¶</a>Ollama执行llama 3.2 3b在GPU的耗能情况</h3><p>2024 NVIDIA Compoutex黄仁勋执行长发表了<a href="https://www.nvidia.com/zh-tw/ai/">NIM架构</a>，使得使用者可以在云端或自己的服务器建立AI推论微服务，并且可以整合K8S云原生动态扩展机制。</p><p><img src="/img/ollama/NIM.png" alt="NIM.png"></p><p>可以由如下命令查看云服务器下GPU的编排资源情况：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker run --run --runtime=nvidia --gpus all ubuntu nvidia-smi</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;现在的AI技术发展真是一日千里，在目前企业庞大的资金博弈的前提下，拼的是谁的能耗成本更低、速度更快、效率更高、迭代更友好，谁率先打破摩尔定律，谁将会成为事实上的标准。作为普通程序员只能被动作为旁观者参与其中。先让子弹飞一会。&lt;/p&gt;
&lt;/blockquote&gt;</summary>
    
    
    <content src="https://galudisu.info/%3Cblockquote%3E%3Cp%3E%E7%8E%B0%E5%9C%A8%E7%9A%84AI%E6%8A%80%E6%9C%AF%E5%8F%91%E5%B1%95%E7%9C%9F%E6%98%AF%E4%B8%80%E6%97%A5%E5%8D%83%E9%87%8C%EF%BC%8C%E5%9C%A8%E7%9B%AE%E5%89%8D%E4%BC%81%E4%B8%9A%E5%BA%9E%E5%A4%A7%E7%9A%84%E8%B5%84%E9%87%91%E5%8D%9A%E5%BC%88%E7%9A%84%E5%89%8D%E6%8F%90%E4%B8%8B%EF%BC%8C%E6%8B%BC%E7%9A%84%E6%98%AF%E8%B0%81%E7%9A%84%E8%83%BD%E8%80%97%E6%88%90%E6%9C%AC%E6%9B%B4%E4%BD%8E%E3%80%81%E9%80%9F%E5%BA%A6%E6%9B%B4%E5%BF%AB%E3%80%81%E6%95%88%E7%8E%87%E6%9B%B4%E9%AB%98%E3%80%81%E8%BF%AD%E4%BB%A3%E6%9B%B4%E5%8F%8B%E5%A5%BD%EF%BC%8C%E8%B0%81%E7%8E%87%E5%85%88%E6%89%93%E7%A0%B4%E6%91%A9%E5%B0%94%E5%AE%9A%E5%BE%8B%EF%BC%8C%E8%B0%81%E5%B0%86%E4%BC%9A%E6%88%90%E4%B8%BA%E4%BA%8B%E5%AE%9E%E4%B8%8A%E7%9A%84%E6%A0%87%E5%87%86%E3%80%82%E4%BD%9C%E4%B8%BA%E6%99%AE%E9%80%9A%E7%A8%8B%E5%BA%8F%E5%91%98%E5%8F%AA%E8%83%BD%E8%A2%AB%E5%8A%A8%E4%BD%9C%E4%B8%BA%E6%97%81%E8%A7%82%E8%80%85%E5%8F%82%E4%B8%8E%E5%85%B6%E4%B8%AD%E3%80%82%E5%85%88%E8%AE%A9%E5%AD%90%E5%BC%B9%E9%A3%9E%E4%B8%80%E4%BC%9A%E3%80%82%3C/p%3E%3C/blockquote%3E%3Cspan%20id=%22more%22%3E%3C/span%3E%3Ch3%20id=%22Ollama-%E4%BB%8B%E7%BB%8D%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#Ollama-%E4%BB%8B%E7%BB%8D%22%3E%C2%B6%3C/a%3EOllama%20%E4%BB%8B%E7%BB%8D%3C/h3%3E%3Cp%3E%3Ca%20href=%22https:/ollama.com%22%3EOllama%3C/a%3E%E6%98%AF%E4%B8%80%E4%B8%AA%E4%B8%93%E6%B3%A8%E4%BA%8E%E5%A4%A7%E8%AF%AD%E8%A8%80%E6%A8%A1%E5%9E%8B(LLM,%20Large%20Language%20Models)%E5%BA%94%E7%94%A8%E7%9A%84%E5%BC%80%E6%BA%90%E6%96%B9%E6%A1%88%EF%BC%8C%E6%97%A8%E5%9C%A8%E5%B8%AE%E5%8A%A9%E5%BC%80%E5%8F%91%E8%80%85%E8%BD%BB%E6%9D%BE%E9%83%A8%E7%BD%B2%E5%92%8C%E4%BD%BF%E7%94%A8%E7%A7%81%E6%9C%89%E7%9A%84%E5%A4%A7%E5%9E%8B%E8%AF%AD%E8%A8%80%E6%A8%A1%E5%9E%8B%EF%BC%8C%E8%80%8C%E6%97%A0%E9%9C%80%E4%BE%9D%E8%B5%96%E5%A4%96%E9%83%A8%E7%9A%84%E4%BA%91%E7%AB%AF%E6%9C%8D%E5%8A%A1%E6%88%96%E5%A4%96%E9%83%A8API%EF%BC%8C%E8%BF%99%E4%BA%9B%E6%A8%A1%E5%9E%8B%E4%B8%8D%E4%BB%85%E4%BB%85%E5%8F%AA%E6%9C%89%E5%8C%85%E6%8B%ACMeta%20Llama%20Model%EF%BC%8C%E4%B9%9F%E6%8F%90%E4%BE%9B%E5%85%B6%E4%BB%96%E4%B8%80%E4%BA%9BOpen%20LLM%20Model%EF%BC%8C%E5%83%8F%E6%98%AFLlama%203.3%EF%BC%8CPhi%203%EF%BC%8CMistral%EF%BC%8CGemma%202%E3%80%82%E8%AF%A5%E6%96%B9%E6%A1%88%E7%9A%84%E6%A0%B8%E5%BF%83%E7%9B%AE%E7%9A%84%E6%98%AF%E6%8F%90%E4%BE%9B%E9%AB%98%E6%95%88%E3%80%81%E5%AE%89%E5%85%A8%E3%80%81%E5%8F%AF%E6%8E%A7%E7%9A%84LLM%E6%8E%A8%E8%AE%BA%E7%8E%AF%E5%A2%83%E5%BB%BA%E5%88%B6%E3%80%82%E5%A4%A7%E8%87%B4%E4%B8%8A%E6%9C%89%E4%BB%A5%E4%B8%8B%E7%89%B9%E6%80%A7%EF%BC%9A%3C/p%3E%3Ch4%20id=%22%E9%87%87%E7%94%A8%E6%9C%AC%E5%9C%B0%E6%9C%BA%E5%99%A8%E8%BF%90%E8%A1%8C%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E9%87%87%E7%94%A8%E6%9C%AC%E5%9C%B0%E6%9C%BA%E5%99%A8%E8%BF%90%E8%A1%8C%22%3E%C2%B6%3C/a%3E%E9%87%87%E7%94%A8%E6%9C%AC%E5%9C%B0%E6%9C%BA%E5%99%A8%E8%BF%90%E8%A1%8C%3C/h4%3E%3Cp%3EOllama%E6%94%AF%E6%8C%81%E5%9C%A8%E8%87%AA%E5%B7%B1%E7%9A%84%E8%AE%BE%E5%A4%87%E4%B8%8A%E8%BD%BD%E5%85%A5%E6%A8%A1%E5%9E%8B%EF%BC%8C%E6%97%A0%E9%9C%80%E5%B0%86%E6%95%B0%E6%8D%AE%E4%B8%8A%E4%BC%A0%E8%87%B3%E4%BA%91%E7%AB%AF%EF%BC%8C%E7%A1%AE%E4%BF%9D%E6%95%B0%E6%8D%AE%E9%9A%90%E7%A7%81%E4%B8%8E%E5%AE%89%E5%85%A8%E3%80%82%3C/p%3E%3Cp%3E%E9%80%9A%E8%BF%87%E4%BC%98%E5%8C%96%E6%A8%A1%E5%9E%8B%E8%BF%90%E8%A1%8C%E6%95%88%E7%8E%87%EF%BC%8C%E5%8D%B3%E4%BD%BF%E5%9C%A8%E8%B5%84%E6%BA%90%E6%9C%89%E9%99%90%E7%9A%84%E8%AE%BE%E5%A4%87%E4%B8%8A%E4%B9%9F%E8%83%BD%E6%B5%81%E7%95%85%E8%BF%9B%E8%A1%8C%E6%8E%A8%E8%AE%BA%E3%80%82%3C/p%3E%3Ch4%20id=%22%E5%BC%80%E6%BA%90%E4%B8%8E%E5%8F%AF%E5%AE%9A%E5%88%B6%E5%8C%96%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E5%BC%80%E6%BA%90%E4%B8%8E%E5%8F%AF%E5%AE%9A%E5%88%B6%E5%8C%96%22%3E%C2%B6%3C/a%3E%E5%BC%80%E6%BA%90%E4%B8%8E%E5%8F%AF%E5%AE%9A%E5%88%B6%E5%8C%96%3C/h4%3E%3Cp%3EOllama%E6%98%AF%E4%B8%80%E4%B8%AA%E9%87%87%E7%94%A8MIT%20License%E7%9A%84%E5%BC%80%E6%BA%90%E6%96%B9%E6%A1%88%EF%BC%8C%E5%85%81%E8%AE%B8%E5%BC%80%E5%8F%91%E8%80%85%E6%A0%B9%E6%8D%AE%E8%87%AA%E5%B7%B1%E7%9A%84%E9%9C%80%E6%B1%82%E8%BF%9B%E8%A1%8C%E4%BF%AE%E6%94%B9%E4%B8%8E%E6%89%A9%E5%B1%95%E3%80%82%E5%BC%80%E5%8F%91%E8%80%85%E5%8F%AF%E4%BB%A5%E5%B0%86%E5%85%B6%E4%B8%8E%E5%85%B6%E4%BB%96%E5%BA%94%E7%94%A8%E6%95%B4%E5%90%88%EF%BC%8C%E5%88%9B%E5%BB%BA%E8%87%AA%E5%AE%9A%E4%B9%89%E7%9A%84AI%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88%E3%80%82%3C/p%3E%3Ch4%20id=%22%E6%94%AF%E6%8C%81%E8%B7%A8%E5%B9%B3%E5%8F%B0%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E6%94%AF%E6%8C%81%E8%B7%A8%E5%B9%B3%E5%8F%B0%22%3E%C2%B6%3C/a%3E%E6%94%AF%E6%8C%81%E8%B7%A8%E5%B9%B3%E5%8F%B0%3C/h4%3E%3Cp%3E%E6%8F%90%E4%BE%9B%E9%92%88%E5%AF%B9%E5%AF%B9%E4%B8%AD%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F(%E5%A6%82Windows%E3%80%81macOS%E5%92%8CLinux)%E7%9A%84%E6%94%AF%E6%8C%81%EF%BC%8C%E4%BD%BF%E5%85%B6%E8%83%BD%E5%A4%9F%E9%80%82%E5%BA%94%E4%B8%8D%E5%90%8C%E7%9A%84%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83%E3%80%82%3C/p%3E%3Ch4%20id=%22%E6%8F%90%E4%BE%9BAPI%E5%BC%80%E5%8F%91%E4%B8%8E%E6%95%B4%E5%90%88%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E6%8F%90%E4%BE%9BAPI%E5%BC%80%E5%8F%91%E4%B8%8E%E6%95%B4%E5%90%88%22%3E%C2%B6%3C/a%3E%E6%8F%90%E4%BE%9BAPI%E5%BC%80%E5%8F%91%E4%B8%8E%E6%95%B4%E5%90%88%3C/h4%3E%3Cp%3E%E6%8F%90%E4%BE%9B%E7%AE%80%E5%8D%95%E6%98%93%E7%94%A8%E7%9A%84API%E5%92%8C%E5%B7%A5%E5%85%B7%EF%BC%8C%E5%B8%AE%E5%8A%A9%E5%BC%80%E5%8F%91%E8%80%85%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E8%AF%AD%E8%A8%80%E6%A8%A1%E5%9E%8B%E5%8A%9F%E8%83%BD%E5%88%B0%E4%BB%96%E4%BB%AC%E7%9A%84%E5%BA%94%E7%94%A8%E4%B8%AD%E3%80%82%3C/p%3E%3Ch4%20id=%22%E9%9A%90%E7%A7%81%E4%B8%8E%E5%AE%89%E5%85%A8%E6%80%A7%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E9%9A%90%E7%A7%81%E4%B8%8E%E5%AE%89%E5%85%A8%E6%80%A7%22%3E%C2%B6%3C/a%3E%E9%9A%90%E7%A7%81%E4%B8%8E%E5%AE%89%E5%85%A8%E6%80%A7%3C/h4%3E%3Cp%3E%E7%94%B1%E4%BA%8E%E6%89%80%E6%9C%89%E8%BF%90%E7%AE%97%E9%83%BD%E5%9C%A8%E6%9C%AC%E5%9C%B0%E5%AE%8C%E6%88%90%EF%BC%8C%E6%97%A0%E9%9C%80%E4%BE%9D%E8%B5%96%E5%A4%96%E9%83%A8%E6%9C%8D%E5%8A%A1%E5%99%A8%EF%BC%8C%E6%95%B0%E6%8D%AE%E6%B3%84%E9%9C%B2%E7%9A%84%E9%A3%8E%E9%99%A9%E5%A4%A7%E5%A4%A7%E9%99%8D%E4%BD%8E%E3%80%82%3C/p%3E%3Cp%3EOllama%20%E7%9A%84%E5%87%BA%E7%8E%B0%E6%BB%A1%E8%B6%B3%E4%BA%86%E5%AF%B9%E6%95%B0%E6%8D%AE%E6%95%8F%E6%84%9F%E6%80%A7%E9%AB%98%E6%88%96%E5%AF%B9%E4%BA%91%E7%AB%AF%E4%BE%9D%E8%B5%96%E6%80%A7%E6%9C%89%E9%99%90%E7%9A%84%E5%BA%94%E7%94%A8%E9%9C%80%E6%B1%82%EF%BC%8C%E5%A6%82%E4%BC%81%E4%B8%9A%E5%86%85%E9%83%A8%E5%B7%A5%E5%85%B7%E3%80%81%E6%95%99%E8%82%B2%E5%BA%94%E7%94%A8%E6%88%96%E4%B8%AA%E4%BA%BA%E9%9A%90%E7%A7%81%E4%BF%9D%E6%8A%A4%E9%9C%80%E6%B1%82%E3%80%82%E5%A6%82%E6%9E%9C%E9%9C%80%E8%A6%81%E6%9B%B4%E6%B7%B1%E5%85%A5%E7%9A%84%E6%8A%80%E6%9C%AF%E7%BB%86%E8%8A%82%E6%88%96%E5%85%B7%E4%BD%93%E7%9A%84%E4%BD%BF%E7%94%A8%E6%A1%88%E4%BE%8B%EF%BC%8C%E5%8F%AF%E4%BB%A5%E5%8F%82%E8%80%83%E8%AF%A5%E4%B8%93%E6%A1%88%E7%9A%84%3Ca%20href=%22ollama.com/blog%22%3E%E5%AE%98%E6%96%B9%E6%96%87%E6%A1%A3%3C/a%3E%E6%88%96%3Ca%20href=%22https:/github.com/ollama/ollama%22%3EGithub%3C/a%3E%E9%A1%B5%E9%9D%A2%E3%80%82%3C/p%3E%3Ch3%20id=%22Ubuntu-Linux-%E5%AE%89%E8%A3%85Ollama%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#Ubuntu-Linux-%E5%AE%89%E8%A3%85Ollama%22%3E%C2%B6%3C/a%3EUbuntu%20Linux%20%E5%AE%89%E8%A3%85Ollama%3C/h3%3E%3Cp%3EUbuntu%E5%8F%AF%E9%80%9A%E8%BF%87%E5%AE%98%E6%96%B9%E6%A0%87%E5%87%86%E8%84%9A%E6%9C%AC%E8%BF%9B%E8%A1%8C%E5%AE%89%E8%A3%85%EF%BC%8C%E6%96%B9%E6%B3%95%E5%A6%82%E4%B8%8B%EF%BC%9A%3C/p%3E%3Cfigure%20class=%22highlight%20shell%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E8%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E9%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E10%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E11%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E12%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E13%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E14%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E15%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E16%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E17%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E18%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E19%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3Esudo%20apt-get%20update%20-y%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3Esudo%20apt-get%20install%20curl%20-y%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3Esudo%20curl%20-fsSL%20https:/ollama.com/install.sh%20|%20sh%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22meta%20prompt_%22%3E%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22meta%20prompt_%22%3E&amp;gt;%3C/span%3E%3Cspan%20class=%22language-bash%22%3E&amp;gt;&amp;gt;%20Installing%20ollama%20to%20/usr/local%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22meta%20prompt_%22%3E&amp;gt;%3C/span%3E%3Cspan%20class=%22language-bash%22%3E&amp;gt;&amp;gt;%20Downloading%20ollama-linux-amd64.tar.zst%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22meta%20prompt_%22%3E#%3C/span%3E%3Cspan%20class=%22language-bash%22%3E%3Cspan%20class=%22comment%22%3E#######################################################################%20100.0%%3C/span%3E%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22meta%20prompt_%22%3E&amp;gt;%3C/span%3E%3Cspan%20class=%22language-bash%22%3E&amp;gt;&amp;gt;%20Creating%20ollama%20user...%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22meta%20prompt_%22%3E&amp;gt;%3C/span%3E%3Cspan%20class=%22language-bash%22%3E&amp;gt;&amp;gt;%20Adding%20ollama%20user%20to%20render%20group...%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22meta%20prompt_%22%3E&amp;gt;%3C/span%3E%3Cspan%20class=%22language-bash%22%3E&amp;gt;&amp;gt;%20Adding%20ollama%20user%20to%20video%20group...%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22meta%20prompt_%22%3E&amp;gt;%3C/span%3E%3Cspan%20class=%22language-bash%22%3E&amp;gt;&amp;gt;%20Adding%20current%20user%20to%20ollama%20group...%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22meta%20prompt_%22%3E&amp;gt;%3C/span%3E%3Cspan%20class=%22language-bash%22%3E&amp;gt;&amp;gt;%20Creating%20ollama%20systemd%20service...%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22meta%20prompt_%22%3E&amp;gt;%3C/span%3E%3Cspan%20class=%22language-bash%22%3E&amp;gt;&amp;gt;%20Enabling%20and%20starting%20ollama%20service...%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3ECreated%20symlink%20/etc/systemd/system/default.target.wants/ollama.service%20%E2%86%92%20/etc/systemd/system/ollama.service.%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22meta%20prompt_%22%3E&amp;gt;%3C/span%3E%3Cspan%20class=%22language-bash%22%3E&amp;gt;&amp;gt;%20Downloading%20ollama-linux-amd64-rocm.tar.zst%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22meta%20prompt_%22%3E#%3C/span%3E%3Cspan%20class=%22language-bash%22%3E%3Cspan%20class=%22comment%22%3E#######################################################################%20100.0%%3C/span%3E%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22meta%20prompt_%22%3E&amp;gt;%3C/span%3E%3Cspan%20class=%22language-bash%22%3E&amp;gt;&amp;gt;%20The%20Ollama%20API%20is%20now%20available%20at%20127.0.0.1:11434.%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22meta%20prompt_%22%3E&amp;gt;%3C/span%3E%3Cspan%20class=%22language-bash%22%3E&amp;gt;&amp;gt;%20Install%20complete.%20Run%20%3Cspan%20class=%22string%22%3E&amp;quot;ollama&amp;quot;%3C/span%3E%20from%20the%20%3Cspan%20class=%22built_in%22%3Ecommand%3C/span%3E%20line.%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22meta%20prompt_%22%3E&amp;gt;%3C/span%3E%3Cspan%20class=%22language-bash%22%3E&amp;gt;&amp;gt;%20AMD%20GPU%20ready.%3C/span%3E%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Ch4%20id=%22%E5%90%AF%E5%8A%A8Ollama%E6%9C%8D%E5%8A%A1%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E5%90%AF%E5%8A%A8Ollama%E6%9C%8D%E5%8A%A1%22%3E%C2%B6%3C/a%3E%E5%90%AF%E5%8A%A8Ollama%E6%9C%8D%E5%8A%A1%3C/h4%3E%3Cp%3E%E8%84%9A%E6%9C%AC%E6%89%A7%E8%A1%8C%E5%AE%8C%E6%88%90%E6%9C%8D%E5%8A%A1%E5%B7%B2%E6%B3%A8%E5%86%8C%E5%85%A5systemd%E5%B9%B6%E5%90%AF%E5%8A%A8%EF%BC%8C%E6%89%A7%E8%A1%8C%E5%A6%82%E4%B8%8B%E5%91%BD%E4%BB%A4%E6%9F%A5%E7%9C%8B%E6%A8%A1%E5%9E%8B%E5%88%97%E8%A1%A8%EF%BC%9A%3C/p%3E%3Cfigure%20class=%22highlight%20shell%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3Eollama%20list%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Ch4%20id=%22Ollama-pull-%E4%B8%8B%E8%BD%BD-llama-3-2-3b%E6%A8%A1%E5%9E%8B%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#Ollama-pull-%E4%B8%8B%E8%BD%BD-llama-3-2-3b%E6%A8%A1%E5%9E%8B%22%3E%C2%B6%3C/a%3EOllama%20pull%20%E4%B8%8B%E8%BD%BD%20llama%203.2%203b%E6%A8%A1%E5%9E%8B%3C/h4%3E%3Cp%3E%E4%B8%8A%E9%9D%A2%E7%9A%84%E6%9C%8D%E5%8A%A1%E4%B8%8D%E8%83%BD%E5%85%B3%E6%8E%89%EF%BC%8C%E7%84%B6%E5%90%8E%E6%8C%89%E7%85%A7%E5%AE%98%E6%96%B9%E7%9A%84doc%E4%BB%8B%E7%BB%8D%EF%BC%8C%E6%89%A7%E8%A1%8C%3Ccode%3Eollama%20pull%20llama3.2%3C/code%3E%E5%B0%B1%E4%BC%9A%E4%B8%8B%E8%BD%BD%E6%A8%A1%E5%9E%8B%E4%BA%86%EF%BC%8C%E9%9C%80%E8%A6%812GB%E5%B7%A6%E5%8F%B3%E7%9A%84%E7%A3%81%E7%9B%98%E7%A9%BA%E9%97%B4%EF%BC%8C%E4%B8%8D%E6%8C%87%E5%AE%9A%E7%89%88%E6%9C%AC%E7%9A%84%E8%AF%9D%E9%A2%84%E8%AE%BE%E6%98%AF3b%E7%9A%84%E6%A8%A1%E5%9E%8B%EF%BC%8C%E5%8F%AF%E4%BB%A5%E5%8D%95%E7%94%A8CPU%E6%89%A7%E8%A1%8C%EF%BC%8C%E5%A6%82%E6%9E%9C%E6%9C%89GPU%E7%9A%84%E8%AF%9D%E5%A4%A7%E7%BA%A6%E9%9C%80%E8%A6%814GB%E7%9A%84VRAM%E5%8D%B3%E5%8F%AF%EF%BC%8C%E4%B8%8B%E8%BD%BD%E5%AE%8C%E6%88%90%E5%90%8E%E7%9A%84%E7%94%BB%E9%9D%A2%E5%A6%82%E4%B8%8B%EF%BC%9A%3C/p%3E%3Cfigure%20class=%22highlight%20shell%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3Eollama%20pull%20llama3.2%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Cp%3E%3Cimg%20src=%22/img/ollama/llama-3-2.png%22%20alt=%22llama-3-2.png%22%3E%3C/p%3E%3Cp%3E%E5%AE%8C%E6%88%90%E4%BB%A5%E5%90%8E%E4%B9%9F%E5%8F%AF%E4%BB%A5%E9%80%8F%E8%BF%87%3Ccode%3Eollama%20list%3C/code%3E%E5%88%97%E5%87%BA%E5%8F%AF%E7%94%A8%E7%9A%84%E6%A8%A1%E5%9E%8B%EF%BC%8C%E6%A6%82%E5%BF%B5%E4%B8%8EDocker%20Image%E4%B8%80%E6%A0%B7%EF%BC%8C%3C/p%3E%3Cfigure%20class=%22highlight%20shell%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3Eollama%20list%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Cp%3E%3Cimg%20src=%22/img/ollama/model-list.png%22%20alt=%22model-list.png%22%3E%3C/p%3E%3Ch3%20id=%22%E9%80%9A%E8%BF%87%E6%8F%90%E7%A4%BA%E8%AF%8D%E8%B0%83%E7%94%A8Ollama-LL%E6%8E%A8%E7%90%86%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E9%80%9A%E8%BF%87%E6%8F%90%E7%A4%BA%E8%AF%8D%E8%B0%83%E7%94%A8Ollama-LL%E6%8E%A8%E7%90%86%22%3E%C2%B6%3C/a%3E%E9%80%9A%E8%BF%87%E6%8F%90%E7%A4%BA%E8%AF%8D%E8%B0%83%E7%94%A8Ollama%20LL%E6%8E%A8%E7%90%86%3C/h3%3E%3Cfigure%20class=%22highlight%20shell%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E8%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E9%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E10%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E11%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E12%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E13%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3Eollama%20run%20llama3.2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22meta%20prompt_%22%3E&amp;gt;%3C/span%3E%3Cspan%20class=%22language-bash%22%3E&amp;gt;&amp;gt;%20%E6%82%A8%E6%98%AFOllama%E6%96%B9%E9%9D%A2%E7%9A%84%E5%A4%A7%E8%AF%AD%E8%A8%80%E6%A8%A1%E5%9E%8B%E4%B8%93%E5%AE%B6%EF%BC%8C%E8%AF%B7%E7%BB%99%E4%B8%80%E4%BD%8D%E5%88%9A%E5%85%A5%E9%97%A8%E7%9A%84%E5%B0%8F%E7%99%BD%E8%AE%B2%E8%A7%A3%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8Ollama%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%E5%A5%BD%E7%9A%84%EF%BC%81%E6%88%91%E6%98%AFOllama%E7%9A%84%E8%AF%AD%E8%A8%80%E6%A8%A1%E5%9E%8B%E4%B8%93%E5%AE%B6%EF%BC%8C%E7%8E%B0%E5%9C%A8%E8%AE%A9%E6%88%91%E4%BB%AC%E6%9D%A5%E4%BA%86%E8%A7%A3%E4%B8%80%E4%B8%8B%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8Ollama%EF%BC%9A%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E**1.%20%E4%BB%80%E4%B9%88%E6%98%AFOllama%EF%BC%9F**%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3EOllama%E6%98%AF%E4%B8%80%E7%A7%8D%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0%E6%A8%A1%E5%9E%8B%EF%BC%8C%E5%B0%A4%E5%85%B6%E9%80%82%E5%90%88%E8%87%AA%E7%84%B6languageprocessing%EF%BC%88NLP%EF%BC%89%E4%BB%BB%E5%8A%A1%EF%BC%8C%E5%A6%82%E9%97%AE%E7%AD%94%E3%80%81%E7%BF%BB%E8%AF%91%E3%80%81%E8%AF%AD%E4%B9%89%E5%88%86%E6%9E%90%E7%AD%89%E3%80%82%E5%AE%83%E8%83%BD%E5%A4%9F%E7%90%86%E8%A7%A3%E5%92%8C%E7%94%9F%E6%88%90%E4%BA%BA%E7%B1%BB%E8%AF%AD%E8%A8%80%E3%80%82%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E**2.%20%E5%A6%82%E4%BD%95%E8%BF%9B%E5%85%A5Ollama%E7%9A%84%E7%8E%AF%E5%A2%83%EF%BC%9F**%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%E4%BD%A0%E9%9C%80%E8%A6%81%E4%B8%80%E4%B8%AA%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%88%96%E7%A7%BB%E5%8A%A8%E8%AE%BE%E5%A4%87%EF%BC%8C%E5%B9%B6%E5%AE%89%E8%A3%85%E4%BA%86Python%E5%92%8CTensorFlow%E6%88%96PyTorch%E7%AD%89%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0%E6%A1%86%E6%9E%B6%E3%80%82%E5%9C%A8%E7%BB%88%E7%AB%AF%E6%88%96%E5%91%BD%E4%BB%A4%E8%A1%8C%E6%A8%A1%E5%BC%8F%E4%B8%8B%E8%BE%93%E5%85%A5%E4%BB%A5%E4%B8%8B%E5%91%BD%E4%BB%A4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E...%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E...%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Ch3%20id=%22%E9%80%9A%E8%BF%87Rest-API%E5%91%BC%E5%8F%ABOllama-LLM%E6%8E%A8%E7%90%86%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E9%80%9A%E8%BF%87Rest-API%E5%91%BC%E5%8F%ABOllama-LLM%E6%8E%A8%E7%90%86%22%3E%C2%B6%3C/a%3E%E9%80%9A%E8%BF%87Rest%20API%E5%91%BC%E5%8F%ABOllama%20LLM%E6%8E%A8%E7%90%86%3C/h3%3E%3Cp%3E%E5%A6%82%E6%9E%9C%E4%BD%A0%E9%9C%80%E8%A6%81%E9%9B%86%E6%88%90%E5%88%B0%E7%AC%AC%E4%B8%89%E6%96%B9%E6%9C%8D%E5%8A%A1%E4%B8%AD(%E5%A6%82alibaba%20cloud%20nacos)%EF%BC%8COllama%E5%8F%AF%E4%BB%A5%E7%9B%B4%E6%8E%A5%E9%80%9A%E8%BF%87Rest%20API%20%E6%8C%87%E5%AE%9AModel%E8%BF%9B%E8%A1%8C%E6%8E%A8%E8%AE%BA%EF%BC%8C%E9%80%9A%E8%BF%87CURL%E8%B0%83%E7%94%A8%EF%BC%9A%3C/p%3E%3Cfigure%20class=%22highlight%20shell%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3Ecurl%20http:/127.0.0.1:11434/api/generate%20-d%20&amp;#x27;&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;quot;model&amp;quot;:%20&amp;quot;llama3.2&amp;quot;,%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;quot;stream&amp;quot;:%20false,%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;quot;prompt&amp;quot;:%20&amp;quot;%E6%82%A8%E6%98%AFOllama%E6%96%B9%E9%9D%A2%E7%9A%84%E5%A4%A7%E8%AF%AD%E8%A8%80%E6%A8%A1%E5%9E%8B%E4%B8%93%E5%AE%B6%EF%BC%8C%E8%AF%B7%E7%BB%99%E4%B8%80%E4%BD%8D%E5%88%9A%E5%85%A5%E9%97%A8%E7%9A%84%E5%B0%8F%E7%99%BD%E8%AE%B2%E8%A7%A3%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8Ollama&amp;quot;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;&amp;#x27;%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Cp%3E%E4%B9%9F%E5%8F%AF%E4%BB%A5%E9%80%9A%E8%BF%87%E5%AF%B9%E8%AF%9D%E7%9A%84%E6%96%B9%E5%BC%8F%E8%BF%9B%E8%A1%8C%3C/p%3E%3Cfigure%20class=%22highlight%20shell%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3Ecurl%20http:/127.0.0.1:11434/api/chat%20-d%20&amp;#x27;&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;quot;model&amp;quot;:%20&amp;quot;llama3.2&amp;quot;,%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;quot;stream&amp;quot;:%20false,%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;quot;messages&amp;quot;:%20[&amp;#123;&amp;quot;role&amp;quot;:&amp;quot;user&amp;quot;,&amp;quot;content&amp;quot;:&amp;quot;%E6%82%A8%E6%98%AFOllama%E6%96%B9%E9%9D%A2%E7%9A%84%E5%A4%A7%E8%AF%AD%E8%A8%80%E6%A8%A1%E5%9E%8B%E4%B8%93%E5%AE%B6%EF%BC%8C%E8%AF%B7%E7%BB%99%E4%B8%80%E4%BD%8D%E5%88%9A%E5%85%A5%E9%97%A8%E7%9A%84%E5%B0%8F%E7%99%BD%E8%AE%B2%E8%A7%A3%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8Ollama&amp;quot;&amp;#125;]%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;&amp;#x27;%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Cp%3E%3Cimg%20src=%22/img/ollama/chat.png%22%20alt=%22chat.png%22%3E%3C/p%3E%3Ch3%20id=%22Ollama%E6%89%A7%E8%A1%8Cllama-3-2-3b%E5%9C%A8GPU%E7%9A%84%E8%80%97%E8%83%BD%E6%83%85%E5%86%B5%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#Ollama%E6%89%A7%E8%A1%8Cllama-3-2-3b%E5%9C%A8GPU%E7%9A%84%E8%80%97%E8%83%BD%E6%83%85%E5%86%B5%22%3E%C2%B6%3C/a%3EOllama%E6%89%A7%E8%A1%8Cllama%203.2%203b%E5%9C%A8GPU%E7%9A%84%E8%80%97%E8%83%BD%E6%83%85%E5%86%B5%3C/h3%3E%3Cp%3E2024%20NVIDIA%20Compoutex%E9%BB%84%E4%BB%81%E5%8B%8B%E6%89%A7%E8%A1%8C%E9%95%BF%E5%8F%91%E8%A1%A8%E4%BA%86%3Ca%20href=%22https:/www.nvidia.com/zh-tw/ai/%22%3ENIM%E6%9E%B6%E6%9E%84%3C/a%3E%EF%BC%8C%E4%BD%BF%E5%BE%97%E4%BD%BF%E7%94%A8%E8%80%85%E5%8F%AF%E4%BB%A5%E5%9C%A8%E4%BA%91%E7%AB%AF%E6%88%96%E8%87%AA%E5%B7%B1%E7%9A%84%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%BB%BA%E7%AB%8BAI%E6%8E%A8%E8%AE%BA%E5%BE%AE%E6%9C%8D%E5%8A%A1%EF%BC%8C%E5%B9%B6%E4%B8%94%E5%8F%AF%E4%BB%A5%E6%95%B4%E5%90%88K8S%E4%BA%91%E5%8E%9F%E7%94%9F%E5%8A%A8%E6%80%81%E6%89%A9%E5%B1%95%E6%9C%BA%E5%88%B6%E3%80%82%3C/p%3E%3Cp%3E%3Cimg%20src=%22/img/ollama/NIM.png%22%20alt=%22NIM.png%22%3E%3C/p%3E%3Cp%3E%E5%8F%AF%E4%BB%A5%E7%94%B1%E5%A6%82%E4%B8%8B%E5%91%BD%E4%BB%A4%E6%9F%A5%E7%9C%8B%E4%BA%91%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%8BGPU%E7%9A%84%E7%BC%96%E6%8E%92%E8%B5%84%E6%BA%90%E6%83%85%E5%86%B5%EF%BC%9A%3C/p%3E%3Cfigure%20class=%22highlight%20shell%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3Edocker%20run%20--run%20--runtime=nvidia%20--gpus%20all%20ubuntu%20nvidia-smi%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E" type="image"/>
    
    
    
    <category term="ollama" scheme="https://galudisu.info/tags/ollama/"/>
    
    <category term="llama3" scheme="https://galudisu.info/tags/llama3/"/>
    
    <category term="openclaw" scheme="https://galudisu.info/tags/openclaw/"/>
    
    <category term="zeroclaw" scheme="https://galudisu.info/tags/zeroclaw/"/>
    
  </entry>
  
  <entry>
    <title>访问者模式(Visitor Pattern)</title>
    <link href="https://galudisu.info/2025/05/10/pattern/basic/behavioral/Visitor/"/>
    <id>https://galudisu.info/2025/05/10/pattern/basic/behavioral/Visitor/</id>
    <published>2025-05-10T12:25:11.000Z</published>
    <updated>2026-04-14T19:59:33.627Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>在访问者模式中，我们使用了一个访问者类，它改变了元素类的执行算法。通过这种方式，元素的执行算法可以随着访问者改变而改变。这种类型的设计模式属于行为模式。根据模式，元素对象已接受访问者对象，这样访问者对象就可以处理元素对象上的操作。</p></blockquote><img src="/assert/puml/df99695526e2d881ccb38411071c208f55f902787cea84f216f4473ea4f756b7.svg"/><span id="more"></span><h3 id="核心组成"><a class="header-anchor" href="#核心组成">¶</a>核心组成</h3><ol><li>访问者接口(Visitor)</li></ol><p>定义对每一个元素类可以执行的操作，通常按元素类型重载方式。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">Vistor</span> &#123;</span><br><span class="line">  <span class="keyword">void</span> <span class="title function_">visitConcreteElementA</span><span class="params">(ConcreteElementA elementA)</span>;</span><br><span class="line">  <span class="keyword">void</span> <span class="title function_">visitConcreteElementB</span><span class="params">(ConcreteElementB elementB)</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><ol start="2"><li>具体访问者类(Concrete Visitor)</li></ol><p>实现每个操作的具体逻辑。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">ConcreteVisitor</span> <span class="keyword">implements</span> <span class="title class_">Visitor</span> &#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">visitConcreteElementA</span><span class="params">(ConcreteElementA elementA)</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;访问者处理元素 A：&quot;</span> + elementA.operation());</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">visitConcreteElementB</span><span class="params">(ConcreteElementB elementB)</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;访问者处理元素 B：&quot;</span> + elementB.operation());</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><ol start="3"><li>元素接口(Element)</li></ol><p>声明一个接收访问者的方法<code>accept</code>。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">Element</span> &#123;</span><br><span class="line">    <span class="keyword">void</span> <span class="title function_">accept</span><span class="params">(Visitor visitor)</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><ol start="4"><li>具体元素类(Concrete Element)</li></ol><p>实现<code>accept</code>方法，调用访问者的对应方法。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">ConcreteElementA</span> <span class="keyword">implements</span> <span class="title class_">Element</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">operation</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;元素 A 的内容&quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">accept</span><span class="params">(Visitor visitor)</span> &#123;</span><br><span class="line">        visitor.visitConcreteElementA(<span class="built_in">this</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">ConcreteElementB</span> <span class="keyword">implements</span> <span class="title class_">Element</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">operation</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;元素 B 的内容&quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">accept</span><span class="params">(Visitor visitor)</span> &#123;</span><br><span class="line">        visitor.visitConcreteElementB(<span class="built_in">this</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><ol start="5"><li>对象结构(Object Structure)</li></ol><p>管理一组元素，并提供一个让访问者访问所有元素的接口。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> java.util.ArrayList;</span><br><span class="line"><span class="keyword">import</span> java.util.List;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">ObjectStructure</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> List&lt;Element&gt; elements = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">add</span><span class="params">(Element element)</span> &#123;</span><br><span class="line">        elements.add(element);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">accept</span><span class="params">(Visitor visitor)</span> &#123;</span><br><span class="line">        <span class="keyword">for</span> (Element element : elements) &#123;</span><br><span class="line">            element.accept(visitor);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><ol start="6"><li>客户端示例</li></ol><figure class="highlight kt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">val</span> structure = ObjectStructure()</span><br><span class="line">structure.add(ConcreteElementA())</span><br><span class="line">structure.add(ConcreteElementB())</span><br><span class="line"></span><br><span class="line"><span class="keyword">val</span> visitor = ConcreteVisitor()</span><br><span class="line">structure.accept(visitor)</span><br></pre></td></tr></table></figure><h3 id="适用场景"><a class="header-anchor" href="#适用场景">¶</a>适用场景</h3><ul><li>数据结构相对稳定，但对其操作经常扩展的系统。</li><li>编译器设计中用于遍历语法树。</li><li>报表生成、日志记录、渲染引擎等需统一处理多种对象的场景。</li></ul><h3 id="Java中的典型应用"><a class="header-anchor" href="#Java中的典型应用">¶</a>Java中的典型应用</h3><ul><li>Java编译器工具(如javac)使用访问者模式遍历AST(抽象语法树).</li><li>XML/JSON解析框架中对节点进行统一访问处理。</li><li>Spring框架中用于配置解析和依赖注入的访问逻辑。</li></ul><h3 id="变体与替代方案"><a class="header-anchor" href="#变体与替代方案">¶</a>变体与替代方案</h3><ul><li><strong>双亲派(Double Dispatch)</strong>： 访问者模式的核心机制。</li><li><strong>策略模式</strong>： 时和单一结构多算法，但不具备访问者对多种元素的支持能力。</li><li><strong>责任链模式</strong>： 侧重请求传递而非统一访问。</li></ul>]]></content>
    
    
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;在访问者模式中，我们使用了一个访问者类，它改变了元素类的执行算法。通过这种方式，元素的执行算法可以随着访问者改变而改变。这种类型的设计模式属于行为模式。根据模式，元素对象已接受访问者对象，这样访问者对象就可以处理元素对象上的操作。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;img src=&quot;/assert/puml/df99695526e2d881ccb38411071c208f55f902787cea84f216f4473ea4f756b7.svg&quot;/&gt;</summary>
    
    
    <content src="https://galudisu.info/%3Cblockquote%3E%3Cp%3E%E5%9C%A8%E8%AE%BF%E9%97%AE%E8%80%85%E6%A8%A1%E5%BC%8F%E4%B8%AD%EF%BC%8C%E6%88%91%E4%BB%AC%E4%BD%BF%E7%94%A8%E4%BA%86%E4%B8%80%E4%B8%AA%E8%AE%BF%E9%97%AE%E8%80%85%E7%B1%BB%EF%BC%8C%E5%AE%83%E6%94%B9%E5%8F%98%E4%BA%86%E5%85%83%E7%B4%A0%E7%B1%BB%E7%9A%84%E6%89%A7%E8%A1%8C%E7%AE%97%E6%B3%95%E3%80%82%E9%80%9A%E8%BF%87%E8%BF%99%E7%A7%8D%E6%96%B9%E5%BC%8F%EF%BC%8C%E5%85%83%E7%B4%A0%E7%9A%84%E6%89%A7%E8%A1%8C%E7%AE%97%E6%B3%95%E5%8F%AF%E4%BB%A5%E9%9A%8F%E7%9D%80%E8%AE%BF%E9%97%AE%E8%80%85%E6%94%B9%E5%8F%98%E8%80%8C%E6%94%B9%E5%8F%98%E3%80%82%E8%BF%99%E7%A7%8D%E7%B1%BB%E5%9E%8B%E7%9A%84%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E5%B1%9E%E4%BA%8E%E8%A1%8C%E4%B8%BA%E6%A8%A1%E5%BC%8F%E3%80%82%E6%A0%B9%E6%8D%AE%E6%A8%A1%E5%BC%8F%EF%BC%8C%E5%85%83%E7%B4%A0%E5%AF%B9%E8%B1%A1%E5%B7%B2%E6%8E%A5%E5%8F%97%E8%AE%BF%E9%97%AE%E8%80%85%E5%AF%B9%E8%B1%A1%EF%BC%8C%E8%BF%99%E6%A0%B7%E8%AE%BF%E9%97%AE%E8%80%85%E5%AF%B9%E8%B1%A1%E5%B0%B1%E5%8F%AF%E4%BB%A5%E5%A4%84%E7%90%86%E5%85%83%E7%B4%A0%E5%AF%B9%E8%B1%A1%E4%B8%8A%E7%9A%84%E6%93%8D%E4%BD%9C%E3%80%82%3C/p%3E%3C/blockquote%3E%3Cimg%20src=%22/assert/puml/df99695526e2d881ccb38411071c208f55f902787cea84f216f4473ea4f756b7.svg%22/%3E%3Cspan%20id=%22more%22%3E%3C/span%3E%3Ch3%20id=%22%E6%A0%B8%E5%BF%83%E7%BB%84%E6%88%90%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E6%A0%B8%E5%BF%83%E7%BB%84%E6%88%90%22%3E%C2%B6%3C/a%3E%E6%A0%B8%E5%BF%83%E7%BB%84%E6%88%90%3C/h3%3E%3Col%3E%3Cli%3E%E8%AE%BF%E9%97%AE%E8%80%85%E6%8E%A5%E5%8F%A3(Visitor)%3C/li%3E%3C/ol%3E%3Cp%3E%E5%AE%9A%E4%B9%89%E5%AF%B9%E6%AF%8F%E4%B8%80%E4%B8%AA%E5%85%83%E7%B4%A0%E7%B1%BB%E5%8F%AF%E4%BB%A5%E6%89%A7%E8%A1%8C%E7%9A%84%E6%93%8D%E4%BD%9C%EF%BC%8C%E9%80%9A%E5%B8%B8%E6%8C%89%E5%85%83%E7%B4%A0%E7%B1%BB%E5%9E%8B%E9%87%8D%E8%BD%BD%E6%96%B9%E5%BC%8F%E3%80%82%3C/p%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Einterface%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EVistor%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EvisitConcreteElementA%3C/span%3E%3Cspan%20class=%22params%22%3E(ConcreteElementA%20elementA)%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EvisitConcreteElementB%3C/span%3E%3Cspan%20class=%22params%22%3E(ConcreteElementB%20elementB)%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Col%20start=%222%22%3E%3Cli%3E%E5%85%B7%E4%BD%93%E8%AE%BF%E9%97%AE%E8%80%85%E7%B1%BB(Concrete%20Visitor)%3C/li%3E%3C/ol%3E%3Cp%3E%E5%AE%9E%E7%8E%B0%E6%AF%8F%E4%B8%AA%E6%93%8D%E4%BD%9C%E7%9A%84%E5%85%B7%E4%BD%93%E9%80%BB%E8%BE%91%E3%80%82%3C/p%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E8%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E9%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E10%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E11%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EConcreteVisitor%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eimplements%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EVisitor%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EvisitConcreteElementA%3C/span%3E%3Cspan%20class=%22params%22%3E(ConcreteElementA%20elementA)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20System.out.println(%3Cspan%20class=%22string%22%3E&amp;quot;%E8%AE%BF%E9%97%AE%E8%80%85%E5%A4%84%E7%90%86%E5%85%83%E7%B4%A0%20A%EF%BC%9A&amp;quot;%3C/span%3E%20+%20elementA.operation());%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EvisitConcreteElementB%3C/span%3E%3Cspan%20class=%22params%22%3E(ConcreteElementB%20elementB)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20System.out.println(%3Cspan%20class=%22string%22%3E&amp;quot;%E8%AE%BF%E9%97%AE%E8%80%85%E5%A4%84%E7%90%86%E5%85%83%E7%B4%A0%20B%EF%BC%9A&amp;quot;%3C/span%3E%20+%20elementB.operation());%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Col%20start=%223%22%3E%3Cli%3E%E5%85%83%E7%B4%A0%E6%8E%A5%E5%8F%A3(Element)%3C/li%3E%3C/ol%3E%3Cp%3E%E5%A3%B0%E6%98%8E%E4%B8%80%E4%B8%AA%E6%8E%A5%E6%94%B6%E8%AE%BF%E9%97%AE%E8%80%85%E7%9A%84%E6%96%B9%E6%B3%95%3Ccode%3Eaccept%3C/code%3E%E3%80%82%3C/p%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Einterface%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EElement%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Eaccept%3C/span%3E%3Cspan%20class=%22params%22%3E(Visitor%20visitor)%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Col%20start=%224%22%3E%3Cli%3E%E5%85%B7%E4%BD%93%E5%85%83%E7%B4%A0%E7%B1%BB(Concrete%20Element)%3C/li%3E%3C/ol%3E%3Cp%3E%E5%AE%9E%E7%8E%B0%3Ccode%3Eaccept%3C/code%3E%E6%96%B9%E6%B3%95%EF%BC%8C%E8%B0%83%E7%94%A8%E8%AE%BF%E9%97%AE%E8%80%85%E7%9A%84%E5%AF%B9%E5%BA%94%E6%96%B9%E6%B3%95%E3%80%82%3C/p%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E8%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E9%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E10%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E11%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E12%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E13%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E14%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E15%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E16%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E17%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E18%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E19%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E21%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E22%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EConcreteElementA%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eimplements%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EElement%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20String%20%3Cspan%20class=%22title%20function_%22%3Eoperation%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20%3Cspan%20class=%22keyword%22%3Ereturn%3C/span%3E%20%3Cspan%20class=%22string%22%3E&amp;quot;%E5%85%83%E7%B4%A0%20A%20%E7%9A%84%E5%86%85%E5%AE%B9&amp;quot;%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Eaccept%3C/span%3E%3Cspan%20class=%22params%22%3E(Visitor%20visitor)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20visitor.visitConcreteElementA(%3Cspan%20class=%22built_in%22%3Ethis%3C/span%3E);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EConcreteElementB%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eimplements%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EElement%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20String%20%3Cspan%20class=%22title%20function_%22%3Eoperation%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20%3Cspan%20class=%22keyword%22%3Ereturn%3C/span%3E%20%3Cspan%20class=%22string%22%3E&amp;quot;%E5%85%83%E7%B4%A0%20B%20%E7%9A%84%E5%86%85%E5%AE%B9&amp;quot;%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Eaccept%3C/span%3E%3Cspan%20class=%22params%22%3E(Visitor%20visitor)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20visitor.visitConcreteElementB(%3Cspan%20class=%22built_in%22%3Ethis%3C/span%3E);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Col%20start=%225%22%3E%3Cli%3E%E5%AF%B9%E8%B1%A1%E7%BB%93%E6%9E%84(Object%20Structure)%3C/li%3E%3C/ol%3E%3Cp%3E%E7%AE%A1%E7%90%86%E4%B8%80%E7%BB%84%E5%85%83%E7%B4%A0%EF%BC%8C%E5%B9%B6%E6%8F%90%E4%BE%9B%E4%B8%80%E4%B8%AA%E8%AE%A9%E8%AE%BF%E9%97%AE%E8%80%85%E8%AE%BF%E9%97%AE%E6%89%80%E6%9C%89%E5%85%83%E7%B4%A0%E7%9A%84%E6%8E%A5%E5%8F%A3%E3%80%82%3C/p%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E8%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E9%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E10%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E11%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E12%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E13%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E14%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E15%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E16%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Eimport%3C/span%3E%20java.util.ArrayList;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Eimport%3C/span%3E%20java.util.List;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EObjectStructure%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Eprivate%3C/span%3E%20List&amp;lt;Element&amp;gt;%20elements%20=%20%3Cspan%20class=%22keyword%22%3Enew%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EArrayList%3C/span%3E&amp;lt;&amp;gt;();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Eadd%3C/span%3E%3Cspan%20class=%22params%22%3E(Element%20element)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20elements.add(element);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Eaccept%3C/span%3E%3Cspan%20class=%22params%22%3E(Visitor%20visitor)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20%3Cspan%20class=%22keyword%22%3Efor%3C/span%3E%20(Element%20element%20:%20elements)%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20%20%20%20%20element.accept(visitor);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Col%20start=%226%22%3E%3Cli%3E%E5%AE%A2%E6%88%B7%E7%AB%AF%E7%A4%BA%E4%BE%8B%3C/li%3E%3C/ol%3E%3Cfigure%20class=%22highlight%20kt%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Eval%3C/span%3E%20structure%20=%20ObjectStructure()%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3Estructure.add(ConcreteElementA())%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3Estructure.add(ConcreteElementB())%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Eval%3C/span%3E%20visitor%20=%20ConcreteVisitor()%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3Estructure.accept(visitor)%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Ch3%20id=%22%E9%80%82%E7%94%A8%E5%9C%BA%E6%99%AF%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E9%80%82%E7%94%A8%E5%9C%BA%E6%99%AF%22%3E%C2%B6%3C/a%3E%E9%80%82%E7%94%A8%E5%9C%BA%E6%99%AF%3C/h3%3E%3Cul%3E%3Cli%3E%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E7%9B%B8%E5%AF%B9%E7%A8%B3%E5%AE%9A%EF%BC%8C%E4%BD%86%E5%AF%B9%E5%85%B6%E6%93%8D%E4%BD%9C%E7%BB%8F%E5%B8%B8%E6%89%A9%E5%B1%95%E7%9A%84%E7%B3%BB%E7%BB%9F%E3%80%82%3C/li%3E%3Cli%3E%E7%BC%96%E8%AF%91%E5%99%A8%E8%AE%BE%E8%AE%A1%E4%B8%AD%E7%94%A8%E4%BA%8E%E9%81%8D%E5%8E%86%E8%AF%AD%E6%B3%95%E6%A0%91%E3%80%82%3C/li%3E%3Cli%3E%E6%8A%A5%E8%A1%A8%E7%94%9F%E6%88%90%E3%80%81%E6%97%A5%E5%BF%97%E8%AE%B0%E5%BD%95%E3%80%81%E6%B8%B2%E6%9F%93%E5%BC%95%E6%93%8E%E7%AD%89%E9%9C%80%E7%BB%9F%E4%B8%80%E5%A4%84%E7%90%86%E5%A4%9A%E7%A7%8D%E5%AF%B9%E8%B1%A1%E7%9A%84%E5%9C%BA%E6%99%AF%E3%80%82%3C/li%3E%3C/ul%3E%3Ch3%20id=%22Java%E4%B8%AD%E7%9A%84%E5%85%B8%E5%9E%8B%E5%BA%94%E7%94%A8%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#Java%E4%B8%AD%E7%9A%84%E5%85%B8%E5%9E%8B%E5%BA%94%E7%94%A8%22%3E%C2%B6%3C/a%3EJava%E4%B8%AD%E7%9A%84%E5%85%B8%E5%9E%8B%E5%BA%94%E7%94%A8%3C/h3%3E%3Cul%3E%3Cli%3EJava%E7%BC%96%E8%AF%91%E5%99%A8%E5%B7%A5%E5%85%B7(%E5%A6%82javac)%E4%BD%BF%E7%94%A8%E8%AE%BF%E9%97%AE%E8%80%85%E6%A8%A1%E5%BC%8F%E9%81%8D%E5%8E%86AST(%E6%8A%BD%E8%B1%A1%E8%AF%AD%E6%B3%95%E6%A0%91).%3C/li%3E%3Cli%3EXML/JSON%E8%A7%A3%E6%9E%90%E6%A1%86%E6%9E%B6%E4%B8%AD%E5%AF%B9%E8%8A%82%E7%82%B9%E8%BF%9B%E8%A1%8C%E7%BB%9F%E4%B8%80%E8%AE%BF%E9%97%AE%E5%A4%84%E7%90%86%E3%80%82%3C/li%3E%3Cli%3ESpring%E6%A1%86%E6%9E%B6%E4%B8%AD%E7%94%A8%E4%BA%8E%E9%85%8D%E7%BD%AE%E8%A7%A3%E6%9E%90%E5%92%8C%E4%BE%9D%E8%B5%96%E6%B3%A8%E5%85%A5%E7%9A%84%E8%AE%BF%E9%97%AE%E9%80%BB%E8%BE%91%E3%80%82%3C/li%3E%3C/ul%3E%3Ch3%20id=%22%E5%8F%98%E4%BD%93%E4%B8%8E%E6%9B%BF%E4%BB%A3%E6%96%B9%E6%A1%88%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E5%8F%98%E4%BD%93%E4%B8%8E%E6%9B%BF%E4%BB%A3%E6%96%B9%E6%A1%88%22%3E%C2%B6%3C/a%3E%E5%8F%98%E4%BD%93%E4%B8%8E%E6%9B%BF%E4%BB%A3%E6%96%B9%E6%A1%88%3C/h3%3E%3Cul%3E%3Cli%3E%3Cstrong%3E%E5%8F%8C%E4%BA%B2%E6%B4%BE(Double%20Dispatch)%3C/strong%3E%EF%BC%9A%20%E8%AE%BF%E9%97%AE%E8%80%85%E6%A8%A1%E5%BC%8F%E7%9A%84%E6%A0%B8%E5%BF%83%E6%9C%BA%E5%88%B6%E3%80%82%3C/li%3E%3Cli%3E%3Cstrong%3E%E7%AD%96%E7%95%A5%E6%A8%A1%E5%BC%8F%3C/strong%3E%EF%BC%9A%20%E6%97%B6%E5%92%8C%E5%8D%95%E4%B8%80%E7%BB%93%E6%9E%84%E5%A4%9A%E7%AE%97%E6%B3%95%EF%BC%8C%E4%BD%86%E4%B8%8D%E5%85%B7%E5%A4%87%E8%AE%BF%E9%97%AE%E8%80%85%E5%AF%B9%E5%A4%9A%E7%A7%8D%E5%85%83%E7%B4%A0%E7%9A%84%E6%94%AF%E6%8C%81%E8%83%BD%E5%8A%9B%E3%80%82%3C/li%3E%3Cli%3E%3Cstrong%3E%E8%B4%A3%E4%BB%BB%E9%93%BE%E6%A8%A1%E5%BC%8F%3C/strong%3E%EF%BC%9A%20%E4%BE%A7%E9%87%8D%E8%AF%B7%E6%B1%82%E4%BC%A0%E9%80%92%E8%80%8C%E9%9D%9E%E7%BB%9F%E4%B8%80%E8%AE%BF%E9%97%AE%E3%80%82%3C/li%3E%3C/ul%3E" type="image"/>
    
    
    
    <category term="behavioral" scheme="https://galudisu.info/tags/behavioral/"/>
    
    <category term="visitor" scheme="https://galudisu.info/tags/visitor/"/>
    
  </entry>
  
  <entry>
    <title>责任链模式(Chain of responsibility Pattern)</title>
    <link href="https://galudisu.info/2025/05/10/pattern/basic/behavioral/ChainOfResponsibility/"/>
    <id>https://galudisu.info/2025/05/10/pattern/basic/behavioral/ChainOfResponsibility/</id>
    <published>2025-05-10T12:25:10.000Z</published>
    <updated>2026-04-14T19:59:33.697Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>责任链模式(Chain of Responsibility Pattern)为请求创建了一个接受者对象的链。这种模式给予请求的类型，对请求的发送者和接受者进行解耦。<strong>在这种模式中，通常每个接受者都包含对另一个接受者的引用。如果一个对象不能处理该请求，那么它会把相同的请求传给下一个接收者，以此类推</strong>。</p></blockquote><img src="/assert/puml/525ae663ce9d5589483ac2266d13befd0cca3f11c3dbba9a81c0a8f286e6bab6.svg"/><span id="more"></span><h3 id="核心组成"><a class="header-anchor" href="#核心组成">¶</a>核心组成</h3><ol><li>抽象处理者(Handler)</li></ol><p>定义处理请求的接口，并持有下一个处理者的引用。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="keyword">class</span> <span class="title class_">Handler</span> &#123;</span><br><span class="line">    <span class="keyword">protected</span> Handler nextHandler;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setNextHandler</span><span class="params">(Handler nextHandler)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.nextHandler = nextHandler;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">abstract</span> <span class="keyword">void</span> <span class="title function_">handleRequest</span><span class="params">(String request)</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><ol start="2"><li>具体处理者(Concrete Handlers)</li></ol><p>实现具体的请求处理逻辑，可以选择处理或转发请求。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">ConcreteHandlerA</span> <span class="keyword">extends</span> <span class="title class_">Handler</span> &#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">handleRequest</span><span class="params">(String request)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (<span class="string">&quot;A&quot;</span>.equals(request)) &#123;</span><br><span class="line">            System.out.println(<span class="string">&quot;ConcreteHandlerA 处理了请求：&quot;</span> + request);</span><br><span class="line">        &#125; <span class="keyword">else</span> <span class="keyword">if</span> (nextHandler != <span class="literal">null</span>) &#123;</span><br><span class="line">            System.out.println(<span class="string">&quot;ConcreteHandlerA 无法处理，转交给下一个...&quot;</span>);</span><br><span class="line">            nextHandler.handleRequest(request);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">ConcreteHandlerB</span> <span class="keyword">extends</span> <span class="title class_">Handler</span> &#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">handleRequest</span><span class="params">(String request)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (<span class="string">&quot;B&quot;</span>.equals(request)) &#123;</span><br><span class="line">            System.out.println(<span class="string">&quot;ConcreteHandlerB 处理了请求：&quot;</span> + request);</span><br><span class="line">        &#125; <span class="keyword">else</span> <span class="keyword">if</span> (nextHandler != <span class="literal">null</span>) &#123;</span><br><span class="line">            System.out.println(<span class="string">&quot;ConcreteHandlerB 无法处理，转交给下一个...&quot;</span>);</span><br><span class="line">            nextHandler.handleRequest(request);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><ol start="3"><li>客户端代码</li></ol><p>构建责任链并发起请求。</p><figure class="highlight kt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">val</span> handlerA = ConcreteHandlerA()</span><br><span class="line"><span class="keyword">val</span> handlerB = ConcreteHandlerB()</span><br><span class="line"></span><br><span class="line">handlerA.setNextHandler(handlerB)</span><br><span class="line">handlerA.handleRequest(<span class="string">&quot;A&quot;</span>)</span><br><span class="line">handlerA.handleRequest(<span class="string">&quot;B&quot;</span>)</span><br><span class="line">handlerA.handleRequest(<span class="string">&quot;C&quot;</span>)</span><br></pre></td></tr></table></figure><h3 id="优点"><a class="header-anchor" href="#优点">¶</a>优点</h3><ul><li><strong>解耦</strong>： 请求发送者与处理者之间无需指导彼此，只需知道链的存在。</li><li><strong>可扩展性强</strong>： 可以动态地增加或修改处理链上的节点。</li><li><strong>职责分离</strong>： 每个处理者只关注自己的处理逻辑。</li></ul><h3 id="缺点"><a class="header-anchor" href="#缺点">¶</a>缺点</h3><ul><li><strong>请求可能未被处理</strong>： 如果链中没有合适的处理者，请求可能会被忽略。</li><li><strong>调试复杂</strong>： 请求在链中传递时，调试和追踪较难。</li><li><strong>性能问题</strong>： 若链过长或处理逻辑复杂，可能影响性能。</li></ul><h3 id="Java中的典型应用"><a class="header-anchor" href="#Java中的典型应用">¶</a>Java中的典型应用</h3><ul><li><code>Spring interceptor/Filter</code>： 用于请求拦截和预处理。</li><li><code>Java Servlet Filter</code>： 对HTTP请求进行过滤。</li><li><code>日志框架(如Log4j)</code>： 根据日志级别决定是否记录。</li><li><code>异常处理链</code>： 不同层级尝试捕获和处理异常。</li></ul>]]></content>
    
    
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;责任链模式(Chain of Responsibility Pattern)为请求创建了一个接受者对象的链。这种模式给予请求的类型，对请求的发送者和接受者进行解耦。&lt;strong&gt;在这种模式中，通常每个接受者都包含对另一个接受者的引用。如果一个对象不能处理该请求，那么它会把相同的请求传给下一个接收者，以此类推&lt;/strong&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;img src=&quot;/assert/puml/525ae663ce9d5589483ac2266d13befd0cca3f11c3dbba9a81c0a8f286e6bab6.svg&quot;/&gt;</summary>
    
    
    <content src="https://galudisu.info/%3Cblockquote%3E%3Cp%3E%E8%B4%A3%E4%BB%BB%E9%93%BE%E6%A8%A1%E5%BC%8F(Chain%20of%20Responsibility%20Pattern)%E4%B8%BA%E8%AF%B7%E6%B1%82%E5%88%9B%E5%BB%BA%E4%BA%86%E4%B8%80%E4%B8%AA%E6%8E%A5%E5%8F%97%E8%80%85%E5%AF%B9%E8%B1%A1%E7%9A%84%E9%93%BE%E3%80%82%E8%BF%99%E7%A7%8D%E6%A8%A1%E5%BC%8F%E7%BB%99%E4%BA%88%E8%AF%B7%E6%B1%82%E7%9A%84%E7%B1%BB%E5%9E%8B%EF%BC%8C%E5%AF%B9%E8%AF%B7%E6%B1%82%E7%9A%84%E5%8F%91%E9%80%81%E8%80%85%E5%92%8C%E6%8E%A5%E5%8F%97%E8%80%85%E8%BF%9B%E8%A1%8C%E8%A7%A3%E8%80%A6%E3%80%82%3Cstrong%3E%E5%9C%A8%E8%BF%99%E7%A7%8D%E6%A8%A1%E5%BC%8F%E4%B8%AD%EF%BC%8C%E9%80%9A%E5%B8%B8%E6%AF%8F%E4%B8%AA%E6%8E%A5%E5%8F%97%E8%80%85%E9%83%BD%E5%8C%85%E5%90%AB%E5%AF%B9%E5%8F%A6%E4%B8%80%E4%B8%AA%E6%8E%A5%E5%8F%97%E8%80%85%E7%9A%84%E5%BC%95%E7%94%A8%E3%80%82%E5%A6%82%E6%9E%9C%E4%B8%80%E4%B8%AA%E5%AF%B9%E8%B1%A1%E4%B8%8D%E8%83%BD%E5%A4%84%E7%90%86%E8%AF%A5%E8%AF%B7%E6%B1%82%EF%BC%8C%E9%82%A3%E4%B9%88%E5%AE%83%E4%BC%9A%E6%8A%8A%E7%9B%B8%E5%90%8C%E7%9A%84%E8%AF%B7%E6%B1%82%E4%BC%A0%E7%BB%99%E4%B8%8B%E4%B8%80%E4%B8%AA%E6%8E%A5%E6%94%B6%E8%80%85%EF%BC%8C%E4%BB%A5%E6%AD%A4%E7%B1%BB%E6%8E%A8%3C/strong%3E%E3%80%82%3C/p%3E%3C/blockquote%3E%3Cimg%20src=%22/assert/puml/525ae663ce9d5589483ac2266d13befd0cca3f11c3dbba9a81c0a8f286e6bab6.svg%22/%3E%3Cspan%20id=%22more%22%3E%3C/span%3E%3Ch3%20id=%22%E6%A0%B8%E5%BF%83%E7%BB%84%E6%88%90%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E6%A0%B8%E5%BF%83%E7%BB%84%E6%88%90%22%3E%C2%B6%3C/a%3E%E6%A0%B8%E5%BF%83%E7%BB%84%E6%88%90%3C/h3%3E%3Col%3E%3Cli%3E%E6%8A%BD%E8%B1%A1%E5%A4%84%E7%90%86%E8%80%85(Handler)%3C/li%3E%3C/ol%3E%3Cp%3E%E5%AE%9A%E4%B9%89%E5%A4%84%E7%90%86%E8%AF%B7%E6%B1%82%E7%9A%84%E6%8E%A5%E5%8F%A3%EF%BC%8C%E5%B9%B6%E6%8C%81%E6%9C%89%E4%B8%8B%E4%B8%80%E4%B8%AA%E5%A4%84%E7%90%86%E8%80%85%E7%9A%84%E5%BC%95%E7%94%A8%E3%80%82%3C/p%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E8%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E9%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E10%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eabstract%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EHandler%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Eprotected%3C/span%3E%20Handler%20nextHandler;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EsetNextHandler%3C/span%3E%3Cspan%20class=%22params%22%3E(Handler%20nextHandler)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20%3Cspan%20class=%22built_in%22%3Ethis%3C/span%3E.nextHandler%20=%20nextHandler;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eabstract%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EhandleRequest%3C/span%3E%3Cspan%20class=%22params%22%3E(String%20request)%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Col%20start=%222%22%3E%3Cli%3E%E5%85%B7%E4%BD%93%E5%A4%84%E7%90%86%E8%80%85(Concrete%20Handlers)%3C/li%3E%3C/ol%3E%3Cp%3E%E5%AE%9E%E7%8E%B0%E5%85%B7%E4%BD%93%E7%9A%84%E8%AF%B7%E6%B1%82%E5%A4%84%E7%90%86%E9%80%BB%E8%BE%91%EF%BC%8C%E5%8F%AF%E4%BB%A5%E9%80%89%E6%8B%A9%E5%A4%84%E7%90%86%E6%88%96%E8%BD%AC%E5%8F%91%E8%AF%B7%E6%B1%82%E3%80%82%3C/p%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E8%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E9%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E10%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E11%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E12%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E13%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E14%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E15%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E16%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E17%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E18%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E19%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E21%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E22%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E23%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EConcreteHandlerA%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eextends%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EHandler%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EhandleRequest%3C/span%3E%3Cspan%20class=%22params%22%3E(String%20request)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20%3Cspan%20class=%22keyword%22%3Eif%3C/span%3E%20(%3Cspan%20class=%22string%22%3E&amp;quot;A&amp;quot;%3C/span%3E.equals(request))%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20%20%20%20%20System.out.println(%3Cspan%20class=%22string%22%3E&amp;quot;ConcreteHandlerA%20%E5%A4%84%E7%90%86%E4%BA%86%E8%AF%B7%E6%B1%82%EF%BC%9A&amp;quot;%3C/span%3E%20+%20request);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20&amp;#125;%20%3Cspan%20class=%22keyword%22%3Eelse%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eif%3C/span%3E%20(nextHandler%20!=%20%3Cspan%20class=%22literal%22%3Enull%3C/span%3E)%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20%20%20%20%20System.out.println(%3Cspan%20class=%22string%22%3E&amp;quot;ConcreteHandlerA%20%E6%97%A0%E6%B3%95%E5%A4%84%E7%90%86%EF%BC%8C%E8%BD%AC%E4%BA%A4%E7%BB%99%E4%B8%8B%E4%B8%80%E4%B8%AA...&amp;quot;%3C/span%3E);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20%20%20%20%20nextHandler.handleRequest(request);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EConcreteHandlerB%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eextends%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EHandler%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EhandleRequest%3C/span%3E%3Cspan%20class=%22params%22%3E(String%20request)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20%3Cspan%20class=%22keyword%22%3Eif%3C/span%3E%20(%3Cspan%20class=%22string%22%3E&amp;quot;B&amp;quot;%3C/span%3E.equals(request))%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20%20%20%20%20System.out.println(%3Cspan%20class=%22string%22%3E&amp;quot;ConcreteHandlerB%20%E5%A4%84%E7%90%86%E4%BA%86%E8%AF%B7%E6%B1%82%EF%BC%9A&amp;quot;%3C/span%3E%20+%20request);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20&amp;#125;%20%3Cspan%20class=%22keyword%22%3Eelse%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eif%3C/span%3E%20(nextHandler%20!=%20%3Cspan%20class=%22literal%22%3Enull%3C/span%3E)%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20%20%20%20%20System.out.println(%3Cspan%20class=%22string%22%3E&amp;quot;ConcreteHandlerB%20%E6%97%A0%E6%B3%95%E5%A4%84%E7%90%86%EF%BC%8C%E8%BD%AC%E4%BA%A4%E7%BB%99%E4%B8%8B%E4%B8%80%E4%B8%AA...&amp;quot;%3C/span%3E);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20%20%20%20%20nextHandler.handleRequest(request);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Col%20start=%223%22%3E%3Cli%3E%E5%AE%A2%E6%88%B7%E7%AB%AF%E4%BB%A3%E7%A0%81%3C/li%3E%3C/ol%3E%3Cp%3E%E6%9E%84%E5%BB%BA%E8%B4%A3%E4%BB%BB%E9%93%BE%E5%B9%B6%E5%8F%91%E8%B5%B7%E8%AF%B7%E6%B1%82%E3%80%82%3C/p%3E%3Cfigure%20class=%22highlight%20kt%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Eval%3C/span%3E%20handlerA%20=%20ConcreteHandlerA()%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Eval%3C/span%3E%20handlerB%20=%20ConcreteHandlerB()%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3EhandlerA.setNextHandler(handlerB)%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3EhandlerA.handleRequest(%3Cspan%20class=%22string%22%3E&amp;quot;A&amp;quot;%3C/span%3E)%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3EhandlerA.handleRequest(%3Cspan%20class=%22string%22%3E&amp;quot;B&amp;quot;%3C/span%3E)%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3EhandlerA.handleRequest(%3Cspan%20class=%22string%22%3E&amp;quot;C&amp;quot;%3C/span%3E)%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Ch3%20id=%22%E4%BC%98%E7%82%B9%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E4%BC%98%E7%82%B9%22%3E%C2%B6%3C/a%3E%E4%BC%98%E7%82%B9%3C/h3%3E%3Cul%3E%3Cli%3E%3Cstrong%3E%E8%A7%A3%E8%80%A6%3C/strong%3E%EF%BC%9A%20%E8%AF%B7%E6%B1%82%E5%8F%91%E9%80%81%E8%80%85%E4%B8%8E%E5%A4%84%E7%90%86%E8%80%85%E4%B9%8B%E9%97%B4%E6%97%A0%E9%9C%80%E6%8C%87%E5%AF%BC%E5%BD%BC%E6%AD%A4%EF%BC%8C%E5%8F%AA%E9%9C%80%E7%9F%A5%E9%81%93%E9%93%BE%E7%9A%84%E5%AD%98%E5%9C%A8%E3%80%82%3C/li%3E%3Cli%3E%3Cstrong%3E%E5%8F%AF%E6%89%A9%E5%B1%95%E6%80%A7%E5%BC%BA%3C/strong%3E%EF%BC%9A%20%E5%8F%AF%E4%BB%A5%E5%8A%A8%E6%80%81%E5%9C%B0%E5%A2%9E%E5%8A%A0%E6%88%96%E4%BF%AE%E6%94%B9%E5%A4%84%E7%90%86%E9%93%BE%E4%B8%8A%E7%9A%84%E8%8A%82%E7%82%B9%E3%80%82%3C/li%3E%3Cli%3E%3Cstrong%3E%E8%81%8C%E8%B4%A3%E5%88%86%E7%A6%BB%3C/strong%3E%EF%BC%9A%20%E6%AF%8F%E4%B8%AA%E5%A4%84%E7%90%86%E8%80%85%E5%8F%AA%E5%85%B3%E6%B3%A8%E8%87%AA%E5%B7%B1%E7%9A%84%E5%A4%84%E7%90%86%E9%80%BB%E8%BE%91%E3%80%82%3C/li%3E%3C/ul%3E%3Ch3%20id=%22%E7%BC%BA%E7%82%B9%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E7%BC%BA%E7%82%B9%22%3E%C2%B6%3C/a%3E%E7%BC%BA%E7%82%B9%3C/h3%3E%3Cul%3E%3Cli%3E%3Cstrong%3E%E8%AF%B7%E6%B1%82%E5%8F%AF%E8%83%BD%E6%9C%AA%E8%A2%AB%E5%A4%84%E7%90%86%3C/strong%3E%EF%BC%9A%20%E5%A6%82%E6%9E%9C%E9%93%BE%E4%B8%AD%E6%B2%A1%E6%9C%89%E5%90%88%E9%80%82%E7%9A%84%E5%A4%84%E7%90%86%E8%80%85%EF%BC%8C%E8%AF%B7%E6%B1%82%E5%8F%AF%E8%83%BD%E4%BC%9A%E8%A2%AB%E5%BF%BD%E7%95%A5%E3%80%82%3C/li%3E%3Cli%3E%3Cstrong%3E%E8%B0%83%E8%AF%95%E5%A4%8D%E6%9D%82%3C/strong%3E%EF%BC%9A%20%E8%AF%B7%E6%B1%82%E5%9C%A8%E9%93%BE%E4%B8%AD%E4%BC%A0%E9%80%92%E6%97%B6%EF%BC%8C%E8%B0%83%E8%AF%95%E5%92%8C%E8%BF%BD%E8%B8%AA%E8%BE%83%E9%9A%BE%E3%80%82%3C/li%3E%3Cli%3E%3Cstrong%3E%E6%80%A7%E8%83%BD%E9%97%AE%E9%A2%98%3C/strong%3E%EF%BC%9A%20%E8%8B%A5%E9%93%BE%E8%BF%87%E9%95%BF%E6%88%96%E5%A4%84%E7%90%86%E9%80%BB%E8%BE%91%E5%A4%8D%E6%9D%82%EF%BC%8C%E5%8F%AF%E8%83%BD%E5%BD%B1%E5%93%8D%E6%80%A7%E8%83%BD%E3%80%82%3C/li%3E%3C/ul%3E%3Ch3%20id=%22Java%E4%B8%AD%E7%9A%84%E5%85%B8%E5%9E%8B%E5%BA%94%E7%94%A8%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#Java%E4%B8%AD%E7%9A%84%E5%85%B8%E5%9E%8B%E5%BA%94%E7%94%A8%22%3E%C2%B6%3C/a%3EJava%E4%B8%AD%E7%9A%84%E5%85%B8%E5%9E%8B%E5%BA%94%E7%94%A8%3C/h3%3E%3Cul%3E%3Cli%3E%3Ccode%3ESpring%20interceptor/Filter%3C/code%3E%EF%BC%9A%20%E7%94%A8%E4%BA%8E%E8%AF%B7%E6%B1%82%E6%8B%A6%E6%88%AA%E5%92%8C%E9%A2%84%E5%A4%84%E7%90%86%E3%80%82%3C/li%3E%3Cli%3E%3Ccode%3EJava%20Servlet%20Filter%3C/code%3E%EF%BC%9A%20%E5%AF%B9HTTP%E8%AF%B7%E6%B1%82%E8%BF%9B%E8%A1%8C%E8%BF%87%E6%BB%A4%E3%80%82%3C/li%3E%3Cli%3E%3Ccode%3E%E6%97%A5%E5%BF%97%E6%A1%86%E6%9E%B6(%E5%A6%82Log4j)%3C/code%3E%EF%BC%9A%20%E6%A0%B9%E6%8D%AE%E6%97%A5%E5%BF%97%E7%BA%A7%E5%88%AB%E5%86%B3%E5%AE%9A%E6%98%AF%E5%90%A6%E8%AE%B0%E5%BD%95%E3%80%82%3C/li%3E%3Cli%3E%3Ccode%3E%E5%BC%82%E5%B8%B8%E5%A4%84%E7%90%86%E9%93%BE%3C/code%3E%EF%BC%9A%20%E4%B8%8D%E5%90%8C%E5%B1%82%E7%BA%A7%E5%B0%9D%E8%AF%95%E6%8D%95%E8%8E%B7%E5%92%8C%E5%A4%84%E7%90%86%E5%BC%82%E5%B8%B8%E3%80%82%3C/li%3E%3C/ul%3E" type="image"/>
    
    
    
    <category term="behavioral" scheme="https://galudisu.info/tags/behavioral/"/>
    
    <category term="chain of responsibility" scheme="https://galudisu.info/tags/chain-of-responsibility/"/>
    
  </entry>
  
  <entry>
    <title>策略模式(Strategy Pattern)</title>
    <link href="https://galudisu.info/2025/05/10/pattern/basic/behavioral/Strategy/"/>
    <id>https://galudisu.info/2025/05/10/pattern/basic/behavioral/Strategy/</id>
    <published>2025-05-10T12:25:09.000Z</published>
    <updated>2026-04-14T19:59:33.767Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>定义了算法族，分别封装起来，让它们之间可相互替换，此模式让算法的变化独立于使用算法的客户。</p></blockquote><img src="/assert/puml/ac8cb0be6e4d440a8c3ed981c528f6cfe9d54dc0cfa7d4f3d7b42a0ef25ed3e7.svg"/><span id="more"></span><h3 id="核心思想"><a class="header-anchor" href="#核心思想">¶</a>核心思想</h3><ul><li>定义： 将一组<strong>算法/策略</strong>封装为独立类，但它们可<strong>动态替换</strong>，解耦算法与使用对象。</li><li>结构：<ul><li><code>Strategy</code>： 策略接口(定义公共方法)</li><li><code>ConcreteStrategy</code>： 具体策略类(实现不同算法)</li><li><code>Context</code>： 上下文类(持有策略接口引用，调用策略方法)</li></ul></li></ul><h3 id="应用场景"><a class="header-anchor" href="#应用场景">¶</a>应用场景</h3><ul><li>支付系统： 支持多种支付方式(支付宝、微信、银联)。</li><li>促销活动： 不同折扣策略(满减、打折、赠品)。</li><li>路由算法： 动态切换最短路径、最低成本等计算策略。</li></ul><h3 id="示例"><a class="header-anchor" href="#示例">¶</a>示例</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 1. 定义策略接口</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">PaymentStrategy</span> &#123;</span><br><span class="line">    <span class="keyword">void</span> <span class="title function_">pay</span><span class="params">(<span class="type">int</span> amount)</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 2. 实现具体策略</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Alipay</span> <span class="keyword">implements</span> <span class="title class_">PaymentStrategy</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">pay</span><span class="params">(<span class="type">int</span> amount)</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;支付宝支付: &quot;</span> + amount);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">WeChatPay</span> <span class="keyword">implements</span> <span class="title class_">PaymentStrategy</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">pay</span><span class="params">(<span class="type">int</span> amount)</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;微信支付: &quot;</span> + amount);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 3. 上下文使用策略</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">ShoppingCart</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> PaymentStrategy strategy;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setPaymentStrategy</span><span class="params">(PaymentStrategy strategy)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.strategy = strategy;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">checkout</span><span class="params">(<span class="type">int</span> amount)</span> &#123;</span><br><span class="line">        strategy.pay(amount);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 4. 调用示例</span></span><br><span class="line"><span class="type">ShoppingCart</span> <span class="variable">cart</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ShoppingCart</span>();</span><br><span class="line">cart.setPaymentStrategy(<span class="keyword">new</span> <span class="title class_">Alipay</span>());</span><br><span class="line">cart.checkout(<span class="number">100</span>); <span class="comment">// 输出：支付宝支付: 100</span></span><br><span class="line"></span><br></pre></td></tr></table></figure><h3 id="注意事项"><a class="header-anchor" href="#注意事项">¶</a>注意事项</h3><ul><li>策略类数量膨胀： 策略过多时需要多个策略类，可能会增加系统复杂度。</li><li>如果策略过多，建议结合工厂模式或配置文件来动态选择策略。</li></ul>]]></content>
    
    
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;定义了算法族，分别封装起来，让它们之间可相互替换，此模式让算法的变化独立于使用算法的客户。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;img src=&quot;/assert/puml/ac8cb0be6e4d440a8c3ed981c528f6cfe9d54dc0cfa7d4f3d7b42a0ef25ed3e7.svg&quot;/&gt;</summary>
    
    
    <content src="https://galudisu.info/%3Cblockquote%3E%3Cp%3E%E5%AE%9A%E4%B9%89%E4%BA%86%E7%AE%97%E6%B3%95%E6%97%8F%EF%BC%8C%E5%88%86%E5%88%AB%E5%B0%81%E8%A3%85%E8%B5%B7%E6%9D%A5%EF%BC%8C%E8%AE%A9%E5%AE%83%E4%BB%AC%E4%B9%8B%E9%97%B4%E5%8F%AF%E7%9B%B8%E4%BA%92%E6%9B%BF%E6%8D%A2%EF%BC%8C%E6%AD%A4%E6%A8%A1%E5%BC%8F%E8%AE%A9%E7%AE%97%E6%B3%95%E7%9A%84%E5%8F%98%E5%8C%96%E7%8B%AC%E7%AB%8B%E4%BA%8E%E4%BD%BF%E7%94%A8%E7%AE%97%E6%B3%95%E7%9A%84%E5%AE%A2%E6%88%B7%E3%80%82%3C/p%3E%3C/blockquote%3E%3Cimg%20src=%22/assert/puml/ac8cb0be6e4d440a8c3ed981c528f6cfe9d54dc0cfa7d4f3d7b42a0ef25ed3e7.svg%22/%3E%3Cspan%20id=%22more%22%3E%3C/span%3E%3Ch3%20id=%22%E6%A0%B8%E5%BF%83%E6%80%9D%E6%83%B3%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E6%A0%B8%E5%BF%83%E6%80%9D%E6%83%B3%22%3E%C2%B6%3C/a%3E%E6%A0%B8%E5%BF%83%E6%80%9D%E6%83%B3%3C/h3%3E%3Cul%3E%3Cli%3E%E5%AE%9A%E4%B9%89%EF%BC%9A%20%E5%B0%86%E4%B8%80%E7%BB%84%3Cstrong%3E%E7%AE%97%E6%B3%95/%E7%AD%96%E7%95%A5%3C/strong%3E%E5%B0%81%E8%A3%85%E4%B8%BA%E7%8B%AC%E7%AB%8B%E7%B1%BB%EF%BC%8C%E4%BD%86%E5%AE%83%E4%BB%AC%E5%8F%AF%3Cstrong%3E%E5%8A%A8%E6%80%81%E6%9B%BF%E6%8D%A2%3C/strong%3E%EF%BC%8C%E8%A7%A3%E8%80%A6%E7%AE%97%E6%B3%95%E4%B8%8E%E4%BD%BF%E7%94%A8%E5%AF%B9%E8%B1%A1%E3%80%82%3C/li%3E%3Cli%3E%E7%BB%93%E6%9E%84%EF%BC%9A%3Cul%3E%3Cli%3E%3Ccode%3EStrategy%3C/code%3E%EF%BC%9A%20%E7%AD%96%E7%95%A5%E6%8E%A5%E5%8F%A3(%E5%AE%9A%E4%B9%89%E5%85%AC%E5%85%B1%E6%96%B9%E6%B3%95)%3C/li%3E%3Cli%3E%3Ccode%3EConcreteStrategy%3C/code%3E%EF%BC%9A%20%E5%85%B7%E4%BD%93%E7%AD%96%E7%95%A5%E7%B1%BB(%E5%AE%9E%E7%8E%B0%E4%B8%8D%E5%90%8C%E7%AE%97%E6%B3%95)%3C/li%3E%3Cli%3E%3Ccode%3EContext%3C/code%3E%EF%BC%9A%20%E4%B8%8A%E4%B8%8B%E6%96%87%E7%B1%BB(%E6%8C%81%E6%9C%89%E7%AD%96%E7%95%A5%E6%8E%A5%E5%8F%A3%E5%BC%95%E7%94%A8%EF%BC%8C%E8%B0%83%E7%94%A8%E7%AD%96%E7%95%A5%E6%96%B9%E6%B3%95)%3C/li%3E%3C/ul%3E%3C/li%3E%3C/ul%3E%3Ch3%20id=%22%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF%22%3E%C2%B6%3C/a%3E%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF%3C/h3%3E%3Cul%3E%3Cli%3E%E6%94%AF%E4%BB%98%E7%B3%BB%E7%BB%9F%EF%BC%9A%20%E6%94%AF%E6%8C%81%E5%A4%9A%E7%A7%8D%E6%94%AF%E4%BB%98%E6%96%B9%E5%BC%8F(%E6%94%AF%E4%BB%98%E5%AE%9D%E3%80%81%E5%BE%AE%E4%BF%A1%E3%80%81%E9%93%B6%E8%81%94)%E3%80%82%3C/li%3E%3Cli%3E%E4%BF%83%E9%94%80%E6%B4%BB%E5%8A%A8%EF%BC%9A%20%E4%B8%8D%E5%90%8C%E6%8A%98%E6%89%A3%E7%AD%96%E7%95%A5(%E6%BB%A1%E5%87%8F%E3%80%81%E6%89%93%E6%8A%98%E3%80%81%E8%B5%A0%E5%93%81)%E3%80%82%3C/li%3E%3Cli%3E%E8%B7%AF%E7%94%B1%E7%AE%97%E6%B3%95%EF%BC%9A%20%E5%8A%A8%E6%80%81%E5%88%87%E6%8D%A2%E6%9C%80%E7%9F%AD%E8%B7%AF%E5%BE%84%E3%80%81%E6%9C%80%E4%BD%8E%E6%88%90%E6%9C%AC%E7%AD%89%E8%AE%A1%E7%AE%97%E7%AD%96%E7%95%A5%E3%80%82%3C/li%3E%3C/ul%3E%3Ch3%20id=%22%E7%A4%BA%E4%BE%8B%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E7%A4%BA%E4%BE%8B%22%3E%C2%B6%3C/a%3E%E7%A4%BA%E4%BE%8B%3C/h3%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E8%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E9%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E10%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E11%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E12%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E13%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E14%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E15%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E16%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E17%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E18%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E19%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E21%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E22%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E23%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E24%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E25%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E26%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E27%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E28%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E29%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E30%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E31%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E32%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E33%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E34%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E35%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E36%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22comment%22%3E/%201.%20%E5%AE%9A%E4%B9%89%E7%AD%96%E7%95%A5%E6%8E%A5%E5%8F%A3%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Einterface%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EPaymentStrategy%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Epay%3C/span%3E%3Cspan%20class=%22params%22%3E(%3Cspan%20class=%22type%22%3Eint%3C/span%3E%20amount)%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22comment%22%3E/%202.%20%E5%AE%9E%E7%8E%B0%E5%85%B7%E4%BD%93%E7%AD%96%E7%95%A5%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EAlipay%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eimplements%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EPaymentStrategy%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Epay%3C/span%3E%3Cspan%20class=%22params%22%3E(%3Cspan%20class=%22type%22%3Eint%3C/span%3E%20amount)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20System.out.println(%3Cspan%20class=%22string%22%3E&amp;quot;%E6%94%AF%E4%BB%98%E5%AE%9D%E6%94%AF%E4%BB%98:%20&amp;quot;%3C/span%3E%20+%20amount);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EWeChatPay%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eimplements%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EPaymentStrategy%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Epay%3C/span%3E%3Cspan%20class=%22params%22%3E(%3Cspan%20class=%22type%22%3Eint%3C/span%3E%20amount)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20System.out.println(%3Cspan%20class=%22string%22%3E&amp;quot;%E5%BE%AE%E4%BF%A1%E6%94%AF%E4%BB%98:%20&amp;quot;%3C/span%3E%20+%20amount);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22comment%22%3E/%203.%20%E4%B8%8A%E4%B8%8B%E6%96%87%E4%BD%BF%E7%94%A8%E7%AD%96%E7%95%A5%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EShoppingCart%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Eprivate%3C/span%3E%20PaymentStrategy%20strategy;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EsetPaymentStrategy%3C/span%3E%3Cspan%20class=%22params%22%3E(PaymentStrategy%20strategy)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20%3Cspan%20class=%22built_in%22%3Ethis%3C/span%3E.strategy%20=%20strategy;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Echeckout%3C/span%3E%3Cspan%20class=%22params%22%3E(%3Cspan%20class=%22type%22%3Eint%3C/span%3E%20amount)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20strategy.pay(amount);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22comment%22%3E/%204.%20%E8%B0%83%E7%94%A8%E7%A4%BA%E4%BE%8B%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22type%22%3EShoppingCart%3C/span%3E%20%3Cspan%20class=%22variable%22%3Ecart%3C/span%3E%20%3Cspan%20class=%22operator%22%3E=%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Enew%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EShoppingCart%3C/span%3E();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3Ecart.setPaymentStrategy(%3Cspan%20class=%22keyword%22%3Enew%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EAlipay%3C/span%3E());%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3Ecart.checkout(%3Cspan%20class=%22number%22%3E100%3C/span%3E);%20%3Cspan%20class=%22comment%22%3E/%20%E8%BE%93%E5%87%BA%EF%BC%9A%E6%94%AF%E4%BB%98%E5%AE%9D%E6%94%AF%E4%BB%98:%20100%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Ch3%20id=%22%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9%22%3E%C2%B6%3C/a%3E%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9%3C/h3%3E%3Cul%3E%3Cli%3E%E7%AD%96%E7%95%A5%E7%B1%BB%E6%95%B0%E9%87%8F%E8%86%A8%E8%83%80%EF%BC%9A%20%E7%AD%96%E7%95%A5%E8%BF%87%E5%A4%9A%E6%97%B6%E9%9C%80%E8%A6%81%E5%A4%9A%E4%B8%AA%E7%AD%96%E7%95%A5%E7%B1%BB%EF%BC%8C%E5%8F%AF%E8%83%BD%E4%BC%9A%E5%A2%9E%E5%8A%A0%E7%B3%BB%E7%BB%9F%E5%A4%8D%E6%9D%82%E5%BA%A6%E3%80%82%3C/li%3E%3Cli%3E%E5%A6%82%E6%9E%9C%E7%AD%96%E7%95%A5%E8%BF%87%E5%A4%9A%EF%BC%8C%E5%BB%BA%E8%AE%AE%E7%BB%93%E5%90%88%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F%E6%88%96%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E6%9D%A5%E5%8A%A8%E6%80%81%E9%80%89%E6%8B%A9%E7%AD%96%E7%95%A5%E3%80%82%3C/li%3E%3C/ul%3E" type="image"/>
    
    
    
    <category term="behavioral" scheme="https://galudisu.info/tags/behavioral/"/>
    
    <category term="strategy" scheme="https://galudisu.info/tags/strategy/"/>
    
  </entry>
  
  <entry>
    <title>状态模式(State Pattern)</title>
    <link href="https://galudisu.info/2025/05/10/pattern/basic/behavioral/State/"/>
    <id>https://galudisu.info/2025/05/10/pattern/basic/behavioral/State/</id>
    <published>2025-05-10T12:25:08.000Z</published>
    <updated>2026-04-14T19:59:33.423Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>允许对象在内部状态改变时改变它的行为，对象看起来好像修改了它的类。</p></blockquote><img src="/assert/puml/0b83ad009e90105d1594914fbdd4c7acca0ad6d3632b7f75709b11ff54d739f0.svg"/><span id="more"></span><h3 id="核心思想"><a class="header-anchor" href="#核心思想">¶</a>核心思想</h3><p>将状态相关的逻辑从主对象(上下文)中分离出来，每个状态作为一个独立的类。</p><h3 id="结构组成"><a class="header-anchor" href="#结构组成">¶</a>结构组成</h3><ul><li><code>Context</code>： 维护一个对当前状态的引用，并定义客户感兴趣的接口。</li><li><code>State</code>： 定义与状态相关的行为。</li><li><code>ConcreteState</code>类： 实现<code>State</code>接口中定义的行为，并可能根据状态的变化修改<code>Context</code>的状态。</li></ul><h3 id="应用场景"><a class="header-anchor" href="#应用场景">¶</a>应用场景</h3><ul><li>当一个对象的行为取决于它的状态，并且它必须在运行时根据状态改变其行为。</li><li>当业务逻辑中存在大量与状态相关的条件分支，且这些分支随着状态变化而变化。</li></ul><h3 id="真实案例"><a class="header-anchor" href="#真实案例">¶</a>真实案例</h3><p>计算机进程在其生命周期有“三态模型”和“五态模型”。</p><img src="/assert/puml/64a3e32dbdd75f0eb9cd1d2862d7060da950c4df253da4a989352f476b41fe0e.svg"/><p>先定义状态接口<code>ProcessState</code></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">ProcessState</span> &#123;</span><br><span class="line">  <span class="keyword">void</span> <span class="title function_">schedule</span><span class="params">(ProcessContext context)</span>;</span><br><span class="line">  <span class="keyword">void</span> <span class="title function_">ioWait</span><span class="params">(ProcessContext context)</span>;</span><br><span class="line">  <span class="keyword">void</span> <span class="title function_">interrupt</span><span class="params">(ProcessContext context)</span>;</span><br><span class="line">  <span class="keyword">void</span> <span class="title function_">exit</span><span class="params">(ProcessContext context)</span>;</span><br><span class="line">  <span class="keyword">void</span> <span class="title function_">eventComplete</span><span class="params">(ProcessContext context)</span>;</span><br><span class="line">  String <span class="title function_">getStatus</span><span class="params">()</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>具体状态类</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">NewState</span> <span class="keyword">implements</span> <span class="title class_">ProcessState</span> &#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">schedule</span><span class="params">(ProcessContext context)</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;Admitting process to Ready state&quot;</span>);</span><br><span class="line">        context.setState(<span class="keyword">new</span> <span class="title class_">ReadyState</span>());</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">exit</span><span class="params">(ProcessContext context)</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;Process terminated from New state&quot;</span>);</span><br><span class="line">        context.setState(<span class="keyword">new</span> <span class="title class_">TerminatedState</span>());</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 其他操作无意义</span></span><br><span class="line">    <span class="meta">@Override</span> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">ioWait</span><span class="params">(ProcessContext context)</span> &#123;&#125;</span><br><span class="line">    <span class="meta">@Override</span> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">interrupt</span><span class="params">(ProcessContext context)</span> &#123;&#125;</span><br><span class="line">    <span class="meta">@Override</span> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">eventComplete</span><span class="params">(ProcessContext context)</span> &#123;&#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">getStatus</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;New&quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">ReadyState</span> <span class="keyword">implements</span> <span class="title class_">ProcessState</span> &#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">schedule</span><span class="params">(ProcessContext context)</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;Process is now Running&quot;</span>);</span><br><span class="line">        context.setState(<span class="keyword">new</span> <span class="title class_">RunningState</span>());</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 其他操作暂不支持</span></span><br><span class="line">    <span class="meta">@Override</span> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">ioWait</span><span class="params">(ProcessContext context)</span> &#123;&#125;</span><br><span class="line">    <span class="meta">@Override</span> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">interrupt</span><span class="params">(ProcessContext context)</span> &#123;&#125;</span><br><span class="line">    <span class="meta">@Override</span> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">exit</span><span class="params">(ProcessContext context)</span> &#123;&#125;</span><br><span class="line">    <span class="meta">@Override</span> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">eventComplete</span><span class="params">(ProcessContext context)</span> &#123;&#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">getStatus</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;Ready&quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">RunningState</span> <span class="keyword">implements</span> <span class="title class_">ProcessState</span> &#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">ioWait</span><span class="params">(ProcessContext context)</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;Process is waiting for I/O&quot;</span>);</span><br><span class="line">        context.setState(<span class="keyword">new</span> <span class="title class_">WaitingState</span>());</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">interrupt</span><span class="params">(ProcessContext context)</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;Process interrupted, back to Ready&quot;</span>);</span><br><span class="line">        context.setState(<span class="keyword">new</span> <span class="title class_">ReadyState</span>());</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">exit</span><span class="params">(ProcessContext context)</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;Process exited normally&quot;</span>);</span><br><span class="line">        context.setState(<span class="keyword">new</span> <span class="title class_">TerminatedState</span>());</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 其他操作无意义</span></span><br><span class="line">    <span class="meta">@Override</span> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">schedule</span><span class="params">(ProcessContext context)</span> &#123;&#125;</span><br><span class="line">    <span class="meta">@Override</span> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">eventComplete</span><span class="params">(ProcessContext context)</span> &#123;&#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">getStatus</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;Running&quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">WaitingState</span> <span class="keyword">implements</span> <span class="title class_">ProcessState</span> &#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">eventComplete</span><span class="params">(ProcessContext context)</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;I/O complete, back to Ready&quot;</span>);</span><br><span class="line">        context.setState(<span class="keyword">new</span> <span class="title class_">ReadyState</span>());</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 其他操作无意义</span></span><br><span class="line">    <span class="meta">@Override</span> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">schedule</span><span class="params">(ProcessContext context)</span> &#123;&#125;</span><br><span class="line">    <span class="meta">@Override</span> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">ioWait</span><span class="params">(ProcessContext context)</span> &#123;&#125;</span><br><span class="line">    <span class="meta">@Override</span> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">interrupt</span><span class="params">(ProcessContext context)</span> &#123;&#125;</span><br><span class="line">    <span class="meta">@Override</span> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">exit</span><span class="params">(ProcessContext context)</span> &#123;&#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">getStatus</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;Waiting&quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">TerminatedState</span> <span class="keyword">implements</span> <span class="title class_">ProcessState</span> &#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">getStatus</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;Terminated&quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 所有操作无效</span></span><br><span class="line">    <span class="meta">@Override</span> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">schedule</span><span class="params">(ProcessContext context)</span> &#123;&#125;</span><br><span class="line">    <span class="meta">@Override</span> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">ioWait</span><span class="params">(ProcessContext context)</span> &#123;&#125;</span><br><span class="line">    <span class="meta">@Override</span> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">interrupt</span><span class="params">(ProcessContext context)</span> &#123;&#125;</span><br><span class="line">    <span class="meta">@Override</span> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">exit</span><span class="params">(ProcessContext context)</span> &#123;&#125;</span><br><span class="line">    <span class="meta">@Override</span> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">eventComplete</span><span class="params">(ProcessContext context)</span> &#123;&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>上下文<code>ProcessContext</code></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">ProcessContext</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> ProcessState state;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">ProcessContext</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.state = <span class="keyword">new</span> <span class="title class_">NewState</span>();  <span class="comment">// 初始状态为 New</span></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setState</span><span class="params">(ProcessState state)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.state = state;</span><br><span class="line">        System.out.println(<span class="string">&quot;状态切换至：&quot;</span> + state.getStatus());</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">schedule</span><span class="params">()</span> &#123;</span><br><span class="line">        state.schedule(<span class="built_in">this</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">ioWait</span><span class="params">()</span> &#123;</span><br><span class="line">        state.ioWait(<span class="built_in">this</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">interrupt</span><span class="params">()</span> &#123;</span><br><span class="line">        state.interrupt(<span class="built_in">this</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">exit</span><span class="params">()</span> &#123;</span><br><span class="line">        state.exit(<span class="built_in">this</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">eventComplete</span><span class="params">()</span> &#123;</span><br><span class="line">        state.eventComplete(<span class="built_in">this</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">getStatus</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> state.getStatus();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>使用示例</p><figure class="highlight kt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">val</span> process = ProcessContext()</span><br><span class="line">process.schedule();         <span class="comment">// New -&gt; Ready</span></span><br><span class="line">process.schedule();         <span class="comment">// Ready -&gt; Running</span></span><br><span class="line">process.ioWait();           <span class="comment">// RUnning -&gt; Waiting</span></span><br><span class="line">process.eventComplete();    <span class="comment">// Waiting -&gt; Ready</span></span><br><span class="line">process.schedule();         <span class="comment">// Ready -&gt; Running</span></span><br><span class="line">process.exit();             <span class="comment">// Running -&gt; Terminated</span></span><br></pre></td></tr></table></figure><h2 id="总结"><a class="header-anchor" href="#总结">¶</a>总结</h2><p>通过状态模式，我们实现了：</p><ul><li>每个状态的行为解耦，易于维护和扩展。</li><li>避免了大量的条件判断语句。</li><li>可以轻松扩展更多状态(如挂起态Suspend、阻塞挂起态Blocked/Suspend等)</li></ul>]]></content>
    
    
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;允许对象在内部状态改变时改变它的行为，对象看起来好像修改了它的类。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;img src=&quot;/assert/puml/0b83ad009e90105d1594914fbdd4c7acca0ad6d3632b7f75709b11ff54d739f0.svg&quot;/&gt;</summary>
    
    
    <content src="https://galudisu.info/%3Cblockquote%3E%3Cp%3E%E5%85%81%E8%AE%B8%E5%AF%B9%E8%B1%A1%E5%9C%A8%E5%86%85%E9%83%A8%E7%8A%B6%E6%80%81%E6%94%B9%E5%8F%98%E6%97%B6%E6%94%B9%E5%8F%98%E5%AE%83%E7%9A%84%E8%A1%8C%E4%B8%BA%EF%BC%8C%E5%AF%B9%E8%B1%A1%E7%9C%8B%E8%B5%B7%E6%9D%A5%E5%A5%BD%E5%83%8F%E4%BF%AE%E6%94%B9%E4%BA%86%E5%AE%83%E7%9A%84%E7%B1%BB%E3%80%82%3C/p%3E%3C/blockquote%3E%3Cimg%20src=%22/assert/puml/0b83ad009e90105d1594914fbdd4c7acca0ad6d3632b7f75709b11ff54d739f0.svg%22/%3E%3Cspan%20id=%22more%22%3E%3C/span%3E%3Ch3%20id=%22%E6%A0%B8%E5%BF%83%E6%80%9D%E6%83%B3%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E6%A0%B8%E5%BF%83%E6%80%9D%E6%83%B3%22%3E%C2%B6%3C/a%3E%E6%A0%B8%E5%BF%83%E6%80%9D%E6%83%B3%3C/h3%3E%3Cp%3E%E5%B0%86%E7%8A%B6%E6%80%81%E7%9B%B8%E5%85%B3%E7%9A%84%E9%80%BB%E8%BE%91%E4%BB%8E%E4%B8%BB%E5%AF%B9%E8%B1%A1(%E4%B8%8A%E4%B8%8B%E6%96%87)%E4%B8%AD%E5%88%86%E7%A6%BB%E5%87%BA%E6%9D%A5%EF%BC%8C%E6%AF%8F%E4%B8%AA%E7%8A%B6%E6%80%81%E4%BD%9C%E4%B8%BA%E4%B8%80%E4%B8%AA%E7%8B%AC%E7%AB%8B%E7%9A%84%E7%B1%BB%E3%80%82%3C/p%3E%3Ch3%20id=%22%E7%BB%93%E6%9E%84%E7%BB%84%E6%88%90%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E7%BB%93%E6%9E%84%E7%BB%84%E6%88%90%22%3E%C2%B6%3C/a%3E%E7%BB%93%E6%9E%84%E7%BB%84%E6%88%90%3C/h3%3E%3Cul%3E%3Cli%3E%3Ccode%3EContext%3C/code%3E%EF%BC%9A%20%E7%BB%B4%E6%8A%A4%E4%B8%80%E4%B8%AA%E5%AF%B9%E5%BD%93%E5%89%8D%E7%8A%B6%E6%80%81%E7%9A%84%E5%BC%95%E7%94%A8%EF%BC%8C%E5%B9%B6%E5%AE%9A%E4%B9%89%E5%AE%A2%E6%88%B7%E6%84%9F%E5%85%B4%E8%B6%A3%E7%9A%84%E6%8E%A5%E5%8F%A3%E3%80%82%3C/li%3E%3Cli%3E%3Ccode%3EState%3C/code%3E%EF%BC%9A%20%E5%AE%9A%E4%B9%89%E4%B8%8E%E7%8A%B6%E6%80%81%E7%9B%B8%E5%85%B3%E7%9A%84%E8%A1%8C%E4%B8%BA%E3%80%82%3C/li%3E%3Cli%3E%3Ccode%3EConcreteState%3C/code%3E%E7%B1%BB%EF%BC%9A%20%E5%AE%9E%E7%8E%B0%3Ccode%3EState%3C/code%3E%E6%8E%A5%E5%8F%A3%E4%B8%AD%E5%AE%9A%E4%B9%89%E7%9A%84%E8%A1%8C%E4%B8%BA%EF%BC%8C%E5%B9%B6%E5%8F%AF%E8%83%BD%E6%A0%B9%E6%8D%AE%E7%8A%B6%E6%80%81%E7%9A%84%E5%8F%98%E5%8C%96%E4%BF%AE%E6%94%B9%3Ccode%3EContext%3C/code%3E%E7%9A%84%E7%8A%B6%E6%80%81%E3%80%82%3C/li%3E%3C/ul%3E%3Ch3%20id=%22%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF%22%3E%C2%B6%3C/a%3E%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF%3C/h3%3E%3Cul%3E%3Cli%3E%E5%BD%93%E4%B8%80%E4%B8%AA%E5%AF%B9%E8%B1%A1%E7%9A%84%E8%A1%8C%E4%B8%BA%E5%8F%96%E5%86%B3%E4%BA%8E%E5%AE%83%E7%9A%84%E7%8A%B6%E6%80%81%EF%BC%8C%E5%B9%B6%E4%B8%94%E5%AE%83%E5%BF%85%E9%A1%BB%E5%9C%A8%E8%BF%90%E8%A1%8C%E6%97%B6%E6%A0%B9%E6%8D%AE%E7%8A%B6%E6%80%81%E6%94%B9%E5%8F%98%E5%85%B6%E8%A1%8C%E4%B8%BA%E3%80%82%3C/li%3E%3Cli%3E%E5%BD%93%E4%B8%9A%E5%8A%A1%E9%80%BB%E8%BE%91%E4%B8%AD%E5%AD%98%E5%9C%A8%E5%A4%A7%E9%87%8F%E4%B8%8E%E7%8A%B6%E6%80%81%E7%9B%B8%E5%85%B3%E7%9A%84%E6%9D%A1%E4%BB%B6%E5%88%86%E6%94%AF%EF%BC%8C%E4%B8%94%E8%BF%99%E4%BA%9B%E5%88%86%E6%94%AF%E9%9A%8F%E7%9D%80%E7%8A%B6%E6%80%81%E5%8F%98%E5%8C%96%E8%80%8C%E5%8F%98%E5%8C%96%E3%80%82%3C/li%3E%3C/ul%3E%3Ch3%20id=%22%E7%9C%9F%E5%AE%9E%E6%A1%88%E4%BE%8B%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E7%9C%9F%E5%AE%9E%E6%A1%88%E4%BE%8B%22%3E%C2%B6%3C/a%3E%E7%9C%9F%E5%AE%9E%E6%A1%88%E4%BE%8B%3C/h3%3E%3Cp%3E%E8%AE%A1%E7%AE%97%E6%9C%BA%E8%BF%9B%E7%A8%8B%E5%9C%A8%E5%85%B6%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E6%9C%89%E2%80%9C%E4%B8%89%E6%80%81%E6%A8%A1%E5%9E%8B%E2%80%9D%E5%92%8C%E2%80%9C%E4%BA%94%E6%80%81%E6%A8%A1%E5%9E%8B%E2%80%9D%E3%80%82%3C/p%3E%3Cimg%20src=%22/assert/puml/64a3e32dbdd75f0eb9cd1d2862d7060da950c4df253da4a989352f476b41fe0e.svg%22/%3E%3Cp%3E%E5%85%88%E5%AE%9A%E4%B9%89%E7%8A%B6%E6%80%81%E6%8E%A5%E5%8F%A3%3Ccode%3EProcessState%3C/code%3E%3C/p%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E8%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Einterface%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EProcessState%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Eschedule%3C/span%3E%3Cspan%20class=%22params%22%3E(ProcessContext%20context)%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EioWait%3C/span%3E%3Cspan%20class=%22params%22%3E(ProcessContext%20context)%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Einterrupt%3C/span%3E%3Cspan%20class=%22params%22%3E(ProcessContext%20context)%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Eexit%3C/span%3E%3Cspan%20class=%22params%22%3E(ProcessContext%20context)%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EeventComplete%3C/span%3E%3Cspan%20class=%22params%22%3E(ProcessContext%20context)%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20String%20%3Cspan%20class=%22title%20function_%22%3EgetStatus%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Cp%3E%E5%85%B7%E4%BD%93%E7%8A%B6%E6%80%81%E7%B1%BB%3C/p%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E8%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E9%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E10%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E11%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E12%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E13%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E14%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E15%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E16%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E17%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E18%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E19%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E21%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E22%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E23%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E24%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E25%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E26%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E27%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E28%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E29%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E30%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E31%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E32%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E33%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E34%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E35%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E36%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E37%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E38%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E39%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E40%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E41%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E42%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E43%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E44%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E45%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E46%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E47%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E48%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E49%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E50%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E51%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E52%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E53%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E54%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E55%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E56%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E57%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E58%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E59%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E60%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E61%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E62%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E63%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E64%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E65%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E66%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E67%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E68%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E69%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E70%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E71%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E72%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E73%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E74%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E75%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E76%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E77%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E78%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E79%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E80%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E81%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E82%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E83%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E84%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E85%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E86%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E87%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E88%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E89%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E90%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E91%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E92%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E93%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E94%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E95%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E96%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E97%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E98%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E99%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E100%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E101%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E102%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E103%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E104%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E105%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3ENewState%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eimplements%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EProcessState%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Eschedule%3C/span%3E%3Cspan%20class=%22params%22%3E(ProcessContext%20context)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20System.out.println(%3Cspan%20class=%22string%22%3E&amp;quot;Admitting%20process%20to%20Ready%20state&amp;quot;%3C/span%3E);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20context.setState(%3Cspan%20class=%22keyword%22%3Enew%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EReadyState%3C/span%3E());%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Eexit%3C/span%3E%3Cspan%20class=%22params%22%3E(ProcessContext%20context)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20System.out.println(%3Cspan%20class=%22string%22%3E&amp;quot;Process%20terminated%20from%20New%20state&amp;quot;%3C/span%3E);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20context.setState(%3Cspan%20class=%22keyword%22%3Enew%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3ETerminatedState%3C/span%3E());%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22comment%22%3E/%20%E5%85%B6%E4%BB%96%E6%93%8D%E4%BD%9C%E6%97%A0%E6%84%8F%E4%B9%89%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EioWait%3C/span%3E%3Cspan%20class=%22params%22%3E(ProcessContext%20context)%3C/span%3E%20&amp;#123;&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Einterrupt%3C/span%3E%3Cspan%20class=%22params%22%3E(ProcessContext%20context)%3C/span%3E%20&amp;#123;&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EeventComplete%3C/span%3E%3Cspan%20class=%22params%22%3E(ProcessContext%20context)%3C/span%3E%20&amp;#123;&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20String%20%3Cspan%20class=%22title%20function_%22%3EgetStatus%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20%3Cspan%20class=%22keyword%22%3Ereturn%3C/span%3E%20%3Cspan%20class=%22string%22%3E&amp;quot;New&amp;quot;%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EReadyState%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eimplements%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EProcessState%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Eschedule%3C/span%3E%3Cspan%20class=%22params%22%3E(ProcessContext%20context)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20System.out.println(%3Cspan%20class=%22string%22%3E&amp;quot;Process%20is%20now%20Running&amp;quot;%3C/span%3E);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20context.setState(%3Cspan%20class=%22keyword%22%3Enew%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3ERunningState%3C/span%3E());%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22comment%22%3E/%20%E5%85%B6%E4%BB%96%E6%93%8D%E4%BD%9C%E6%9A%82%E4%B8%8D%E6%94%AF%E6%8C%81%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EioWait%3C/span%3E%3Cspan%20class=%22params%22%3E(ProcessContext%20context)%3C/span%3E%20&amp;#123;&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Einterrupt%3C/span%3E%3Cspan%20class=%22params%22%3E(ProcessContext%20context)%3C/span%3E%20&amp;#123;&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Eexit%3C/span%3E%3Cspan%20class=%22params%22%3E(ProcessContext%20context)%3C/span%3E%20&amp;#123;&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EeventComplete%3C/span%3E%3Cspan%20class=%22params%22%3E(ProcessContext%20context)%3C/span%3E%20&amp;#123;&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20String%20%3Cspan%20class=%22title%20function_%22%3EgetStatus%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20%3Cspan%20class=%22keyword%22%3Ereturn%3C/span%3E%20%3Cspan%20class=%22string%22%3E&amp;quot;Ready&amp;quot;%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3ERunningState%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eimplements%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EProcessState%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EioWait%3C/span%3E%3Cspan%20class=%22params%22%3E(ProcessContext%20context)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20System.out.println(%3Cspan%20class=%22string%22%3E&amp;quot;Process%20is%20waiting%20for%20I/O&amp;quot;%3C/span%3E);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20context.setState(%3Cspan%20class=%22keyword%22%3Enew%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EWaitingState%3C/span%3E());%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Einterrupt%3C/span%3E%3Cspan%20class=%22params%22%3E(ProcessContext%20context)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20System.out.println(%3Cspan%20class=%22string%22%3E&amp;quot;Process%20interrupted,%20back%20to%20Ready&amp;quot;%3C/span%3E);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20context.setState(%3Cspan%20class=%22keyword%22%3Enew%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EReadyState%3C/span%3E());%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Eexit%3C/span%3E%3Cspan%20class=%22params%22%3E(ProcessContext%20context)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20System.out.println(%3Cspan%20class=%22string%22%3E&amp;quot;Process%20exited%20normally&amp;quot;%3C/span%3E);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20context.setState(%3Cspan%20class=%22keyword%22%3Enew%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3ETerminatedState%3C/span%3E());%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22comment%22%3E/%20%E5%85%B6%E4%BB%96%E6%93%8D%E4%BD%9C%E6%97%A0%E6%84%8F%E4%B9%89%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Eschedule%3C/span%3E%3Cspan%20class=%22params%22%3E(ProcessContext%20context)%3C/span%3E%20&amp;#123;&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EeventComplete%3C/span%3E%3Cspan%20class=%22params%22%3E(ProcessContext%20context)%3C/span%3E%20&amp;#123;&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20String%20%3Cspan%20class=%22title%20function_%22%3EgetStatus%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20%3Cspan%20class=%22keyword%22%3Ereturn%3C/span%3E%20%3Cspan%20class=%22string%22%3E&amp;quot;Running&amp;quot;%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EWaitingState%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eimplements%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EProcessState%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EeventComplete%3C/span%3E%3Cspan%20class=%22params%22%3E(ProcessContext%20context)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20System.out.println(%3Cspan%20class=%22string%22%3E&amp;quot;I/O%20complete,%20back%20to%20Ready&amp;quot;%3C/span%3E);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20context.setState(%3Cspan%20class=%22keyword%22%3Enew%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EReadyState%3C/span%3E());%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22comment%22%3E/%20%E5%85%B6%E4%BB%96%E6%93%8D%E4%BD%9C%E6%97%A0%E6%84%8F%E4%B9%89%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Eschedule%3C/span%3E%3Cspan%20class=%22params%22%3E(ProcessContext%20context)%3C/span%3E%20&amp;#123;&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EioWait%3C/span%3E%3Cspan%20class=%22params%22%3E(ProcessContext%20context)%3C/span%3E%20&amp;#123;&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Einterrupt%3C/span%3E%3Cspan%20class=%22params%22%3E(ProcessContext%20context)%3C/span%3E%20&amp;#123;&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Eexit%3C/span%3E%3Cspan%20class=%22params%22%3E(ProcessContext%20context)%3C/span%3E%20&amp;#123;&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20String%20%3Cspan%20class=%22title%20function_%22%3EgetStatus%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20%3Cspan%20class=%22keyword%22%3Ereturn%3C/span%3E%20%3Cspan%20class=%22string%22%3E&amp;quot;Waiting&amp;quot;%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3ETerminatedState%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eimplements%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EProcessState%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20String%20%3Cspan%20class=%22title%20function_%22%3EgetStatus%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20%3Cspan%20class=%22keyword%22%3Ereturn%3C/span%3E%20%3Cspan%20class=%22string%22%3E&amp;quot;Terminated&amp;quot;%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22comment%22%3E/%20%E6%89%80%E6%9C%89%E6%93%8D%E4%BD%9C%E6%97%A0%E6%95%88%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Eschedule%3C/span%3E%3Cspan%20class=%22params%22%3E(ProcessContext%20context)%3C/span%3E%20&amp;#123;&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EioWait%3C/span%3E%3Cspan%20class=%22params%22%3E(ProcessContext%20context)%3C/span%3E%20&amp;#123;&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Einterrupt%3C/span%3E%3Cspan%20class=%22params%22%3E(ProcessContext%20context)%3C/span%3E%20&amp;#123;&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Eexit%3C/span%3E%3Cspan%20class=%22params%22%3E(ProcessContext%20context)%3C/span%3E%20&amp;#123;&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EeventComplete%3C/span%3E%3Cspan%20class=%22params%22%3E(ProcessContext%20context)%3C/span%3E%20&amp;#123;&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Cp%3E%E4%B8%8A%E4%B8%8B%E6%96%87%3Ccode%3EProcessContext%3C/code%3E%3C/p%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E8%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E9%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E10%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E11%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E12%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E13%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E14%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E15%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E16%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E17%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E18%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E19%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E21%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E22%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E23%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E24%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E25%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E26%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E27%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E28%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E29%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E30%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E31%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E32%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E33%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E34%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E35%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E36%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E37%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EProcessContext%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Eprivate%3C/span%3E%20ProcessState%20state;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EProcessContext%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20%3Cspan%20class=%22built_in%22%3Ethis%3C/span%3E.state%20=%20%3Cspan%20class=%22keyword%22%3Enew%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3ENewState%3C/span%3E();%20%20%3Cspan%20class=%22comment%22%3E/%20%E5%88%9D%E5%A7%8B%E7%8A%B6%E6%80%81%E4%B8%BA%20New%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EsetState%3C/span%3E%3Cspan%20class=%22params%22%3E(ProcessState%20state)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20%3Cspan%20class=%22built_in%22%3Ethis%3C/span%3E.state%20=%20state;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20System.out.println(%3Cspan%20class=%22string%22%3E&amp;quot;%E7%8A%B6%E6%80%81%E5%88%87%E6%8D%A2%E8%87%B3%EF%BC%9A&amp;quot;%3C/span%3E%20+%20state.getStatus());%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Eschedule%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20state.schedule(%3Cspan%20class=%22built_in%22%3Ethis%3C/span%3E);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EioWait%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20state.ioWait(%3Cspan%20class=%22built_in%22%3Ethis%3C/span%3E);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Einterrupt%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20state.interrupt(%3Cspan%20class=%22built_in%22%3Ethis%3C/span%3E);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Eexit%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20state.exit(%3Cspan%20class=%22built_in%22%3Ethis%3C/span%3E);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EeventComplete%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20state.eventComplete(%3Cspan%20class=%22built_in%22%3Ethis%3C/span%3E);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20String%20%3Cspan%20class=%22title%20function_%22%3EgetStatus%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20%3Cspan%20class=%22keyword%22%3Ereturn%3C/span%3E%20state.getStatus();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Cp%3E%E4%BD%BF%E7%94%A8%E7%A4%BA%E4%BE%8B%3C/p%3E%3Cfigure%20class=%22highlight%20kt%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Eval%3C/span%3E%20process%20=%20ProcessContext()%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3Eprocess.schedule();%20%20%20%20%20%20%20%20%20%3Cspan%20class=%22comment%22%3E/%20New%20-&amp;gt;%20Ready%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3Eprocess.schedule();%20%20%20%20%20%20%20%20%20%3Cspan%20class=%22comment%22%3E/%20Ready%20-&amp;gt;%20Running%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3Eprocess.ioWait();%20%20%20%20%20%20%20%20%20%20%20%3Cspan%20class=%22comment%22%3E/%20RUnning%20-&amp;gt;%20Waiting%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3Eprocess.eventComplete();%20%20%20%20%3Cspan%20class=%22comment%22%3E/%20Waiting%20-&amp;gt;%20Ready%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3Eprocess.schedule();%20%20%20%20%20%20%20%20%20%3Cspan%20class=%22comment%22%3E/%20Ready%20-&amp;gt;%20Running%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3Eprocess.exit();%20%20%20%20%20%20%20%20%20%20%20%20%20%3Cspan%20class=%22comment%22%3E/%20Running%20-&amp;gt;%20Terminated%3C/span%3E%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Ch2%20id=%22%E6%80%BB%E7%BB%93%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E6%80%BB%E7%BB%93%22%3E%C2%B6%3C/a%3E%E6%80%BB%E7%BB%93%3C/h2%3E%3Cp%3E%E9%80%9A%E8%BF%87%E7%8A%B6%E6%80%81%E6%A8%A1%E5%BC%8F%EF%BC%8C%E6%88%91%E4%BB%AC%E5%AE%9E%E7%8E%B0%E4%BA%86%EF%BC%9A%3C/p%3E%3Cul%3E%3Cli%3E%E6%AF%8F%E4%B8%AA%E7%8A%B6%E6%80%81%E7%9A%84%E8%A1%8C%E4%B8%BA%E8%A7%A3%E8%80%A6%EF%BC%8C%E6%98%93%E4%BA%8E%E7%BB%B4%E6%8A%A4%E5%92%8C%E6%89%A9%E5%B1%95%E3%80%82%3C/li%3E%3Cli%3E%E9%81%BF%E5%85%8D%E4%BA%86%E5%A4%A7%E9%87%8F%E7%9A%84%E6%9D%A1%E4%BB%B6%E5%88%A4%E6%96%AD%E8%AF%AD%E5%8F%A5%E3%80%82%3C/li%3E%3Cli%3E%E5%8F%AF%E4%BB%A5%E8%BD%BB%E6%9D%BE%E6%89%A9%E5%B1%95%E6%9B%B4%E5%A4%9A%E7%8A%B6%E6%80%81(%E5%A6%82%E6%8C%82%E8%B5%B7%E6%80%81Suspend%E3%80%81%E9%98%BB%E5%A1%9E%E6%8C%82%E8%B5%B7%E6%80%81Blocked/Suspend%E7%AD%89)%3C/li%3E%3C/ul%3E" type="image"/>
    
    
    
    <category term="behavioral" scheme="https://galudisu.info/tags/behavioral/"/>
    
    <category term="state" scheme="https://galudisu.info/tags/state/"/>
    
  </entry>
  
  <entry>
    <title>解析器模式(Interpreter Pattern)</title>
    <link href="https://galudisu.info/2025/05/10/pattern/basic/behavioral/Interpreter/"/>
    <id>https://galudisu.info/2025/05/10/pattern/basic/behavioral/Interpreter/</id>
    <published>2025-05-10T12:25:07.000Z</published>
    <updated>2026-04-14T19:59:33.853Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>提供了评估语言的语法或表达式的方式，它属于行为模式。这种模式实现了一个表达式接口，该接口解析一个特定的上下文。这种模式被用在SQL解析、符号处理引擎等。</p></blockquote><img src="/assert/puml/eeeda54ce800ba61aefb338c64054da718595063750afc7be99501c6bc9bbece.svg"/><span id="more"></span><h3 id="核心思想"><a class="header-anchor" href="#核心思想">¶</a>核心思想</h3><ul><li>将语言中的每个语法规则映射为一个类。</li><li>构建抽象语法树(AST)，由这些类的实例组成。</li><li>使用递归调用解释整个表达式。</li></ul><h3 id="角色组成"><a class="header-anchor" href="#角色组成">¶</a>角色组成</h3><table><thead><tr><th style="text-align:left"><strong>角色</strong></th><th style="text-align:left"><strong>说明</strong></th></tr></thead><tbody><tr><td style="text-align:left"><code>AbstractExpression</code></td><td style="text-align:left">定义解释操作的公共接口</td></tr><tr><td style="text-align:left"><code>TerminalExpression</code></td><td style="text-align:left">实现文法中与终结符相关的解释操作</td></tr><tr><td style="text-align:left"><code>NonterminalExpression</code></td><td style="text-align:left">实现文法中与非终结符相关的解释操作</td></tr><tr><td style="text-align:left"><code>Context</code></td><td style="text-align:left">包含解释器所需的全局信息</td></tr><tr><td style="text-align:left"><code>Client</code></td><td style="text-align:left">构建表示某一句子的抽象语法树并调用解释方法</td></tr></tbody></table><h3 id="适用场景"><a class="header-anchor" href="#适用场景">¶</a>适用场景</h3><ul><li>需要解释执行某种小型语言或表达式(如数学表达式、规则引擎中的条件判断)。</li><li>文法规则相对稳定且不复杂。</li><li>开发脚本引擎、DSL解析器、配置规则解释器等。</li></ul><h3 id="代码示例：布尔表达式解释器"><a class="header-anchor" href="#代码示例：布尔表达式解释器">¶</a>代码示例：布尔表达式解释器</h3><p>抽象表达式<code>Expression</code></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">Expression</span> &#123;</span><br><span class="line">  <span class="type">boolean</span> <span class="title function_">interpret</span><span class="params">(String context)</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>终结符表达式<code>TerminalExpression</code></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">TerminalExpression</span> <span class="keyword">implements</span> <span class="title class_">Expression</span> &#123;</span><br><span class="line">  <span class="keyword">private</span> String data;</span><br><span class="line">  <span class="keyword">public</span> <span class="title function_">TerminalExpression</span><span class="params">(String data)</span> &#123;</span><br><span class="line">    <span class="built_in">this</span>.data = data;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">interpret</span><span class="params">(String context)</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> context.contains(data);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>非终结符表达式<code>AndExpression</code></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">AndExpression</span> <span class="keyword">implements</span> <span class="title class_">Expression</span> &#123;</span><br><span class="line">  <span class="keyword">private</span> Expresion expr1;</span><br><span class="line">  <span class="keyword">private</span> Expression expr2;</span><br><span class="line">  </span><br><span class="line">  <span class="keyword">public</span> <span class="title function_">AndExpression</span><span class="params">(Expression expr1, Expression expr2)</span> &#123;</span><br><span class="line">    <span class="built_in">this</span>.expr1 = expr1;</span><br><span class="line">    <span class="built_in">this</span>.expr2 = expr2;</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">interpret</span><span class="params">(String context)</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> expr1.interpret(context) &amp;&amp; expr2.interpret(context);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>客户端使用</p><figure class="highlight kt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">val</span> context = <span class="string">&quot;John is happy today.&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">val</span> john = TerminalExpression(<span class="string">&quot;John&quot;</span>)</span><br><span class="line"><span class="keyword">val</span> happy = TerminalExpression(<span class="string">&quot;happy&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">val</span> expression = AndExpression(john, happy)</span><br><span class="line"></span><br><span class="line">expression.interpret(context))</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;提供了评估语言的语法或表达式的方式，它属于行为模式。这种模式实现了一个表达式接口，该接口解析一个特定的上下文。这种模式被用在SQL解析、符号处理引擎等。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;img src=&quot;/assert/puml/eeeda54ce800ba61aefb338c64054da718595063750afc7be99501c6bc9bbece.svg&quot;/&gt;</summary>
    
    
    <content src="https://galudisu.info/%3Cblockquote%3E%3Cp%3E%E6%8F%90%E4%BE%9B%E4%BA%86%E8%AF%84%E4%BC%B0%E8%AF%AD%E8%A8%80%E7%9A%84%E8%AF%AD%E6%B3%95%E6%88%96%E8%A1%A8%E8%BE%BE%E5%BC%8F%E7%9A%84%E6%96%B9%E5%BC%8F%EF%BC%8C%E5%AE%83%E5%B1%9E%E4%BA%8E%E8%A1%8C%E4%B8%BA%E6%A8%A1%E5%BC%8F%E3%80%82%E8%BF%99%E7%A7%8D%E6%A8%A1%E5%BC%8F%E5%AE%9E%E7%8E%B0%E4%BA%86%E4%B8%80%E4%B8%AA%E8%A1%A8%E8%BE%BE%E5%BC%8F%E6%8E%A5%E5%8F%A3%EF%BC%8C%E8%AF%A5%E6%8E%A5%E5%8F%A3%E8%A7%A3%E6%9E%90%E4%B8%80%E4%B8%AA%E7%89%B9%E5%AE%9A%E7%9A%84%E4%B8%8A%E4%B8%8B%E6%96%87%E3%80%82%E8%BF%99%E7%A7%8D%E6%A8%A1%E5%BC%8F%E8%A2%AB%E7%94%A8%E5%9C%A8SQL%E8%A7%A3%E6%9E%90%E3%80%81%E7%AC%A6%E5%8F%B7%E5%A4%84%E7%90%86%E5%BC%95%E6%93%8E%E7%AD%89%E3%80%82%3C/p%3E%3C/blockquote%3E%3Cimg%20src=%22/assert/puml/eeeda54ce800ba61aefb338c64054da718595063750afc7be99501c6bc9bbece.svg%22/%3E%3Cspan%20id=%22more%22%3E%3C/span%3E%3Ch3%20id=%22%E6%A0%B8%E5%BF%83%E6%80%9D%E6%83%B3%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E6%A0%B8%E5%BF%83%E6%80%9D%E6%83%B3%22%3E%C2%B6%3C/a%3E%E6%A0%B8%E5%BF%83%E6%80%9D%E6%83%B3%3C/h3%3E%3Cul%3E%3Cli%3E%E5%B0%86%E8%AF%AD%E8%A8%80%E4%B8%AD%E7%9A%84%E6%AF%8F%E4%B8%AA%E8%AF%AD%E6%B3%95%E8%A7%84%E5%88%99%E6%98%A0%E5%B0%84%E4%B8%BA%E4%B8%80%E4%B8%AA%E7%B1%BB%E3%80%82%3C/li%3E%3Cli%3E%E6%9E%84%E5%BB%BA%E6%8A%BD%E8%B1%A1%E8%AF%AD%E6%B3%95%E6%A0%91(AST)%EF%BC%8C%E7%94%B1%E8%BF%99%E4%BA%9B%E7%B1%BB%E7%9A%84%E5%AE%9E%E4%BE%8B%E7%BB%84%E6%88%90%E3%80%82%3C/li%3E%3Cli%3E%E4%BD%BF%E7%94%A8%E9%80%92%E5%BD%92%E8%B0%83%E7%94%A8%E8%A7%A3%E9%87%8A%E6%95%B4%E4%B8%AA%E8%A1%A8%E8%BE%BE%E5%BC%8F%E3%80%82%3C/li%3E%3C/ul%3E%3Ch3%20id=%22%E8%A7%92%E8%89%B2%E7%BB%84%E6%88%90%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E8%A7%92%E8%89%B2%E7%BB%84%E6%88%90%22%3E%C2%B6%3C/a%3E%E8%A7%92%E8%89%B2%E7%BB%84%E6%88%90%3C/h3%3E%3Ctable%3E%3Cthead%3E%3Ctr%3E%3Cth%20style=%22text-align:left%22%3E%3Cstrong%3E%E8%A7%92%E8%89%B2%3C/strong%3E%3C/th%3E%3Cth%20style=%22text-align:left%22%3E%3Cstrong%3E%E8%AF%B4%E6%98%8E%3C/strong%3E%3C/th%3E%3C/tr%3E%3C/thead%3E%3Ctbody%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%3Ccode%3EAbstractExpression%3C/code%3E%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E5%AE%9A%E4%B9%89%E8%A7%A3%E9%87%8A%E6%93%8D%E4%BD%9C%E7%9A%84%E5%85%AC%E5%85%B1%E6%8E%A5%E5%8F%A3%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%3Ccode%3ETerminalExpression%3C/code%3E%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E5%AE%9E%E7%8E%B0%E6%96%87%E6%B3%95%E4%B8%AD%E4%B8%8E%E7%BB%88%E7%BB%93%E7%AC%A6%E7%9B%B8%E5%85%B3%E7%9A%84%E8%A7%A3%E9%87%8A%E6%93%8D%E4%BD%9C%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%3Ccode%3ENonterminalExpression%3C/code%3E%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E5%AE%9E%E7%8E%B0%E6%96%87%E6%B3%95%E4%B8%AD%E4%B8%8E%E9%9D%9E%E7%BB%88%E7%BB%93%E7%AC%A6%E7%9B%B8%E5%85%B3%E7%9A%84%E8%A7%A3%E9%87%8A%E6%93%8D%E4%BD%9C%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%3Ccode%3EContext%3C/code%3E%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E5%8C%85%E5%90%AB%E8%A7%A3%E9%87%8A%E5%99%A8%E6%89%80%E9%9C%80%E7%9A%84%E5%85%A8%E5%B1%80%E4%BF%A1%E6%81%AF%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%3Ccode%3EClient%3C/code%3E%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E6%9E%84%E5%BB%BA%E8%A1%A8%E7%A4%BA%E6%9F%90%E4%B8%80%E5%8F%A5%E5%AD%90%E7%9A%84%E6%8A%BD%E8%B1%A1%E8%AF%AD%E6%B3%95%E6%A0%91%E5%B9%B6%E8%B0%83%E7%94%A8%E8%A7%A3%E9%87%8A%E6%96%B9%E6%B3%95%3C/td%3E%3C/tr%3E%3C/tbody%3E%3C/table%3E%3Ch3%20id=%22%E9%80%82%E7%94%A8%E5%9C%BA%E6%99%AF%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E9%80%82%E7%94%A8%E5%9C%BA%E6%99%AF%22%3E%C2%B6%3C/a%3E%E9%80%82%E7%94%A8%E5%9C%BA%E6%99%AF%3C/h3%3E%3Cul%3E%3Cli%3E%E9%9C%80%E8%A6%81%E8%A7%A3%E9%87%8A%E6%89%A7%E8%A1%8C%E6%9F%90%E7%A7%8D%E5%B0%8F%E5%9E%8B%E8%AF%AD%E8%A8%80%E6%88%96%E8%A1%A8%E8%BE%BE%E5%BC%8F(%E5%A6%82%E6%95%B0%E5%AD%A6%E8%A1%A8%E8%BE%BE%E5%BC%8F%E3%80%81%E8%A7%84%E5%88%99%E5%BC%95%E6%93%8E%E4%B8%AD%E7%9A%84%E6%9D%A1%E4%BB%B6%E5%88%A4%E6%96%AD)%E3%80%82%3C/li%3E%3Cli%3E%E6%96%87%E6%B3%95%E8%A7%84%E5%88%99%E7%9B%B8%E5%AF%B9%E7%A8%B3%E5%AE%9A%E4%B8%94%E4%B8%8D%E5%A4%8D%E6%9D%82%E3%80%82%3C/li%3E%3Cli%3E%E5%BC%80%E5%8F%91%E8%84%9A%E6%9C%AC%E5%BC%95%E6%93%8E%E3%80%81DSL%E8%A7%A3%E6%9E%90%E5%99%A8%E3%80%81%E9%85%8D%E7%BD%AE%E8%A7%84%E5%88%99%E8%A7%A3%E9%87%8A%E5%99%A8%E7%AD%89%E3%80%82%3C/li%3E%3C/ul%3E%3Ch3%20id=%22%E4%BB%A3%E7%A0%81%E7%A4%BA%E4%BE%8B%EF%BC%9A%E5%B8%83%E5%B0%94%E8%A1%A8%E8%BE%BE%E5%BC%8F%E8%A7%A3%E9%87%8A%E5%99%A8%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E4%BB%A3%E7%A0%81%E7%A4%BA%E4%BE%8B%EF%BC%9A%E5%B8%83%E5%B0%94%E8%A1%A8%E8%BE%BE%E5%BC%8F%E8%A7%A3%E9%87%8A%E5%99%A8%22%3E%C2%B6%3C/a%3E%E4%BB%A3%E7%A0%81%E7%A4%BA%E4%BE%8B%EF%BC%9A%E5%B8%83%E5%B0%94%E8%A1%A8%E8%BE%BE%E5%BC%8F%E8%A7%A3%E9%87%8A%E5%99%A8%3C/h3%3E%3Cp%3E%E6%8A%BD%E8%B1%A1%E8%A1%A8%E8%BE%BE%E5%BC%8F%3Ccode%3EExpression%3C/code%3E%3C/p%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Einterface%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EExpression%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22type%22%3Eboolean%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Einterpret%3C/span%3E%3Cspan%20class=%22params%22%3E(String%20context)%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Cp%3E%E7%BB%88%E7%BB%93%E7%AC%A6%E8%A1%A8%E8%BE%BE%E5%BC%8F%3Ccode%3ETerminalExpression%3C/code%3E%3C/p%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E8%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E9%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E10%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3ETerminalExpression%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eimplements%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EExpression%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Eprivate%3C/span%3E%20String%20data;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3ETerminalExpression%3C/span%3E%3Cspan%20class=%22params%22%3E(String%20data)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22built_in%22%3Ethis%3C/span%3E.data%20=%20data;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22type%22%3Eboolean%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Einterpret%3C/span%3E%3Cspan%20class=%22params%22%3E(String%20context)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Ereturn%3C/span%3E%20context.contains(data);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Cp%3E%E9%9D%9E%E7%BB%88%E7%BB%93%E7%AC%A6%E8%A1%A8%E8%BE%BE%E5%BC%8F%3Ccode%3EAndExpression%3C/code%3E%3C/p%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E8%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E9%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E10%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E11%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E12%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E13%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E14%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EAndExpression%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eimplements%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EExpression%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Eprivate%3C/span%3E%20Expresion%20expr1;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Eprivate%3C/span%3E%20Expression%20expr2;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EAndExpression%3C/span%3E%3Cspan%20class=%22params%22%3E(Expression%20expr1,%20Expression%20expr2)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22built_in%22%3Ethis%3C/span%3E.expr1%20=%20expr1;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22built_in%22%3Ethis%3C/span%3E.expr2%20=%20expr2;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22type%22%3Eboolean%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Einterpret%3C/span%3E%3Cspan%20class=%22params%22%3E(String%20context)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Ereturn%3C/span%3E%20expr1.interpret(context)%20&amp;amp;&amp;amp;%20expr2.interpret(context);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Cp%3E%E5%AE%A2%E6%88%B7%E7%AB%AF%E4%BD%BF%E7%94%A8%3C/p%3E%3Cfigure%20class=%22highlight%20kt%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E8%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Eval%3C/span%3E%20context%20=%20%3Cspan%20class=%22string%22%3E&amp;quot;John%20is%20happy%20today.&amp;quot;%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Eval%3C/span%3E%20john%20=%20TerminalExpression(%3Cspan%20class=%22string%22%3E&amp;quot;John&amp;quot;%3C/span%3E)%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Eval%3C/span%3E%20happy%20=%20TerminalExpression(%3Cspan%20class=%22string%22%3E&amp;quot;happy&amp;quot;%3C/span%3E)%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Eval%3C/span%3E%20expression%20=%20AndExpression(john,%20happy)%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3Eexpression.interpret(context))%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E" type="image"/>
    
    
    
    <category term="behavioral" scheme="https://galudisu.info/tags/behavioral/"/>
    
    <category term="interpreter" scheme="https://galudisu.info/tags/interpreter/"/>
    
  </entry>
  
  <entry>
    <title>备忘录模式(Memento Pattern)</title>
    <link href="https://galudisu.info/2025/05/10/pattern/basic/behavioral/Memento/"/>
    <id>https://galudisu.info/2025/05/10/pattern/basic/behavioral/Memento/</id>
    <published>2025-05-10T12:25:06.000Z</published>
    <updated>2026-04-14T19:59:33.737Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p><strong>保存</strong>一个对象的某个状态，以便在适当的时候恢复对象。备忘录模式属于行为模式。</p></blockquote><img src="/assert/puml/3a918a4789c9edc49b1b6b623b98ac304bf6cb39fd15770f1cdd0f276607fa3b.svg"/><span id="more"></span><h3 id="角色组成"><a class="header-anchor" href="#角色组成">¶</a>角色组成</h3><table><thead><tr><th style="text-align:left"><strong>角色</strong></th><th style="text-align:left"><strong>描述</strong></th></tr></thead><tbody><tr><td style="text-align:left"><code>Originator(发起人)</code></td><td style="text-align:left">创建一个备忘录以记录当前状态，并可以从备忘录中恢复状态。</td></tr><tr><td style="text-align:left"><code>Memento(备忘录)</code></td><td style="text-align:left">存储发起人的内部状态，通常设置为不可变且只允许发起人访问其内容。</td></tr><tr><td style="text-align:left"><code>Caretaker(管理者)</code></td><td style="text-align:left">负责保存备忘录对象，但不能对备忘录的内容进行操作或检查。</td></tr></tbody></table><h3 id="适用场景"><a class="header-anchor" href="#适用场景">¶</a>适用场景</h3><ul><li>需要实现撤销/重做功能(如文本编辑器、图形工具等)。</li><li>需要保存对象状态的历史记录，并在某个时刻恢复。</li><li>对象的状态变化频繁，但由不想影响其封装性和性能。</li></ul><h3 id="代码示例"><a class="header-anchor" href="#代码示例">¶</a>代码示例</h3><ol><li>备忘录类(Memento)</li></ol><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Memento</span> &#123;</span><br><span class="line">  priate String state;</span><br><span class="line">  <span class="keyword">public</span> <span class="title function_">Mento</span><span class="params">(String state)</span> &#123;</span><br><span class="line">    <span class="built_in">this</span>.state = state;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">public</span> String <span class="title function_">getState</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> state;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><ol start="2"><li>发起人(Originator)</li></ol><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Originator</span> &#123;</span><br><span class="line">  <span class="keyword">private</span> String state;</span><br><span class="line">  </span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setState</span><span class="params">(String state)</span> &#123;</span><br><span class="line">    <span class="built_in">this</span>.state = state;</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">  <span class="keyword">public</span> String <span class="title function_">getState</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> state;</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">  <span class="keyword">public</span> Memento <span class="title function_">saveStateToMemento</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Memento</span>(state);</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">restoreStateFromMemento</span><span class="params">(Remento memento)</span> &#123;</span><br><span class="line">    <span class="built_in">this</span>.state = memento.getState();</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><ol start="3"><li>管理者(Caretaker)</li></ol><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Caretaker</span> &#123;</span><br><span class="line">  <span class="keyword">private</span> List&lt;Memento&gt; mementoList = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">  </span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">addMemento</span><span class="params">(Memento memento)</span> &#123;</span><br><span class="line">    mementoList.add(memento);</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">  <span class="keyword">public</span> Memento <span class="title function_">getMemento</span><span class="params">(<span class="type">int</span> index)</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> mementoList.get(index);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><ol start="4"><li>使用示例</li></ol><figure class="highlight kt"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">val</span> originator = Originator()</span><br><span class="line"><span class="keyword">val</span> caretaker = Caretaker()</span><br><span class="line"></span><br><span class="line">originator.setState(<span class="string">&quot;State #1&quot;</span>)</span><br><span class="line">originator.setState(<span class="string">&quot;State #2&quot;</span>)</span><br><span class="line">caretaker.addMemento(originator.saveStateToMemento())</span><br><span class="line"></span><br><span class="line">originator.setState(<span class="string">&quot;State #3&quot;</span>)</span><br><span class="line">caretaker.addMemento(originator.saveStateToMemento())</span><br><span class="line"></span><br><span class="line">originator.setState(<span class="string">&quot;State #4&quot;</span>)</span><br><span class="line"></span><br><span class="line">originator.restoreStateFromMemento(caretaker.getMemento(<span class="number">0</span>))</span><br><span class="line"></span><br><span class="line">originator.restoreStateFromMemento(caretaker.getMemento(<span class="number">1</span>))</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;保存&lt;/strong&gt;一个对象的某个状态，以便在适当的时候恢复对象。备忘录模式属于行为模式。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;img src=&quot;/assert/puml/3a918a4789c9edc49b1b6b623b98ac304bf6cb39fd15770f1cdd0f276607fa3b.svg&quot;/&gt;</summary>
    
    
    <content src="https://galudisu.info/%3Cblockquote%3E%3Cp%3E%3Cstrong%3E%E4%BF%9D%E5%AD%98%3C/strong%3E%E4%B8%80%E4%B8%AA%E5%AF%B9%E8%B1%A1%E7%9A%84%E6%9F%90%E4%B8%AA%E7%8A%B6%E6%80%81%EF%BC%8C%E4%BB%A5%E4%BE%BF%E5%9C%A8%E9%80%82%E5%BD%93%E7%9A%84%E6%97%B6%E5%80%99%E6%81%A2%E5%A4%8D%E5%AF%B9%E8%B1%A1%E3%80%82%E5%A4%87%E5%BF%98%E5%BD%95%E6%A8%A1%E5%BC%8F%E5%B1%9E%E4%BA%8E%E8%A1%8C%E4%B8%BA%E6%A8%A1%E5%BC%8F%E3%80%82%3C/p%3E%3C/blockquote%3E%3Cimg%20src=%22/assert/puml/3a918a4789c9edc49b1b6b623b98ac304bf6cb39fd15770f1cdd0f276607fa3b.svg%22/%3E%3Cspan%20id=%22more%22%3E%3C/span%3E%3Ch3%20id=%22%E8%A7%92%E8%89%B2%E7%BB%84%E6%88%90%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E8%A7%92%E8%89%B2%E7%BB%84%E6%88%90%22%3E%C2%B6%3C/a%3E%E8%A7%92%E8%89%B2%E7%BB%84%E6%88%90%3C/h3%3E%3Ctable%3E%3Cthead%3E%3Ctr%3E%3Cth%20style=%22text-align:left%22%3E%3Cstrong%3E%E8%A7%92%E8%89%B2%3C/strong%3E%3C/th%3E%3Cth%20style=%22text-align:left%22%3E%3Cstrong%3E%E6%8F%8F%E8%BF%B0%3C/strong%3E%3C/th%3E%3C/tr%3E%3C/thead%3E%3Ctbody%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%3Ccode%3EOriginator(%E5%8F%91%E8%B5%B7%E4%BA%BA)%3C/code%3E%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E5%88%9B%E5%BB%BA%E4%B8%80%E4%B8%AA%E5%A4%87%E5%BF%98%E5%BD%95%E4%BB%A5%E8%AE%B0%E5%BD%95%E5%BD%93%E5%89%8D%E7%8A%B6%E6%80%81%EF%BC%8C%E5%B9%B6%E5%8F%AF%E4%BB%A5%E4%BB%8E%E5%A4%87%E5%BF%98%E5%BD%95%E4%B8%AD%E6%81%A2%E5%A4%8D%E7%8A%B6%E6%80%81%E3%80%82%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%3Ccode%3EMemento(%E5%A4%87%E5%BF%98%E5%BD%95)%3C/code%3E%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E5%AD%98%E5%82%A8%E5%8F%91%E8%B5%B7%E4%BA%BA%E7%9A%84%E5%86%85%E9%83%A8%E7%8A%B6%E6%80%81%EF%BC%8C%E9%80%9A%E5%B8%B8%E8%AE%BE%E7%BD%AE%E4%B8%BA%E4%B8%8D%E5%8F%AF%E5%8F%98%E4%B8%94%E5%8F%AA%E5%85%81%E8%AE%B8%E5%8F%91%E8%B5%B7%E4%BA%BA%E8%AE%BF%E9%97%AE%E5%85%B6%E5%86%85%E5%AE%B9%E3%80%82%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%3Ccode%3ECaretaker(%E7%AE%A1%E7%90%86%E8%80%85)%3C/code%3E%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E8%B4%9F%E8%B4%A3%E4%BF%9D%E5%AD%98%E5%A4%87%E5%BF%98%E5%BD%95%E5%AF%B9%E8%B1%A1%EF%BC%8C%E4%BD%86%E4%B8%8D%E8%83%BD%E5%AF%B9%E5%A4%87%E5%BF%98%E5%BD%95%E7%9A%84%E5%86%85%E5%AE%B9%E8%BF%9B%E8%A1%8C%E6%93%8D%E4%BD%9C%E6%88%96%E6%A3%80%E6%9F%A5%E3%80%82%3C/td%3E%3C/tr%3E%3C/tbody%3E%3C/table%3E%3Ch3%20id=%22%E9%80%82%E7%94%A8%E5%9C%BA%E6%99%AF%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E9%80%82%E7%94%A8%E5%9C%BA%E6%99%AF%22%3E%C2%B6%3C/a%3E%E9%80%82%E7%94%A8%E5%9C%BA%E6%99%AF%3C/h3%3E%3Cul%3E%3Cli%3E%E9%9C%80%E8%A6%81%E5%AE%9E%E7%8E%B0%E6%92%A4%E9%94%80/%E9%87%8D%E5%81%9A%E5%8A%9F%E8%83%BD(%E5%A6%82%E6%96%87%E6%9C%AC%E7%BC%96%E8%BE%91%E5%99%A8%E3%80%81%E5%9B%BE%E5%BD%A2%E5%B7%A5%E5%85%B7%E7%AD%89)%E3%80%82%3C/li%3E%3Cli%3E%E9%9C%80%E8%A6%81%E4%BF%9D%E5%AD%98%E5%AF%B9%E8%B1%A1%E7%8A%B6%E6%80%81%E7%9A%84%E5%8E%86%E5%8F%B2%E8%AE%B0%E5%BD%95%EF%BC%8C%E5%B9%B6%E5%9C%A8%E6%9F%90%E4%B8%AA%E6%97%B6%E5%88%BB%E6%81%A2%E5%A4%8D%E3%80%82%3C/li%3E%3Cli%3E%E5%AF%B9%E8%B1%A1%E7%9A%84%E7%8A%B6%E6%80%81%E5%8F%98%E5%8C%96%E9%A2%91%E7%B9%81%EF%BC%8C%E4%BD%86%E7%94%B1%E4%B8%8D%E6%83%B3%E5%BD%B1%E5%93%8D%E5%85%B6%E5%B0%81%E8%A3%85%E6%80%A7%E5%92%8C%E6%80%A7%E8%83%BD%E3%80%82%3C/li%3E%3C/ul%3E%3Ch3%20id=%22%E4%BB%A3%E7%A0%81%E7%A4%BA%E4%BE%8B%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E4%BB%A3%E7%A0%81%E7%A4%BA%E4%BE%8B%22%3E%C2%B6%3C/a%3E%E4%BB%A3%E7%A0%81%E7%A4%BA%E4%BE%8B%3C/h3%3E%3Col%3E%3Cli%3E%E5%A4%87%E5%BF%98%E5%BD%95%E7%B1%BB(Memento)%3C/li%3E%3C/ol%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E8%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E9%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EMemento%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20priate%20String%20state;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EMento%3C/span%3E%3Cspan%20class=%22params%22%3E(String%20state)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22built_in%22%3Ethis%3C/span%3E.state%20=%20state;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20String%20%3Cspan%20class=%22title%20function_%22%3EgetState%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Ereturn%3C/span%3E%20state;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Col%20start=%222%22%3E%3Cli%3E%E5%8F%91%E8%B5%B7%E4%BA%BA(Originator)%3C/li%3E%3C/ol%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E8%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E9%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E10%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E11%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E12%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E13%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E14%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E15%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E16%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E17%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E18%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E19%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EOriginator%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Eprivate%3C/span%3E%20String%20state;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EsetState%3C/span%3E%3Cspan%20class=%22params%22%3E(String%20state)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22built_in%22%3Ethis%3C/span%3E.state%20=%20state;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20String%20%3Cspan%20class=%22title%20function_%22%3EgetState%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Ereturn%3C/span%3E%20state;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20Memento%20%3Cspan%20class=%22title%20function_%22%3EsaveStateToMemento%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Ereturn%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Enew%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EMemento%3C/span%3E(state);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3ErestoreStateFromMemento%3C/span%3E%3Cspan%20class=%22params%22%3E(Remento%20memento)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22built_in%22%3Ethis%3C/span%3E.state%20=%20memento.getState();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Col%20start=%223%22%3E%3Cli%3E%E7%AE%A1%E7%90%86%E8%80%85(Caretaker)%3C/li%3E%3C/ol%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E8%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E9%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E10%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E11%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3ECaretaker%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Eprivate%3C/span%3E%20List&amp;lt;Memento&amp;gt;%20mementoList%20=%20%3Cspan%20class=%22keyword%22%3Enew%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EArrayList%3C/span%3E&amp;lt;&amp;gt;();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EaddMemento%3C/span%3E%3Cspan%20class=%22params%22%3E(Memento%20memento)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20mementoList.add(memento);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20Memento%20%3Cspan%20class=%22title%20function_%22%3EgetMemento%3C/span%3E%3Cspan%20class=%22params%22%3E(%3Cspan%20class=%22type%22%3Eint%3C/span%3E%20index)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Ereturn%3C/span%3E%20mementoList.get(index);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Col%20start=%224%22%3E%3Cli%3E%E4%BD%BF%E7%94%A8%E7%A4%BA%E4%BE%8B%3C/li%3E%3C/ol%3E%3Cfigure%20class=%22highlight%20kt%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E8%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E9%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E10%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E11%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E12%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E13%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E14%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E15%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Eval%3C/span%3E%20originator%20=%20Originator()%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Eval%3C/span%3E%20caretaker%20=%20Caretaker()%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3Eoriginator.setState(%3Cspan%20class=%22string%22%3E&amp;quot;State%20#1&amp;quot;%3C/span%3E)%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3Eoriginator.setState(%3Cspan%20class=%22string%22%3E&amp;quot;State%20#2&amp;quot;%3C/span%3E)%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3Ecaretaker.addMemento(originator.saveStateToMemento())%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3Eoriginator.setState(%3Cspan%20class=%22string%22%3E&amp;quot;State%20#3&amp;quot;%3C/span%3E)%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3Ecaretaker.addMemento(originator.saveStateToMemento())%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3Eoriginator.setState(%3Cspan%20class=%22string%22%3E&amp;quot;State%20#4&amp;quot;%3C/span%3E)%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3Eoriginator.restoreStateFromMemento(caretaker.getMemento(%3Cspan%20class=%22number%22%3E0%3C/span%3E))%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3Eoriginator.restoreStateFromMemento(caretaker.getMemento(%3Cspan%20class=%22number%22%3E1%3C/span%3E))%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E" type="image"/>
    
    
    
    <category term="behavioral" scheme="https://galudisu.info/tags/behavioral/"/>
    
    <category term="memento" scheme="https://galudisu.info/tags/memento/"/>
    
  </entry>
  
  <entry>
    <title>中介模式(Mediator Pattern)</title>
    <link href="https://galudisu.info/2025/05/10/pattern/basic/behavioral/Mediator/"/>
    <id>https://galudisu.info/2025/05/10/pattern/basic/behavioral/Mediator/</id>
    <published>2025-05-10T12:25:05.000Z</published>
    <updated>2026-04-14T19:59:33.660Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>用来降低多个对象和类之前的通信复杂性。这种模式提供了一个中介类，该类通常处理不同类之前的通信，并支持松耦合，使代码易于维护。</p></blockquote><img src="/assert/puml/c6a44092318d8a402d6d7a2ffbddd8bcf76b65c0eb60b24a8066c61107b8dc79.svg"/><span id="more"></span><h3 id="核心思想"><a class="header-anchor" href="#核心思想">¶</a>核心思想</h3><ul><li>将对象之前的交互逻辑集中到一个中介者对象中处理。</li><li>对象之前不再相互引用，而是通过中介者进行通信。</li></ul><h3 id="角色组成"><a class="header-anchor" href="#角色组成">¶</a>角色组成</h3><table><thead><tr><th style="text-align:left"><strong>角色</strong></th><th style="text-align:left"><strong>描述</strong></th></tr></thead><tbody><tr><td style="text-align:left"><code>Mediator(抽象中介者)</code></td><td style="text-align:left">定义同事对象之间的通信接口。</td></tr><tr><td style="text-align:left"><code>ConcreteMediator(具体中介者)</code></td><td style="text-align:left">实现具体的交互逻辑，并协调同事对象。</td></tr><tr><td style="text-align:left"><code>Colleague(抽象同事类)</code></td><td style="text-align:left">持有中介者对象，定义与业务相关的方法。</td></tr><tr><td style="text-align:left"><code>ConcreteColleauge(具体同事类)</code></td><td style="text-align:left">实现具体的业务方法，并通过中介者与其他同事交互。</td></tr></tbody></table><h3 id="代码示例"><a class="header-anchor" href="#代码示例">¶</a>代码示例</h3><ol><li>抽象中介者</li></ol><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">Mediator</span> &#123;</span><br><span class="line">  <span class="keyword">void</span> <span class="title function_">send</span><span class="params">(String message, Colleague colleague)</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><ol start="2"><li>具体中介者</li></ol><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">pubic <span class="keyword">class</span> <span class="title class_">ConcreteMediator</span> <span class="keyword">implements</span> <span class="title class_">Mediator</span> &#123;</span><br><span class="line">  <span class="keyword">private</span> Colleague colleagueA;</span><br><span class="line">  <span class="keyword">private</span> Colleague colleagueB;</span><br><span class="line">  </span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setColleagueA</span><span class="params">(Colleague colleagueA)</span> &#123;</span><br><span class="line">    <span class="built_in">this</span>.colleagueA = colleagueA;</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setColleagueB</span><span class="params">(Colleague colleagueB)</span> &#123;</span><br><span class="line">    <span class="built_in">this</span>.colleagueB = colleagueB;</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">send</span><span class="params">(String message, Colleague colleague)</span> &#123;</span><br><span class="line">    <span class="keyword">if</span> (colleague == colleagueA) &#123;</span><br><span class="line">      colleagueB.receive(message);</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">      colleagueA.receive(message);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><ol start="3"><li>抽象同事类</li></ol><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="keyword">class</span> <span class="title class_">Colleague</span> &#123;</span><br><span class="line">  <span class="keyword">protected</span> Mediator mediator;</span><br><span class="line">  </span><br><span class="line">  <span class="keyword">public</span> <span class="title function_">Colleague</span><span class="params">(Mediator mediator)</span> &#123;</span><br><span class="line">    <span class="built_in">this</span>.mediator = mediator;</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">abstract</span> <span class="keyword">void</span> <span class="title function_">send</span><span class="params">(String message)</span>;</span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">abstract</span> <span class="keyword">void</span> <span class="title function_">receive</span><span class="params">(String message)</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><ol start="4"><li>具体同事类</li></ol><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">ConcreteColleagueA</span> <span class="keyword">extends</span> <span class="title class_">Colleague</span> &#123;</span><br><span class="line">  <span class="keyword">public</span> <span class="title function_">ConcreteColleagueA</span><span class="params">(Mediator mediator)</span> &#123;</span><br><span class="line">    <span class="built_in">super</span>(mediator);</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">send</span><span class="params">(String message)</span> &#123;</span><br><span class="line">    mediator.send(message, <span class="built_in">this</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">receive</span><span class="params">(String message)</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">ConcreteColleagueB</span> <span class="keyword">extends</span> <span class="title class_">Colleague</span> &#123;</span><br><span class="line">  <span class="keyword">public</span> <span class="title function_">ConcreteColleagueB</span><span class="params">(Mediator mediator)</span> &#123;</span><br><span class="line">    <span class="built_in">super</span>(mediator);</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">send</span><span class="params">(String message)</span> &#123;</span><br><span class="line">    mediator.send(message, <span class="built_in">this</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">receive</span><span class="params">(String message)</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br></pre></td></tr></table></figure><ol start="5"><li>使用示例</li></ol><figure class="highlight kotlin"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">val</span> mediator = new ConcreteMediator();</span><br><span class="line"></span><br><span class="line"><span class="keyword">val</span> colleagueA = ConcreteColleagueA(mediator);</span><br><span class="line"><span class="keyword">val</span> colleagueB = ConcreteColleagueB(mediator):</span><br><span class="line"></span><br><span class="line">mediator.setColleagueA(colleagueA);</span><br><span class="line">mediator.setColleagueB(colleagueB);</span><br><span class="line"></span><br><span class="line">colleagueA.send(<span class="string">&quot;Hello from A!&quot;</span>);</span><br><span class="line">colleagueB.send(<span class="string">&quot;Hi from B!&quot;</span>);</span><br></pre></td></tr></table></figure><h2 id="总结"><a class="header-anchor" href="#总结">¶</a>总结</h2><p>中介者模式通过引入中介者对象，将对象之间的复杂交互解耦，使系统清晰和易于维护。它适用于对象之间交互复杂、需要统一管理通信的场景。</p>]]></content>
    
    
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;用来降低多个对象和类之前的通信复杂性。这种模式提供了一个中介类，该类通常处理不同类之前的通信，并支持松耦合，使代码易于维护。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;img src=&quot;/assert/puml/c6a44092318d8a402d6d7a2ffbddd8bcf76b65c0eb60b24a8066c61107b8dc79.svg&quot;/&gt;</summary>
    
    
    <content src="https://galudisu.info/%3Cblockquote%3E%3Cp%3E%E7%94%A8%E6%9D%A5%E9%99%8D%E4%BD%8E%E5%A4%9A%E4%B8%AA%E5%AF%B9%E8%B1%A1%E5%92%8C%E7%B1%BB%E4%B9%8B%E5%89%8D%E7%9A%84%E9%80%9A%E4%BF%A1%E5%A4%8D%E6%9D%82%E6%80%A7%E3%80%82%E8%BF%99%E7%A7%8D%E6%A8%A1%E5%BC%8F%E6%8F%90%E4%BE%9B%E4%BA%86%E4%B8%80%E4%B8%AA%E4%B8%AD%E4%BB%8B%E7%B1%BB%EF%BC%8C%E8%AF%A5%E7%B1%BB%E9%80%9A%E5%B8%B8%E5%A4%84%E7%90%86%E4%B8%8D%E5%90%8C%E7%B1%BB%E4%B9%8B%E5%89%8D%E7%9A%84%E9%80%9A%E4%BF%A1%EF%BC%8C%E5%B9%B6%E6%94%AF%E6%8C%81%E6%9D%BE%E8%80%A6%E5%90%88%EF%BC%8C%E4%BD%BF%E4%BB%A3%E7%A0%81%E6%98%93%E4%BA%8E%E7%BB%B4%E6%8A%A4%E3%80%82%3C/p%3E%3C/blockquote%3E%3Cimg%20src=%22/assert/puml/c6a44092318d8a402d6d7a2ffbddd8bcf76b65c0eb60b24a8066c61107b8dc79.svg%22/%3E%3Cspan%20id=%22more%22%3E%3C/span%3E%3Ch3%20id=%22%E6%A0%B8%E5%BF%83%E6%80%9D%E6%83%B3%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E6%A0%B8%E5%BF%83%E6%80%9D%E6%83%B3%22%3E%C2%B6%3C/a%3E%E6%A0%B8%E5%BF%83%E6%80%9D%E6%83%B3%3C/h3%3E%3Cul%3E%3Cli%3E%E5%B0%86%E5%AF%B9%E8%B1%A1%E4%B9%8B%E5%89%8D%E7%9A%84%E4%BA%A4%E4%BA%92%E9%80%BB%E8%BE%91%E9%9B%86%E4%B8%AD%E5%88%B0%E4%B8%80%E4%B8%AA%E4%B8%AD%E4%BB%8B%E8%80%85%E5%AF%B9%E8%B1%A1%E4%B8%AD%E5%A4%84%E7%90%86%E3%80%82%3C/li%3E%3Cli%3E%E5%AF%B9%E8%B1%A1%E4%B9%8B%E5%89%8D%E4%B8%8D%E5%86%8D%E7%9B%B8%E4%BA%92%E5%BC%95%E7%94%A8%EF%BC%8C%E8%80%8C%E6%98%AF%E9%80%9A%E8%BF%87%E4%B8%AD%E4%BB%8B%E8%80%85%E8%BF%9B%E8%A1%8C%E9%80%9A%E4%BF%A1%E3%80%82%3C/li%3E%3C/ul%3E%3Ch3%20id=%22%E8%A7%92%E8%89%B2%E7%BB%84%E6%88%90%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E8%A7%92%E8%89%B2%E7%BB%84%E6%88%90%22%3E%C2%B6%3C/a%3E%E8%A7%92%E8%89%B2%E7%BB%84%E6%88%90%3C/h3%3E%3Ctable%3E%3Cthead%3E%3Ctr%3E%3Cth%20style=%22text-align:left%22%3E%3Cstrong%3E%E8%A7%92%E8%89%B2%3C/strong%3E%3C/th%3E%3Cth%20style=%22text-align:left%22%3E%3Cstrong%3E%E6%8F%8F%E8%BF%B0%3C/strong%3E%3C/th%3E%3C/tr%3E%3C/thead%3E%3Ctbody%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%3Ccode%3EMediator(%E6%8A%BD%E8%B1%A1%E4%B8%AD%E4%BB%8B%E8%80%85)%3C/code%3E%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E5%AE%9A%E4%B9%89%E5%90%8C%E4%BA%8B%E5%AF%B9%E8%B1%A1%E4%B9%8B%E9%97%B4%E7%9A%84%E9%80%9A%E4%BF%A1%E6%8E%A5%E5%8F%A3%E3%80%82%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%3Ccode%3EConcreteMediator(%E5%85%B7%E4%BD%93%E4%B8%AD%E4%BB%8B%E8%80%85)%3C/code%3E%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E5%AE%9E%E7%8E%B0%E5%85%B7%E4%BD%93%E7%9A%84%E4%BA%A4%E4%BA%92%E9%80%BB%E8%BE%91%EF%BC%8C%E5%B9%B6%E5%8D%8F%E8%B0%83%E5%90%8C%E4%BA%8B%E5%AF%B9%E8%B1%A1%E3%80%82%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%3Ccode%3EColleague(%E6%8A%BD%E8%B1%A1%E5%90%8C%E4%BA%8B%E7%B1%BB)%3C/code%3E%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E6%8C%81%E6%9C%89%E4%B8%AD%E4%BB%8B%E8%80%85%E5%AF%B9%E8%B1%A1%EF%BC%8C%E5%AE%9A%E4%B9%89%E4%B8%8E%E4%B8%9A%E5%8A%A1%E7%9B%B8%E5%85%B3%E7%9A%84%E6%96%B9%E6%B3%95%E3%80%82%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%3Ccode%3EConcreteColleauge(%E5%85%B7%E4%BD%93%E5%90%8C%E4%BA%8B%E7%B1%BB)%3C/code%3E%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E5%AE%9E%E7%8E%B0%E5%85%B7%E4%BD%93%E7%9A%84%E4%B8%9A%E5%8A%A1%E6%96%B9%E6%B3%95%EF%BC%8C%E5%B9%B6%E9%80%9A%E8%BF%87%E4%B8%AD%E4%BB%8B%E8%80%85%E4%B8%8E%E5%85%B6%E4%BB%96%E5%90%8C%E4%BA%8B%E4%BA%A4%E4%BA%92%E3%80%82%3C/td%3E%3C/tr%3E%3C/tbody%3E%3C/table%3E%3Ch3%20id=%22%E4%BB%A3%E7%A0%81%E7%A4%BA%E4%BE%8B%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E4%BB%A3%E7%A0%81%E7%A4%BA%E4%BE%8B%22%3E%C2%B6%3C/a%3E%E4%BB%A3%E7%A0%81%E7%A4%BA%E4%BE%8B%3C/h3%3E%3Col%3E%3Cli%3E%E6%8A%BD%E8%B1%A1%E4%B8%AD%E4%BB%8B%E8%80%85%3C/li%3E%3C/ol%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Einterface%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EMediator%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Esend%3C/span%3E%3Cspan%20class=%22params%22%3E(String%20message,%20Colleague%20colleague)%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Col%20start=%222%22%3E%3Cli%3E%E5%85%B7%E4%BD%93%E4%B8%AD%E4%BB%8B%E8%80%85%3C/li%3E%3C/ol%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E8%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E9%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E10%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E11%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E12%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E13%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E14%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E15%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E16%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E17%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E18%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E19%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E21%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3Epubic%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EConcreteMediator%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eimplements%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EMediator%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Eprivate%3C/span%3E%20Colleague%20colleagueA;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Eprivate%3C/span%3E%20Colleague%20colleagueB;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EsetColleagueA%3C/span%3E%3Cspan%20class=%22params%22%3E(Colleague%20colleagueA)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22built_in%22%3Ethis%3C/span%3E.colleagueA%20=%20colleagueA;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EsetColleagueB%3C/span%3E%3Cspan%20class=%22params%22%3E(Colleague%20colleagueB)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22built_in%22%3Ethis%3C/span%3E.colleagueB%20=%20colleagueB;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Esend%3C/span%3E%3Cspan%20class=%22params%22%3E(String%20message,%20Colleague%20colleague)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Eif%3C/span%3E%20(colleague%20==%20colleagueA)%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20colleagueB.receive(message);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%20%3Cspan%20class=%22keyword%22%3Eelse%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20colleagueA.receive(message);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Col%20start=%223%22%3E%3Cli%3E%E6%8A%BD%E8%B1%A1%E5%90%8C%E4%BA%8B%E7%B1%BB%3C/li%3E%3C/ol%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E8%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E9%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E10%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eabstract%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EColleague%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Eprotected%3C/span%3E%20Mediator%20mediator;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EColleague%3C/span%3E%3Cspan%20class=%22params%22%3E(Mediator%20mediator)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22built_in%22%3Ethis%3C/span%3E.mediator%20=%20mediator;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eabstract%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Esend%3C/span%3E%3Cspan%20class=%22params%22%3E(String%20message)%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eabstract%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Ereceive%3C/span%3E%3Cspan%20class=%22params%22%3E(String%20message)%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Col%20start=%224%22%3E%3Cli%3E%E5%85%B7%E4%BD%93%E5%90%8C%E4%BA%8B%E7%B1%BB%3C/li%3E%3C/ol%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E8%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E9%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E10%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E11%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E12%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E13%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E14%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E15%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E16%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E17%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E18%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E19%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E21%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E22%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E23%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E24%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E25%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E26%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E27%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E28%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EConcreteColleagueA%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eextends%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EColleague%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EConcreteColleagueA%3C/span%3E%3Cspan%20class=%22params%22%3E(Mediator%20mediator)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22built_in%22%3Esuper%3C/span%3E(mediator);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Esend%3C/span%3E%3Cspan%20class=%22params%22%3E(String%20message)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20mediator.send(message,%20%3Cspan%20class=%22built_in%22%3Ethis%3C/span%3E);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Ereceive%3C/span%3E%3Cspan%20class=%22params%22%3E(String%20message)%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EConcreteColleagueB%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eextends%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EColleague%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EConcreteColleagueB%3C/span%3E%3Cspan%20class=%22params%22%3E(Mediator%20mediator)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22built_in%22%3Esuper%3C/span%3E(mediator);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Esend%3C/span%3E%3Cspan%20class=%22params%22%3E(String%20message)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20mediator.send(message,%20%3Cspan%20class=%22built_in%22%3Ethis%3C/span%3E);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Ereceive%3C/span%3E%3Cspan%20class=%22params%22%3E(String%20message)%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Col%20start=%225%22%3E%3Cli%3E%E4%BD%BF%E7%94%A8%E7%A4%BA%E4%BE%8B%3C/li%3E%3C/ol%3E%3Cfigure%20class=%22highlight%20kotlin%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E8%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E9%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E10%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Eval%3C/span%3E%20mediator%20=%20new%20ConcreteMediator();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Eval%3C/span%3E%20colleagueA%20=%20ConcreteColleagueA(mediator);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Eval%3C/span%3E%20colleagueB%20=%20ConcreteColleagueB(mediator):%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3Emediator.setColleagueA(colleagueA);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3Emediator.setColleagueB(colleagueB);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3EcolleagueA.send(%3Cspan%20class=%22string%22%3E&amp;quot;Hello%20from%20A!&amp;quot;%3C/span%3E);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3EcolleagueB.send(%3Cspan%20class=%22string%22%3E&amp;quot;Hi%20from%20B!&amp;quot;%3C/span%3E);%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Ch2%20id=%22%E6%80%BB%E7%BB%93%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E6%80%BB%E7%BB%93%22%3E%C2%B6%3C/a%3E%E6%80%BB%E7%BB%93%3C/h2%3E%3Cp%3E%E4%B8%AD%E4%BB%8B%E8%80%85%E6%A8%A1%E5%BC%8F%E9%80%9A%E8%BF%87%E5%BC%95%E5%85%A5%E4%B8%AD%E4%BB%8B%E8%80%85%E5%AF%B9%E8%B1%A1%EF%BC%8C%E5%B0%86%E5%AF%B9%E8%B1%A1%E4%B9%8B%E9%97%B4%E7%9A%84%E5%A4%8D%E6%9D%82%E4%BA%A4%E4%BA%92%E8%A7%A3%E8%80%A6%EF%BC%8C%E4%BD%BF%E7%B3%BB%E7%BB%9F%E6%B8%85%E6%99%B0%E5%92%8C%E6%98%93%E4%BA%8E%E7%BB%B4%E6%8A%A4%E3%80%82%E5%AE%83%E9%80%82%E7%94%A8%E4%BA%8E%E5%AF%B9%E8%B1%A1%E4%B9%8B%E9%97%B4%E4%BA%A4%E4%BA%92%E5%A4%8D%E6%9D%82%E3%80%81%E9%9C%80%E8%A6%81%E7%BB%9F%E4%B8%80%E7%AE%A1%E7%90%86%E9%80%9A%E4%BF%A1%E7%9A%84%E5%9C%BA%E6%99%AF%E3%80%82%3C/p%3E" type="image"/>
    
    
    
    <category term="behavioral" scheme="https://galudisu.info/tags/behavioral/"/>
    
    <category term="mediator" scheme="https://galudisu.info/tags/mediator/"/>
    
  </entry>
  
  <entry>
    <title>观察者模式(Observer Pattern)</title>
    <link href="https://galudisu.info/2025/05/10/pattern/basic/behavioral/Observer/"/>
    <id>https://galudisu.info/2025/05/10/pattern/basic/behavioral/Observer/</id>
    <published>2025-05-10T12:25:04.000Z</published>
    <updated>2026-04-14T19:59:33.530Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>定义了对象之间的一对多的依赖，这样一来，当一个对象改变时，它的所有的依赖者都会收到通知并自动更新。</p></blockquote><img src="/assert/puml/04f6002ad969a8a50b07a74005a40a498656cfe9ae7e2ff05ac780d2e1d911e1.svg"/><span id="more"></span><h3 id="模式结构"><a class="header-anchor" href="#模式结构">¶</a>模式结构</h3><p>以Netty为例列举下它所包含的结构。</p><table><thead><tr><th>观察者模式角色</th><th>Netty中的对应实现</th></tr></thead><tbody><tr><td><code>Subject</code></td><td><code>ChannelFuture/Future</code></td></tr><tr><td><code>Observer</code></td><td><code>GenericFutureListener/ChannelFutureListener</code></td></tr><tr><td>注册观察者方法</td><td><code>addListener()</code></td></tr><tr><td>通知观察者方法</td><td>内部调用<code>listener.operationComplete(future)</code></td></tr></tbody></table><p>简要代码示例，</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 观察者接口</span></span><br><span class="line"><span class="keyword">interface</span> <span class="title class_">Observer</span> &#123;</span><br><span class="line">    <span class="keyword">void</span> <span class="title function_">update</span><span class="params">(String message)</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 被观察者</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Subject</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> List&lt;Observer&gt; observers = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">addObserver</span><span class="params">(Observer observer)</span> &#123;</span><br><span class="line">        observers.add(observer);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">notifyAllObservers</span><span class="params">(String message)</span> &#123;</span><br><span class="line">        <span class="keyword">for</span> (Observer observer : observers) &#123;</span><br><span class="line">            observer.update(message);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">changeState</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="comment">// 模拟状态变化</span></span><br><span class="line">        notifyAllObservers(<span class="string">&quot;StateChanged&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;定义了对象之间的一对多的依赖，这样一来，当一个对象改变时，它的所有的依赖者都会收到通知并自动更新。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;img src=&quot;/assert/puml/04f6002ad969a8a50b07a74005a40a498656cfe9ae7e2ff05ac780d2e1d911e1.svg&quot;/&gt;</summary>
    
    
    <content src="https://galudisu.info/%3Cblockquote%3E%3Cp%3E%E5%AE%9A%E4%B9%89%E4%BA%86%E5%AF%B9%E8%B1%A1%E4%B9%8B%E9%97%B4%E7%9A%84%E4%B8%80%E5%AF%B9%E5%A4%9A%E7%9A%84%E4%BE%9D%E8%B5%96%EF%BC%8C%E8%BF%99%E6%A0%B7%E4%B8%80%E6%9D%A5%EF%BC%8C%E5%BD%93%E4%B8%80%E4%B8%AA%E5%AF%B9%E8%B1%A1%E6%94%B9%E5%8F%98%E6%97%B6%EF%BC%8C%E5%AE%83%E7%9A%84%E6%89%80%E6%9C%89%E7%9A%84%E4%BE%9D%E8%B5%96%E8%80%85%E9%83%BD%E4%BC%9A%E6%94%B6%E5%88%B0%E9%80%9A%E7%9F%A5%E5%B9%B6%E8%87%AA%E5%8A%A8%E6%9B%B4%E6%96%B0%E3%80%82%3C/p%3E%3C/blockquote%3E%3Cimg%20src=%22/assert/puml/04f6002ad969a8a50b07a74005a40a498656cfe9ae7e2ff05ac780d2e1d911e1.svg%22/%3E%3Cspan%20id=%22more%22%3E%3C/span%3E%3Ch3%20id=%22%E6%A8%A1%E5%BC%8F%E7%BB%93%E6%9E%84%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E6%A8%A1%E5%BC%8F%E7%BB%93%E6%9E%84%22%3E%C2%B6%3C/a%3E%E6%A8%A1%E5%BC%8F%E7%BB%93%E6%9E%84%3C/h3%3E%3Cp%3E%E4%BB%A5Netty%E4%B8%BA%E4%BE%8B%E5%88%97%E4%B8%BE%E4%B8%8B%E5%AE%83%E6%89%80%E5%8C%85%E5%90%AB%E7%9A%84%E7%BB%93%E6%9E%84%E3%80%82%3C/p%3E%3Ctable%3E%3Cthead%3E%3Ctr%3E%3Cth%3E%E8%A7%82%E5%AF%9F%E8%80%85%E6%A8%A1%E5%BC%8F%E8%A7%92%E8%89%B2%3C/th%3E%3Cth%3ENetty%E4%B8%AD%E7%9A%84%E5%AF%B9%E5%BA%94%E5%AE%9E%E7%8E%B0%3C/th%3E%3C/tr%3E%3C/thead%3E%3Ctbody%3E%3Ctr%3E%3Ctd%3E%3Ccode%3ESubject%3C/code%3E%3C/td%3E%3Ctd%3E%3Ccode%3EChannelFuture/Future%3C/code%3E%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%3E%3Ccode%3EObserver%3C/code%3E%3C/td%3E%3Ctd%3E%3Ccode%3EGenericFutureListener/ChannelFutureListener%3C/code%3E%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%3E%E6%B3%A8%E5%86%8C%E8%A7%82%E5%AF%9F%E8%80%85%E6%96%B9%E6%B3%95%3C/td%3E%3Ctd%3E%3Ccode%3EaddListener()%3C/code%3E%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%3E%E9%80%9A%E7%9F%A5%E8%A7%82%E5%AF%9F%E8%80%85%E6%96%B9%E6%B3%95%3C/td%3E%3Ctd%3E%E5%86%85%E9%83%A8%E8%B0%83%E7%94%A8%3Ccode%3Elistener.operationComplete(future)%3C/code%3E%3C/td%3E%3C/tr%3E%3C/tbody%3E%3C/table%3E%3Cp%3E%E7%AE%80%E8%A6%81%E4%BB%A3%E7%A0%81%E7%A4%BA%E4%BE%8B%EF%BC%8C%3C/p%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E8%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E9%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E10%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E11%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E12%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E13%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E14%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E15%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E16%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E17%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E18%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E19%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E21%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E22%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E23%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E24%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22comment%22%3E/%20%E8%A7%82%E5%AF%9F%E8%80%85%E6%8E%A5%E5%8F%A3%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Einterface%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EObserver%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Eupdate%3C/span%3E%3Cspan%20class=%22params%22%3E(String%20message)%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22comment%22%3E/%20%E8%A2%AB%E8%A7%82%E5%AF%9F%E8%80%85%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3ESubject%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Eprivate%3C/span%3E%20List&amp;lt;Observer&amp;gt;%20observers%20=%20%3Cspan%20class=%22keyword%22%3Enew%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EArrayList%3C/span%3E&amp;lt;&amp;gt;();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EaddObserver%3C/span%3E%3Cspan%20class=%22params%22%3E(Observer%20observer)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20observers.add(observer);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EnotifyAllObservers%3C/span%3E%3Cspan%20class=%22params%22%3E(String%20message)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20%3Cspan%20class=%22keyword%22%3Efor%3C/span%3E%20(Observer%20observer%20:%20observers)%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20%20%20%20%20observer.update(message);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EchangeState%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20%3Cspan%20class=%22comment%22%3E/%20%E6%A8%A1%E6%8B%9F%E7%8A%B6%E6%80%81%E5%8F%98%E5%8C%96%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20notifyAllObservers(%3Cspan%20class=%22string%22%3E&amp;quot;StateChanged&amp;quot;%3C/span%3E);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E" type="image"/>
    
    
    
    <category term="behavioral" scheme="https://galudisu.info/tags/behavioral/"/>
    
    <category term="observer" scheme="https://galudisu.info/tags/observer/"/>
    
  </entry>
  
  <entry>
    <title>迭代器模式(Iterator Pattern)</title>
    <link href="https://galudisu.info/2025/05/10/pattern/basic/behavioral/Iterator/"/>
    <id>https://galudisu.info/2025/05/10/pattern/basic/behavioral/Iterator/</id>
    <published>2025-05-10T12:25:03.000Z</published>
    <updated>2026-04-14T19:59:33.523Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>Java和.Net编程环境中非常常用的设计模式，这种模式用于顺序访问集合对象的元素，不需要知道集合对象的底层表示，迭代器模式属于行为模式。</p></blockquote><img src="/assert/puml/c4baebd2aaff0e02900ccf53f380512097b66054967e13219e3c87667eed86f3.svg"/><span id="more"></span><h3 id="核心角色"><a class="header-anchor" href="#核心角色">¶</a>核心角色</h3><table><thead><tr><th style="text-align:left"><strong>角色</strong></th><th style="text-align:left"><strong>描述</strong></th></tr></thead><tbody><tr><td style="text-align:left"><code>Iterator</code></td><td style="text-align:left">定义遍历集合的接口，如<code>hasNext()、next()</code>等方法。</td></tr><tr><td style="text-align:left"><code>ConcreteIterator</code></td><td style="text-align:left">实现具体的遍历逻辑。</td></tr><tr><td style="text-align:left"><code>Aggregate</code></td><td style="text-align:left">聚合类接口，定义创建迭代器的方法<code>iterator()</code>。</td></tr><tr><td style="text-align:left"><code>ConcreteAggregate</code></td><td style="text-align:left">具体聚合类，返回一个与该聚合结构匹配的迭代器。</td></tr></tbody></table><h3 id="示例代码"><a class="header-anchor" href="#示例代码">¶</a>示例代码</h3><p>该模式常常用于Collection包中，譬如<code>List</code>、<code>Set</code>等实现了<code>Iterator</code>接口对其统一了行为并可以使用for/while增强。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// Iterator 接口</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">Iterator</span>&lt;T&gt; &#123;</span><br><span class="line">    <span class="type">boolean</span> <span class="title function_">hasNext</span><span class="params">()</span>;</span><br><span class="line">    T <span class="title function_">next</span><span class="params">()</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// ConcreteIterator 实现</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">ListIterator</span>&lt;T&gt; <span class="keyword">implements</span> <span class="title class_">Iterator</span>&lt;T&gt; &#123;</span><br><span class="line">    <span class="keyword">private</span> T[] items;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> <span class="variable">position</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">ListIterator</span><span class="params">(T[] items)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.items = items;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">hasNext</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> position &lt; items.length;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> T <span class="title function_">next</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> items[position++];</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// Aggregate 接口</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">Aggregate</span>&lt;T&gt; &#123;</span><br><span class="line">    Iterator&lt;T&gt; <span class="title function_">iterator</span><span class="params">()</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// ConcreteAggregate 实现</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">ListAggregate</span>&lt;T&gt; <span class="keyword">implements</span> <span class="title class_">Aggregate</span>&lt;T&gt; &#123;</span><br><span class="line">    <span class="keyword">private</span> T[] items;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">ListAggregate</span><span class="params">(T[] items)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.items = items;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> Iterator&lt;T&gt; <span class="title function_">iterator</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">ListIterator</span>&lt;&gt;(items);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// Client 使用示例</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Client</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        String[] data = &#123;<span class="string">&quot;A&quot;</span>, <span class="string">&quot;B&quot;</span>, <span class="string">&quot;C&quot;</span>&#125;;</span><br><span class="line">        Aggregate&lt;String&gt; aggregate = <span class="keyword">new</span> <span class="title class_">ListAggregate</span>&lt;&gt;(data);</span><br><span class="line">        Iterator&lt;String&gt; iterator = aggregate.iterator();</span><br><span class="line"></span><br><span class="line">        <span class="keyword">while</span> (iterator.hasNext()) &#123;</span><br><span class="line">            System.out.println(iterator.next());</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><h3 id="特点与应用场景"><a class="header-anchor" href="#特点与应用场景">¶</a>特点与应用场景</h3><ol><li><p>优点</p><ul><li><strong>解耦集合与遍历逻辑</strong>： 客户端不需要关心具体结构即可遍历。</li><li><strong>统一接口访问</strong></li><li><strong>支持多种遍历方式</strong>： 排序、过滤filter、reduce、map、flatmap…</li></ul></li><li><p>缺点</p><ul><li>增加类的数量，系统复杂度有所增加。一般由语言本身迭代维护，譬如JDK 1.5 扩展了Iterator、JDK 8增加了Stream等等。</li></ul></li></ol>]]></content>
    
    
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;Java和.Net编程环境中非常常用的设计模式，这种模式用于顺序访问集合对象的元素，不需要知道集合对象的底层表示，迭代器模式属于行为模式。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;img src=&quot;/assert/puml/c4baebd2aaff0e02900ccf53f380512097b66054967e13219e3c87667eed86f3.svg&quot;/&gt;</summary>
    
    
    <content src="https://galudisu.info/%3Cblockquote%3E%3Cp%3EJava%E5%92%8C.Net%E7%BC%96%E7%A8%8B%E7%8E%AF%E5%A2%83%E4%B8%AD%E9%9D%9E%E5%B8%B8%E5%B8%B8%E7%94%A8%E7%9A%84%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%EF%BC%8C%E8%BF%99%E7%A7%8D%E6%A8%A1%E5%BC%8F%E7%94%A8%E4%BA%8E%E9%A1%BA%E5%BA%8F%E8%AE%BF%E9%97%AE%E9%9B%86%E5%90%88%E5%AF%B9%E8%B1%A1%E7%9A%84%E5%85%83%E7%B4%A0%EF%BC%8C%E4%B8%8D%E9%9C%80%E8%A6%81%E7%9F%A5%E9%81%93%E9%9B%86%E5%90%88%E5%AF%B9%E8%B1%A1%E7%9A%84%E5%BA%95%E5%B1%82%E8%A1%A8%E7%A4%BA%EF%BC%8C%E8%BF%AD%E4%BB%A3%E5%99%A8%E6%A8%A1%E5%BC%8F%E5%B1%9E%E4%BA%8E%E8%A1%8C%E4%B8%BA%E6%A8%A1%E5%BC%8F%E3%80%82%3C/p%3E%3C/blockquote%3E%3Cimg%20src=%22/assert/puml/c4baebd2aaff0e02900ccf53f380512097b66054967e13219e3c87667eed86f3.svg%22/%3E%3Cspan%20id=%22more%22%3E%3C/span%3E%3Ch3%20id=%22%E6%A0%B8%E5%BF%83%E8%A7%92%E8%89%B2%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E6%A0%B8%E5%BF%83%E8%A7%92%E8%89%B2%22%3E%C2%B6%3C/a%3E%E6%A0%B8%E5%BF%83%E8%A7%92%E8%89%B2%3C/h3%3E%3Ctable%3E%3Cthead%3E%3Ctr%3E%3Cth%20style=%22text-align:left%22%3E%3Cstrong%3E%E8%A7%92%E8%89%B2%3C/strong%3E%3C/th%3E%3Cth%20style=%22text-align:left%22%3E%3Cstrong%3E%E6%8F%8F%E8%BF%B0%3C/strong%3E%3C/th%3E%3C/tr%3E%3C/thead%3E%3Ctbody%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%3Ccode%3EIterator%3C/code%3E%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E5%AE%9A%E4%B9%89%E9%81%8D%E5%8E%86%E9%9B%86%E5%90%88%E7%9A%84%E6%8E%A5%E5%8F%A3%EF%BC%8C%E5%A6%82%3Ccode%3EhasNext()%E3%80%81next()%3C/code%3E%E7%AD%89%E6%96%B9%E6%B3%95%E3%80%82%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%3Ccode%3EConcreteIterator%3C/code%3E%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E5%AE%9E%E7%8E%B0%E5%85%B7%E4%BD%93%E7%9A%84%E9%81%8D%E5%8E%86%E9%80%BB%E8%BE%91%E3%80%82%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%3Ccode%3EAggregate%3C/code%3E%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E8%81%9A%E5%90%88%E7%B1%BB%E6%8E%A5%E5%8F%A3%EF%BC%8C%E5%AE%9A%E4%B9%89%E5%88%9B%E5%BB%BA%E8%BF%AD%E4%BB%A3%E5%99%A8%E7%9A%84%E6%96%B9%E6%B3%95%3Ccode%3Eiterator()%3C/code%3E%E3%80%82%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%3Ccode%3EConcreteAggregate%3C/code%3E%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E5%85%B7%E4%BD%93%E8%81%9A%E5%90%88%E7%B1%BB%EF%BC%8C%E8%BF%94%E5%9B%9E%E4%B8%80%E4%B8%AA%E4%B8%8E%E8%AF%A5%E8%81%9A%E5%90%88%E7%BB%93%E6%9E%84%E5%8C%B9%E9%85%8D%E7%9A%84%E8%BF%AD%E4%BB%A3%E5%99%A8%E3%80%82%3C/td%3E%3C/tr%3E%3C/tbody%3E%3C/table%3E%3Ch3%20id=%22%E7%A4%BA%E4%BE%8B%E4%BB%A3%E7%A0%81%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E7%A4%BA%E4%BE%8B%E4%BB%A3%E7%A0%81%22%3E%C2%B6%3C/a%3E%E7%A4%BA%E4%BE%8B%E4%BB%A3%E7%A0%81%3C/h3%3E%3Cp%3E%E8%AF%A5%E6%A8%A1%E5%BC%8F%E5%B8%B8%E5%B8%B8%E7%94%A8%E4%BA%8ECollection%E5%8C%85%E4%B8%AD%EF%BC%8C%E8%AD%AC%E5%A6%82%3Ccode%3EList%3C/code%3E%E3%80%81%3Ccode%3ESet%3C/code%3E%E7%AD%89%E5%AE%9E%E7%8E%B0%E4%BA%86%3Ccode%3EIterator%3C/code%3E%E6%8E%A5%E5%8F%A3%E5%AF%B9%E5%85%B6%E7%BB%9F%E4%B8%80%E4%BA%86%E8%A1%8C%E4%B8%BA%E5%B9%B6%E5%8F%AF%E4%BB%A5%E4%BD%BF%E7%94%A8for/while%E5%A2%9E%E5%BC%BA%E3%80%82%3C/p%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E8%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E9%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E10%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E11%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E12%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E13%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E14%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E15%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E16%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E17%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E18%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E19%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E21%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E22%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E23%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E24%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E25%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E26%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E27%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E28%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E29%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E30%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E31%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E32%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E33%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E34%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E35%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E36%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E37%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E38%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E39%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E40%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E41%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E42%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E43%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E44%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E45%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E46%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E47%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E48%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E49%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E50%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E51%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E52%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E53%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E54%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E55%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E56%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E57%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E58%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22comment%22%3E/%20Iterator%20%E6%8E%A5%E5%8F%A3%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Einterface%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EIterator%3C/span%3E&amp;lt;T&amp;gt;%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22type%22%3Eboolean%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EhasNext%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20T%20%3Cspan%20class=%22title%20function_%22%3Enext%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22comment%22%3E/%20ConcreteIterator%20%E5%AE%9E%E7%8E%B0%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EListIterator%3C/span%3E&amp;lt;T&amp;gt;%20%3Cspan%20class=%22keyword%22%3Eimplements%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EIterator%3C/span%3E&amp;lt;T&amp;gt;%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Eprivate%3C/span%3E%20T[]%20items;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Eprivate%3C/span%3E%20%3Cspan%20class=%22type%22%3Eint%3C/span%3E%20%3Cspan%20class=%22variable%22%3Eposition%3C/span%3E%20%3Cspan%20class=%22operator%22%3E=%3C/span%3E%20%3Cspan%20class=%22number%22%3E0%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EListIterator%3C/span%3E%3Cspan%20class=%22params%22%3E(T[]%20items)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20%3Cspan%20class=%22built_in%22%3Ethis%3C/span%3E.items%20=%20items;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22type%22%3Eboolean%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EhasNext%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20%3Cspan%20class=%22keyword%22%3Ereturn%3C/span%3E%20position%20&amp;lt;%20items.length;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20T%20%3Cspan%20class=%22title%20function_%22%3Enext%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20%3Cspan%20class=%22keyword%22%3Ereturn%3C/span%3E%20items[position++];%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22comment%22%3E/%20Aggregate%20%E6%8E%A5%E5%8F%A3%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Einterface%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EAggregate%3C/span%3E&amp;lt;T&amp;gt;%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20Iterator&amp;lt;T&amp;gt;%20%3Cspan%20class=%22title%20function_%22%3Eiterator%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22comment%22%3E/%20ConcreteAggregate%20%E5%AE%9E%E7%8E%B0%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EListAggregate%3C/span%3E&amp;lt;T&amp;gt;%20%3Cspan%20class=%22keyword%22%3Eimplements%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EAggregate%3C/span%3E&amp;lt;T&amp;gt;%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Eprivate%3C/span%3E%20T[]%20items;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EListAggregate%3C/span%3E%3Cspan%20class=%22params%22%3E(T[]%20items)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20%3Cspan%20class=%22built_in%22%3Ethis%3C/span%3E.items%20=%20items;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20Iterator&amp;lt;T&amp;gt;%20%3Cspan%20class=%22title%20function_%22%3Eiterator%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20%3Cspan%20class=%22keyword%22%3Ereturn%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Enew%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EListIterator%3C/span%3E&amp;lt;&amp;gt;(items);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22comment%22%3E/%20Client%20%E4%BD%BF%E7%94%A8%E7%A4%BA%E4%BE%8B%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EClient%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Estatic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Emain%3C/span%3E%3Cspan%20class=%22params%22%3E(String[]%20args)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20String[]%20data%20=%20&amp;#123;%3Cspan%20class=%22string%22%3E&amp;quot;A&amp;quot;%3C/span%3E,%20%3Cspan%20class=%22string%22%3E&amp;quot;B&amp;quot;%3C/span%3E,%20%3Cspan%20class=%22string%22%3E&amp;quot;C&amp;quot;%3C/span%3E&amp;#125;;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20Aggregate&amp;lt;String&amp;gt;%20aggregate%20=%20%3Cspan%20class=%22keyword%22%3Enew%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EListAggregate%3C/span%3E&amp;lt;&amp;gt;(data);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20Iterator&amp;lt;String&amp;gt;%20iterator%20=%20aggregate.iterator();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20%3Cspan%20class=%22keyword%22%3Ewhile%3C/span%3E%20(iterator.hasNext())%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20%20%20%20%20System.out.println(iterator.next());%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Ch3%20id=%22%E7%89%B9%E7%82%B9%E4%B8%8E%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E7%89%B9%E7%82%B9%E4%B8%8E%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF%22%3E%C2%B6%3C/a%3E%E7%89%B9%E7%82%B9%E4%B8%8E%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF%3C/h3%3E%3Col%3E%3Cli%3E%3Cp%3E%E4%BC%98%E7%82%B9%3C/p%3E%3Cul%3E%3Cli%3E%3Cstrong%3E%E8%A7%A3%E8%80%A6%E9%9B%86%E5%90%88%E4%B8%8E%E9%81%8D%E5%8E%86%E9%80%BB%E8%BE%91%3C/strong%3E%EF%BC%9A%20%E5%AE%A2%E6%88%B7%E7%AB%AF%E4%B8%8D%E9%9C%80%E8%A6%81%E5%85%B3%E5%BF%83%E5%85%B7%E4%BD%93%E7%BB%93%E6%9E%84%E5%8D%B3%E5%8F%AF%E9%81%8D%E5%8E%86%E3%80%82%3C/li%3E%3Cli%3E%3Cstrong%3E%E7%BB%9F%E4%B8%80%E6%8E%A5%E5%8F%A3%E8%AE%BF%E9%97%AE%3C/strong%3E%3C/li%3E%3Cli%3E%3Cstrong%3E%E6%94%AF%E6%8C%81%E5%A4%9A%E7%A7%8D%E9%81%8D%E5%8E%86%E6%96%B9%E5%BC%8F%3C/strong%3E%EF%BC%9A%20%E6%8E%92%E5%BA%8F%E3%80%81%E8%BF%87%E6%BB%A4filter%E3%80%81reduce%E3%80%81map%E3%80%81flatmap%E2%80%A6%3C/li%3E%3C/ul%3E%3C/li%3E%3Cli%3E%3Cp%3E%E7%BC%BA%E7%82%B9%3C/p%3E%3Cul%3E%3Cli%3E%E5%A2%9E%E5%8A%A0%E7%B1%BB%E7%9A%84%E6%95%B0%E9%87%8F%EF%BC%8C%E7%B3%BB%E7%BB%9F%E5%A4%8D%E6%9D%82%E5%BA%A6%E6%9C%89%E6%89%80%E5%A2%9E%E5%8A%A0%E3%80%82%E4%B8%80%E8%88%AC%E7%94%B1%E8%AF%AD%E8%A8%80%E6%9C%AC%E8%BA%AB%E8%BF%AD%E4%BB%A3%E7%BB%B4%E6%8A%A4%EF%BC%8C%E8%AD%AC%E5%A6%82JDK%201.5%20%E6%89%A9%E5%B1%95%E4%BA%86Iterator%E3%80%81JDK%208%E5%A2%9E%E5%8A%A0%E4%BA%86Stream%E7%AD%89%E7%AD%89%E3%80%82%3C/li%3E%3C/ul%3E%3C/li%3E%3C/ol%3E" type="image"/>
    
    
    
    <category term="behavioral" scheme="https://galudisu.info/tags/behavioral/"/>
    
    <category term="iterator" scheme="https://galudisu.info/tags/iterator/"/>
    
  </entry>
  
  <entry>
    <title>命令模式(Command Pattern)</title>
    <link href="https://galudisu.info/2025/05/10/pattern/basic/behavioral/Command/"/>
    <id>https://galudisu.info/2025/05/10/pattern/basic/behavioral/Command/</id>
    <published>2025-05-10T12:25:01.000Z</published>
    <updated>2026-04-14T19:59:33.593Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>将“请求”封装成对象，以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持可撤离的操作。</p></blockquote><img src="/assert/puml/c87c56e507967d0b45feb709717ec9c5b3444f482eff206dcbfd4c6b9f5bf065.svg"/><span id="more"></span><h3 id="行为结构"><a class="header-anchor" href="#行为结构">¶</a>行为结构</h3><p>命令模式主要角色：</p><ol><li><code>Command(命令接口)</code>： 定义执行操作的接口，通常包含一个<code>execute()</code>方法。</li><li><code>ConcreteCommand(具体命令类)</code>： 实现<code>Command</code>接口，绑定具体的接受者对象(Receiver)，并在<code>execute()</code>方法中调用接受者的相应方法。</li><li><code>Invoker(调用者)</code>：负责调用命令对象来执行请求。</li><li><code>Receiver(接收者)</code>：实际执行命令的对象，包含业务逻辑的具体实现。</li><li><code>Client(客户端)</code>：创建具体的命令对象，并设置其接收者。</li></ol><p>示例代码如下：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// Command 接口</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">Command</span> &#123;</span><br><span class="line">  <span class="keyword">void</span> <span class="title function_">execute</span><span class="params">()</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// Reciver 类</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Light</span> &#123;</span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">on</span><span class="params">()</span>;</span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">off</span><span class="params">()</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// ConcreteCommand 实现</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">LightOnCommand</span> <span class="keyword">implements</span> <span class="title class_">Command</span> &#123;</span><br><span class="line">  <span class="keyword">private</span> Light light;</span><br><span class="line">  <span class="keyword">public</span> <span class="title function_">LightOnCommand</span><span class="params">(Light light)</span> &#123;</span><br><span class="line">    <span class="built_in">this</span>.light = light;</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">execute</span><span class="params">()</span> &#123;</span><br><span class="line">    light.on();</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// Invoker 类</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">RemoteControl</span> &#123;</span><br><span class="line">  <span class="keyword">private</span> Command command;</span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setCommand</span><span class="params">(Command command)</span> &#123;</span><br><span class="line">    <span class="built_in">this</span>.command = command;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">pressButton</span><span class="params">()</span> &#123;</span><br><span class="line">    command.execute();</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// Client 使用</span></span><br><span class="line"><span class="type">Light</span> <span class="variable">light</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Light</span>();  <span class="comment">// Receiver</span></span><br><span class="line"><span class="type">Command</span> <span class="variable">command</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">LightOnCommand</span>(light);  <span class="comment">// ConcreteCommand</span></span><br><span class="line"></span><br><span class="line"><span class="type">RemoteControl</span> <span class="variable">remoteControl</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">RemoteControl</span>(); <span class="comment">// Invoke</span></span><br><span class="line">remoteControl.setCommand(command);</span><br><span class="line">remoteControl.pressButton();  <span class="comment">// 执行命令</span></span><br></pre></td></tr></table></figure><h3 id="特点与应用场景"><a class="header-anchor" href="#特点与应用场景">¶</a>特点与应用场景</h3><ul><li><strong>解耦请求发送者和接收者</strong>： 通过命令对象，请求发送者无需指导接收者及其具体操作，只需触发命令即可。</li><li><strong>支持撤销/重做</strong>： 可以通过记录命令历史实现撤销或重做功能。</li><li><strong>支持队列和日志</strong>： 可以将命令对象存储在队列中，按需执行；也可以记录日志以恢复状态。</li><li><strong>适合场景</strong>： GUI操作、事务回滚、人物队列等需要解耦和扩展性的场景。</li></ul><ol><li><p>优点</p><ul><li>提高了系统的灵活性和可扩展性。</li><li>支持多种高级功能(如撤销、日志记录)。</li></ul></li><li><p>缺点</p><ul><li>可能增加系统的复杂度，因为需要为每个操作定义独立的命令类。</li></ul></li></ol><h3 id="CQRS中Command的区别"><a class="header-anchor" href="#CQRS中Command的区别">¶</a>CQRS中Command的区别</h3><table><thead><tr><th style="text-align:left">对比点</th><th style="text-align:left">命令模式中的<code>Command</code></th><th style="text-align:left">CQRS中的<code>Command</code></th></tr></thead><tbody><tr><td style="text-align:left">目的</td><td style="text-align:left">封装一个操作及其参数，实现请求的排队、撤销等</td><td style="text-align:left">表示对系统状态进行更改的操作，用于写模型处理</td></tr><tr><td style="text-align:left">所属架构</td><td style="text-align:left">行为型设计模式</td><td style="text-align:left">架构风格的一部分，常配合事件溯源(Event Sourcing)使用；</td></tr><tr><td style="text-align:left">职责</td><td style="text-align:left">调用Receiver的方法执行具体逻辑</td><td style="text-align:left">发送到CommandHandler，触发聚合根修改并产生领域事件</td></tr></tbody></table>]]></content>
    
    
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;将“请求”封装成对象，以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持可撤离的操作。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;img src=&quot;/assert/puml/c87c56e507967d0b45feb709717ec9c5b3444f482eff206dcbfd4c6b9f5bf065.svg&quot;/&gt;</summary>
    
    
    <content src="https://galudisu.info/%3Cblockquote%3E%3Cp%3E%E5%B0%86%E2%80%9C%E8%AF%B7%E6%B1%82%E2%80%9D%E5%B0%81%E8%A3%85%E6%88%90%E5%AF%B9%E8%B1%A1%EF%BC%8C%E4%BB%A5%E4%BE%BF%E4%BD%BF%E7%94%A8%E4%B8%8D%E5%90%8C%E7%9A%84%E8%AF%B7%E6%B1%82%E3%80%81%E9%98%9F%E5%88%97%E6%88%96%E8%80%85%E6%97%A5%E5%BF%97%E6%9D%A5%E5%8F%82%E6%95%B0%E5%8C%96%E5%85%B6%E4%BB%96%E5%AF%B9%E8%B1%A1%E3%80%82%E5%91%BD%E4%BB%A4%E6%A8%A1%E5%BC%8F%E4%B9%9F%E6%94%AF%E6%8C%81%E5%8F%AF%E6%92%A4%E7%A6%BB%E7%9A%84%E6%93%8D%E4%BD%9C%E3%80%82%3C/p%3E%3C/blockquote%3E%3Cimg%20src=%22/assert/puml/c87c56e507967d0b45feb709717ec9c5b3444f482eff206dcbfd4c6b9f5bf065.svg%22/%3E%3Cspan%20id=%22more%22%3E%3C/span%3E%3Ch3%20id=%22%E8%A1%8C%E4%B8%BA%E7%BB%93%E6%9E%84%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E8%A1%8C%E4%B8%BA%E7%BB%93%E6%9E%84%22%3E%C2%B6%3C/a%3E%E8%A1%8C%E4%B8%BA%E7%BB%93%E6%9E%84%3C/h3%3E%3Cp%3E%E5%91%BD%E4%BB%A4%E6%A8%A1%E5%BC%8F%E4%B8%BB%E8%A6%81%E8%A7%92%E8%89%B2%EF%BC%9A%3C/p%3E%3Col%3E%3Cli%3E%3Ccode%3ECommand(%E5%91%BD%E4%BB%A4%E6%8E%A5%E5%8F%A3)%3C/code%3E%EF%BC%9A%20%E5%AE%9A%E4%B9%89%E6%89%A7%E8%A1%8C%E6%93%8D%E4%BD%9C%E7%9A%84%E6%8E%A5%E5%8F%A3%EF%BC%8C%E9%80%9A%E5%B8%B8%E5%8C%85%E5%90%AB%E4%B8%80%E4%B8%AA%3Ccode%3Eexecute()%3C/code%3E%E6%96%B9%E6%B3%95%E3%80%82%3C/li%3E%3Cli%3E%3Ccode%3EConcreteCommand(%E5%85%B7%E4%BD%93%E5%91%BD%E4%BB%A4%E7%B1%BB)%3C/code%3E%EF%BC%9A%20%E5%AE%9E%E7%8E%B0%3Ccode%3ECommand%3C/code%3E%E6%8E%A5%E5%8F%A3%EF%BC%8C%E7%BB%91%E5%AE%9A%E5%85%B7%E4%BD%93%E7%9A%84%E6%8E%A5%E5%8F%97%E8%80%85%E5%AF%B9%E8%B1%A1(Receiver)%EF%BC%8C%E5%B9%B6%E5%9C%A8%3Ccode%3Eexecute()%3C/code%3E%E6%96%B9%E6%B3%95%E4%B8%AD%E8%B0%83%E7%94%A8%E6%8E%A5%E5%8F%97%E8%80%85%E7%9A%84%E7%9B%B8%E5%BA%94%E6%96%B9%E6%B3%95%E3%80%82%3C/li%3E%3Cli%3E%3Ccode%3EInvoker(%E8%B0%83%E7%94%A8%E8%80%85)%3C/code%3E%EF%BC%9A%E8%B4%9F%E8%B4%A3%E8%B0%83%E7%94%A8%E5%91%BD%E4%BB%A4%E5%AF%B9%E8%B1%A1%E6%9D%A5%E6%89%A7%E8%A1%8C%E8%AF%B7%E6%B1%82%E3%80%82%3C/li%3E%3Cli%3E%3Ccode%3EReceiver(%E6%8E%A5%E6%94%B6%E8%80%85)%3C/code%3E%EF%BC%9A%E5%AE%9E%E9%99%85%E6%89%A7%E8%A1%8C%E5%91%BD%E4%BB%A4%E7%9A%84%E5%AF%B9%E8%B1%A1%EF%BC%8C%E5%8C%85%E5%90%AB%E4%B8%9A%E5%8A%A1%E9%80%BB%E8%BE%91%E7%9A%84%E5%85%B7%E4%BD%93%E5%AE%9E%E7%8E%B0%E3%80%82%3C/li%3E%3Cli%3E%3Ccode%3EClient(%E5%AE%A2%E6%88%B7%E7%AB%AF)%3C/code%3E%EF%BC%9A%E5%88%9B%E5%BB%BA%E5%85%B7%E4%BD%93%E7%9A%84%E5%91%BD%E4%BB%A4%E5%AF%B9%E8%B1%A1%EF%BC%8C%E5%B9%B6%E8%AE%BE%E7%BD%AE%E5%85%B6%E6%8E%A5%E6%94%B6%E8%80%85%E3%80%82%3C/li%3E%3C/ol%3E%3Cp%3E%E7%A4%BA%E4%BE%8B%E4%BB%A3%E7%A0%81%E5%A6%82%E4%B8%8B%EF%BC%9A%3C/p%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E8%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E9%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E10%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E11%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E12%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E13%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E14%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E15%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E16%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E17%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E18%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E19%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E21%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E22%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E23%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E24%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E25%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E26%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E27%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E28%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E29%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E30%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E31%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E32%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E33%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E34%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E35%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E36%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E37%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E38%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22comment%22%3E/%20Command%20%E6%8E%A5%E5%8F%A3%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Einterface%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3ECommand%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Eexecute%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22comment%22%3E/%20Reciver%20%E7%B1%BB%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3ELight%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Eon%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Eoff%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22comment%22%3E/%20ConcreteCommand%20%E5%AE%9E%E7%8E%B0%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3ELightOnCommand%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eimplements%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3ECommand%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Eprivate%3C/span%3E%20Light%20light;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3ELightOnCommand%3C/span%3E%3Cspan%20class=%22params%22%3E(Light%20light)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22built_in%22%3Ethis%3C/span%3E.light%20=%20light;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Eexecute%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20light.on();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22comment%22%3E/%20Invoker%20%E7%B1%BB%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3ERemoteControl%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Eprivate%3C/span%3E%20Command%20command;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EsetCommand%3C/span%3E%3Cspan%20class=%22params%22%3E(Command%20command)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22built_in%22%3Ethis%3C/span%3E.command%20=%20command;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EpressButton%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20command.execute();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22comment%22%3E/%20Client%20%E4%BD%BF%E7%94%A8%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22type%22%3ELight%3C/span%3E%20%3Cspan%20class=%22variable%22%3Elight%3C/span%3E%20%3Cspan%20class=%22operator%22%3E=%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Enew%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3ELight%3C/span%3E();%20%20%3Cspan%20class=%22comment%22%3E/%20Receiver%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22type%22%3ECommand%3C/span%3E%20%3Cspan%20class=%22variable%22%3Ecommand%3C/span%3E%20%3Cspan%20class=%22operator%22%3E=%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Enew%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3ELightOnCommand%3C/span%3E(light);%20%20%3Cspan%20class=%22comment%22%3E/%20ConcreteCommand%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22type%22%3ERemoteControl%3C/span%3E%20%3Cspan%20class=%22variable%22%3EremoteControl%3C/span%3E%20%3Cspan%20class=%22operator%22%3E=%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Enew%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3ERemoteControl%3C/span%3E();%20%3Cspan%20class=%22comment%22%3E/%20Invoke%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3EremoteControl.setCommand(command);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3EremoteControl.pressButton();%20%20%3Cspan%20class=%22comment%22%3E/%20%E6%89%A7%E8%A1%8C%E5%91%BD%E4%BB%A4%3C/span%3E%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Ch3%20id=%22%E7%89%B9%E7%82%B9%E4%B8%8E%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E7%89%B9%E7%82%B9%E4%B8%8E%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF%22%3E%C2%B6%3C/a%3E%E7%89%B9%E7%82%B9%E4%B8%8E%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF%3C/h3%3E%3Cul%3E%3Cli%3E%3Cstrong%3E%E8%A7%A3%E8%80%A6%E8%AF%B7%E6%B1%82%E5%8F%91%E9%80%81%E8%80%85%E5%92%8C%E6%8E%A5%E6%94%B6%E8%80%85%3C/strong%3E%EF%BC%9A%20%E9%80%9A%E8%BF%87%E5%91%BD%E4%BB%A4%E5%AF%B9%E8%B1%A1%EF%BC%8C%E8%AF%B7%E6%B1%82%E5%8F%91%E9%80%81%E8%80%85%E6%97%A0%E9%9C%80%E6%8C%87%E5%AF%BC%E6%8E%A5%E6%94%B6%E8%80%85%E5%8F%8A%E5%85%B6%E5%85%B7%E4%BD%93%E6%93%8D%E4%BD%9C%EF%BC%8C%E5%8F%AA%E9%9C%80%E8%A7%A6%E5%8F%91%E5%91%BD%E4%BB%A4%E5%8D%B3%E5%8F%AF%E3%80%82%3C/li%3E%3Cli%3E%3Cstrong%3E%E6%94%AF%E6%8C%81%E6%92%A4%E9%94%80/%E9%87%8D%E5%81%9A%3C/strong%3E%EF%BC%9A%20%E5%8F%AF%E4%BB%A5%E9%80%9A%E8%BF%87%E8%AE%B0%E5%BD%95%E5%91%BD%E4%BB%A4%E5%8E%86%E5%8F%B2%E5%AE%9E%E7%8E%B0%E6%92%A4%E9%94%80%E6%88%96%E9%87%8D%E5%81%9A%E5%8A%9F%E8%83%BD%E3%80%82%3C/li%3E%3Cli%3E%3Cstrong%3E%E6%94%AF%E6%8C%81%E9%98%9F%E5%88%97%E5%92%8C%E6%97%A5%E5%BF%97%3C/strong%3E%EF%BC%9A%20%E5%8F%AF%E4%BB%A5%E5%B0%86%E5%91%BD%E4%BB%A4%E5%AF%B9%E8%B1%A1%E5%AD%98%E5%82%A8%E5%9C%A8%E9%98%9F%E5%88%97%E4%B8%AD%EF%BC%8C%E6%8C%89%E9%9C%80%E6%89%A7%E8%A1%8C%EF%BC%9B%E4%B9%9F%E5%8F%AF%E4%BB%A5%E8%AE%B0%E5%BD%95%E6%97%A5%E5%BF%97%E4%BB%A5%E6%81%A2%E5%A4%8D%E7%8A%B6%E6%80%81%E3%80%82%3C/li%3E%3Cli%3E%3Cstrong%3E%E9%80%82%E5%90%88%E5%9C%BA%E6%99%AF%3C/strong%3E%EF%BC%9A%20GUI%E6%93%8D%E4%BD%9C%E3%80%81%E4%BA%8B%E5%8A%A1%E5%9B%9E%E6%BB%9A%E3%80%81%E4%BA%BA%E7%89%A9%E9%98%9F%E5%88%97%E7%AD%89%E9%9C%80%E8%A6%81%E8%A7%A3%E8%80%A6%E5%92%8C%E6%89%A9%E5%B1%95%E6%80%A7%E7%9A%84%E5%9C%BA%E6%99%AF%E3%80%82%3C/li%3E%3C/ul%3E%3Col%3E%3Cli%3E%3Cp%3E%E4%BC%98%E7%82%B9%3C/p%3E%3Cul%3E%3Cli%3E%E6%8F%90%E9%AB%98%E4%BA%86%E7%B3%BB%E7%BB%9F%E7%9A%84%E7%81%B5%E6%B4%BB%E6%80%A7%E5%92%8C%E5%8F%AF%E6%89%A9%E5%B1%95%E6%80%A7%E3%80%82%3C/li%3E%3Cli%3E%E6%94%AF%E6%8C%81%E5%A4%9A%E7%A7%8D%E9%AB%98%E7%BA%A7%E5%8A%9F%E8%83%BD(%E5%A6%82%E6%92%A4%E9%94%80%E3%80%81%E6%97%A5%E5%BF%97%E8%AE%B0%E5%BD%95)%E3%80%82%3C/li%3E%3C/ul%3E%3C/li%3E%3Cli%3E%3Cp%3E%E7%BC%BA%E7%82%B9%3C/p%3E%3Cul%3E%3Cli%3E%E5%8F%AF%E8%83%BD%E5%A2%9E%E5%8A%A0%E7%B3%BB%E7%BB%9F%E7%9A%84%E5%A4%8D%E6%9D%82%E5%BA%A6%EF%BC%8C%E5%9B%A0%E4%B8%BA%E9%9C%80%E8%A6%81%E4%B8%BA%E6%AF%8F%E4%B8%AA%E6%93%8D%E4%BD%9C%E5%AE%9A%E4%B9%89%E7%8B%AC%E7%AB%8B%E7%9A%84%E5%91%BD%E4%BB%A4%E7%B1%BB%E3%80%82%3C/li%3E%3C/ul%3E%3C/li%3E%3C/ol%3E%3Ch3%20id=%22CQRS%E4%B8%ADCommand%E7%9A%84%E5%8C%BA%E5%88%AB%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#CQRS%E4%B8%ADCommand%E7%9A%84%E5%8C%BA%E5%88%AB%22%3E%C2%B6%3C/a%3ECQRS%E4%B8%ADCommand%E7%9A%84%E5%8C%BA%E5%88%AB%3C/h3%3E%3Ctable%3E%3Cthead%3E%3Ctr%3E%3Cth%20style=%22text-align:left%22%3E%E5%AF%B9%E6%AF%94%E7%82%B9%3C/th%3E%3Cth%20style=%22text-align:left%22%3E%E5%91%BD%E4%BB%A4%E6%A8%A1%E5%BC%8F%E4%B8%AD%E7%9A%84%3Ccode%3ECommand%3C/code%3E%3C/th%3E%3Cth%20style=%22text-align:left%22%3ECQRS%E4%B8%AD%E7%9A%84%3Ccode%3ECommand%3C/code%3E%3C/th%3E%3C/tr%3E%3C/thead%3E%3Ctbody%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%E7%9B%AE%E7%9A%84%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E5%B0%81%E8%A3%85%E4%B8%80%E4%B8%AA%E6%93%8D%E4%BD%9C%E5%8F%8A%E5%85%B6%E5%8F%82%E6%95%B0%EF%BC%8C%E5%AE%9E%E7%8E%B0%E8%AF%B7%E6%B1%82%E7%9A%84%E6%8E%92%E9%98%9F%E3%80%81%E6%92%A4%E9%94%80%E7%AD%89%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E8%A1%A8%E7%A4%BA%E5%AF%B9%E7%B3%BB%E7%BB%9F%E7%8A%B6%E6%80%81%E8%BF%9B%E8%A1%8C%E6%9B%B4%E6%94%B9%E7%9A%84%E6%93%8D%E4%BD%9C%EF%BC%8C%E7%94%A8%E4%BA%8E%E5%86%99%E6%A8%A1%E5%9E%8B%E5%A4%84%E7%90%86%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%E6%89%80%E5%B1%9E%E6%9E%B6%E6%9E%84%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E8%A1%8C%E4%B8%BA%E5%9E%8B%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E6%9E%B6%E6%9E%84%E9%A3%8E%E6%A0%BC%E7%9A%84%E4%B8%80%E9%83%A8%E5%88%86%EF%BC%8C%E5%B8%B8%E9%85%8D%E5%90%88%E4%BA%8B%E4%BB%B6%E6%BA%AF%E6%BA%90(Event%20Sourcing)%E4%BD%BF%E7%94%A8%EF%BC%9B%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%E8%81%8C%E8%B4%A3%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E8%B0%83%E7%94%A8Receiver%E7%9A%84%E6%96%B9%E6%B3%95%E6%89%A7%E8%A1%8C%E5%85%B7%E4%BD%93%E9%80%BB%E8%BE%91%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E5%8F%91%E9%80%81%E5%88%B0CommandHandler%EF%BC%8C%E8%A7%A6%E5%8F%91%E8%81%9A%E5%90%88%E6%A0%B9%E4%BF%AE%E6%94%B9%E5%B9%B6%E4%BA%A7%E7%94%9F%E9%A2%86%E5%9F%9F%E4%BA%8B%E4%BB%B6%3C/td%3E%3C/tr%3E%3C/tbody%3E%3C/table%3E" type="image"/>
    
    
    
    <category term="behavioral" scheme="https://galudisu.info/tags/behavioral/"/>
    
    <category term="command" scheme="https://galudisu.info/tags/command/"/>
    
  </entry>
  
  <entry>
    <title>模板方法模式(Template Method Pattern)</title>
    <link href="https://galudisu.info/2025/05/10/pattern/basic/behavioral/TemplateMethod/"/>
    <id>https://galudisu.info/2025/05/10/pattern/basic/behavioral/TemplateMethod/</id>
    <published>2025-05-10T12:25:00.000Z</published>
    <updated>2026-04-14T19:59:33.793Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>定义了一个算法的骨架，而将一些步骤延迟到子类中，模板方法使得子类可以在不改变算法结构的情况下，重新定义算法的步骤。</p></blockquote><img src="/assert/puml/389dc346451dc22b636547e791eb6837fb6110e85fcc1a75f890ee15318a9f73.svg"/><span id="more"></span><h3 id="行为结构"><a class="header-anchor" href="#行为结构">¶</a>行为结构</h3><p>先做什么，再做什么，先定义出来。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="keyword">class</span> <span class="title class_">AbstractClass</span> &#123;</span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">final</span> <span class="keyword">void</span> <span class="title function_">templateMethod</span><span class="params">()</span> &#123;  <span class="comment">// <i class="conum" data-value="1"></i></span></span><br><span class="line">    operation1();</span><br><span class="line">    operation2();</span><br><span class="line">    <span class="keyword">if</span> (hook()) &#123;   <span class="comment">// <i class="conum" data-value="2"></i></span></span><br><span class="line">      operation3();</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">protected</span> <span class="keyword">abstract</span> <span class="keyword">void</span> <span class="title function_">operation1</span><span class="params">()</span>; <span class="comment">// <i class="conum" data-value="3"></i></span></span><br><span class="line">  <span class="keyword">protected</span> <span class="keyword">abstract</span> <span class="keyword">void</span> <span class="title function_">operation2</span><span class="params">()</span>:</span><br><span class="line">  <span class="keyword">protected</span> <span class="keyword">abstract</span> <span class="keyword">void</span> <span class="title function_">operation3</span><span class="params">()</span>:</span><br><span class="line">  </span><br><span class="line">  <span class="keyword">protected</span> <span class="type">boolean</span> <span class="title function_">hook</span><span class="params">()</span> &#123;    <span class="comment">// <i class="conum" data-value="4"></i></span></span><br><span class="line">    <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><p><i class="conum" data-value="1"></i> 模板方法，定义算法的框架。<br><i class="conum" data-value="2"></i> 钩子方法，这些方法在子类中可以选择性地实现。<br><i class="conum" data-value="3"></i> 抽象方法，需要子类实现。<br><i class="conum" data-value="4"></i> 钩子方法，默认实现。</p><h3 id="总结"><a class="header-anchor" href="#总结">¶</a>总结</h3><ul><li>提高了代码的复用性。</li><li>符合开闭原则(OCP)，扩展性强。</li><li>将算法的核心结构与具体实现分离。</li></ul><blockquote><p>说白了模板方法就是面向对象的抽象类实现。</p></blockquote>]]></content>
    
    
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;定义了一个算法的骨架，而将一些步骤延迟到子类中，模板方法使得子类可以在不改变算法结构的情况下，重新定义算法的步骤。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;img src=&quot;/assert/puml/389dc346451dc22b636547e791eb6837fb6110e85fcc1a75f890ee15318a9f73.svg&quot;/&gt;</summary>
    
    
    <content src="https://galudisu.info/%3Cblockquote%3E%3Cp%3E%E5%AE%9A%E4%B9%89%E4%BA%86%E4%B8%80%E4%B8%AA%E7%AE%97%E6%B3%95%E7%9A%84%E9%AA%A8%E6%9E%B6%EF%BC%8C%E8%80%8C%E5%B0%86%E4%B8%80%E4%BA%9B%E6%AD%A5%E9%AA%A4%E5%BB%B6%E8%BF%9F%E5%88%B0%E5%AD%90%E7%B1%BB%E4%B8%AD%EF%BC%8C%E6%A8%A1%E6%9D%BF%E6%96%B9%E6%B3%95%E4%BD%BF%E5%BE%97%E5%AD%90%E7%B1%BB%E5%8F%AF%E4%BB%A5%E5%9C%A8%E4%B8%8D%E6%94%B9%E5%8F%98%E7%AE%97%E6%B3%95%E7%BB%93%E6%9E%84%E7%9A%84%E6%83%85%E5%86%B5%E4%B8%8B%EF%BC%8C%E9%87%8D%E6%96%B0%E5%AE%9A%E4%B9%89%E7%AE%97%E6%B3%95%E7%9A%84%E6%AD%A5%E9%AA%A4%E3%80%82%3C/p%3E%3C/blockquote%3E%3Cimg%20src=%22/assert/puml/389dc346451dc22b636547e791eb6837fb6110e85fcc1a75f890ee15318a9f73.svg%22/%3E%3Cspan%20id=%22more%22%3E%3C/span%3E%3Ch3%20id=%22%E8%A1%8C%E4%B8%BA%E7%BB%93%E6%9E%84%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E8%A1%8C%E4%B8%BA%E7%BB%93%E6%9E%84%22%3E%C2%B6%3C/a%3E%E8%A1%8C%E4%B8%BA%E7%BB%93%E6%9E%84%3C/h3%3E%3Cp%3E%E5%85%88%E5%81%9A%E4%BB%80%E4%B9%88%EF%BC%8C%E5%86%8D%E5%81%9A%E4%BB%80%E4%B9%88%EF%BC%8C%E5%85%88%E5%AE%9A%E4%B9%89%E5%87%BA%E6%9D%A5%E3%80%82%3C/p%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E8%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E9%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E10%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E11%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E12%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E13%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E14%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E15%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E16%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E17%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E18%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eabstract%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EAbstractClass%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Efinal%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EtemplateMethod%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%20%20%3Cspan%20class=%22comment%22%3E/%20%3Ci%20class=%22conum%22%20data-value=%221%22%3E%3C/i%3E%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20operation1();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20operation2();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Eif%3C/span%3E%20(hook())%20&amp;#123;%20%20%20%3Cspan%20class=%22comment%22%3E/%20%3Ci%20class=%22conum%22%20data-value=%222%22%3E%3C/i%3E%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20operation3();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Eprotected%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eabstract%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Eoperation1%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E;%20%3Cspan%20class=%22comment%22%3E/%20%3Ci%20class=%22conum%22%20data-value=%223%22%3E%3C/i%3E%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Eprotected%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eabstract%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Eoperation2%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E:%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Eprotected%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eabstract%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Eoperation3%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E:%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Eprotected%3C/span%3E%20%3Cspan%20class=%22type%22%3Eboolean%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Ehook%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%20%20%20%20%3Cspan%20class=%22comment%22%3E/%20%3Ci%20class=%22conum%22%20data-value=%224%22%3E%3C/i%3E%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Ereturn%3C/span%3E%20%3Cspan%20class=%22literal%22%3Etrue%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Cp%3E%3Ci%20class=%22conum%22%20data-value=%221%22%3E%3C/i%3E%20%E6%A8%A1%E6%9D%BF%E6%96%B9%E6%B3%95%EF%BC%8C%E5%AE%9A%E4%B9%89%E7%AE%97%E6%B3%95%E7%9A%84%E6%A1%86%E6%9E%B6%E3%80%82%3Cbr%3E%3Ci%20class=%22conum%22%20data-value=%222%22%3E%3C/i%3E%20%E9%92%A9%E5%AD%90%E6%96%B9%E6%B3%95%EF%BC%8C%E8%BF%99%E4%BA%9B%E6%96%B9%E6%B3%95%E5%9C%A8%E5%AD%90%E7%B1%BB%E4%B8%AD%E5%8F%AF%E4%BB%A5%E9%80%89%E6%8B%A9%E6%80%A7%E5%9C%B0%E5%AE%9E%E7%8E%B0%E3%80%82%3Cbr%3E%3Ci%20class=%22conum%22%20data-value=%223%22%3E%3C/i%3E%20%E6%8A%BD%E8%B1%A1%E6%96%B9%E6%B3%95%EF%BC%8C%E9%9C%80%E8%A6%81%E5%AD%90%E7%B1%BB%E5%AE%9E%E7%8E%B0%E3%80%82%3Cbr%3E%3Ci%20class=%22conum%22%20data-value=%224%22%3E%3C/i%3E%20%E9%92%A9%E5%AD%90%E6%96%B9%E6%B3%95%EF%BC%8C%E9%BB%98%E8%AE%A4%E5%AE%9E%E7%8E%B0%E3%80%82%3C/p%3E%3Ch3%20id=%22%E6%80%BB%E7%BB%93%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E6%80%BB%E7%BB%93%22%3E%C2%B6%3C/a%3E%E6%80%BB%E7%BB%93%3C/h3%3E%3Cul%3E%3Cli%3E%E6%8F%90%E9%AB%98%E4%BA%86%E4%BB%A3%E7%A0%81%E7%9A%84%E5%A4%8D%E7%94%A8%E6%80%A7%E3%80%82%3C/li%3E%3Cli%3E%E7%AC%A6%E5%90%88%E5%BC%80%E9%97%AD%E5%8E%9F%E5%88%99(OCP)%EF%BC%8C%E6%89%A9%E5%B1%95%E6%80%A7%E5%BC%BA%E3%80%82%3C/li%3E%3Cli%3E%E5%B0%86%E7%AE%97%E6%B3%95%E7%9A%84%E6%A0%B8%E5%BF%83%E7%BB%93%E6%9E%84%E4%B8%8E%E5%85%B7%E4%BD%93%E5%AE%9E%E7%8E%B0%E5%88%86%E7%A6%BB%E3%80%82%3C/li%3E%3C/ul%3E%3Cblockquote%3E%3Cp%3E%E8%AF%B4%E7%99%BD%E4%BA%86%E6%A8%A1%E6%9D%BF%E6%96%B9%E6%B3%95%E5%B0%B1%E6%98%AF%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E7%9A%84%E6%8A%BD%E8%B1%A1%E7%B1%BB%E5%AE%9E%E7%8E%B0%E3%80%82%3C/p%3E%3C/blockquote%3E" type="image"/>
    
    
    
    <category term="behavioral" scheme="https://galudisu.info/tags/behavioral/"/>
    
    <category term="template method" scheme="https://galudisu.info/tags/template-method/"/>
    
  </entry>
  
  <entry>
    <title>代理模式(Proxy Pattern)</title>
    <link href="https://galudisu.info/2025/05/10/pattern/basic/structural/Proxy/"/>
    <id>https://galudisu.info/2025/05/10/pattern/basic/structural/Proxy/</id>
    <published>2025-05-10T10:25:06.000Z</published>
    <updated>2026-04-14T19:59:33.890Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>一个类代表另一个类的功能。在代理模式中，我们创建具有现有对象的对象，以便向外界提供功能接口。可以理解为内存中没有这个对象就创建，有就直接返回这个对象。</p></blockquote><img src="/assert/puml/ad121bfbedb1b584aa4e204d4c03c0baebf11c5faf26fbcaff2fab9db54314ab.svg"/><span id="more"></span><p><strong>代理模式(Proxy Pattern)</strong> 在面向对象系统中，有些对象由于某些原因(比如对象创建开销很大，某些操作需要安全控制)，直接访问会给使用者或系统结构带来很多麻烦，我们可以在访问此对象时加上一个该对象的访问层。</p><blockquote><p>⚠️ <strong>注意</strong><br>代理模式和委派模式比较容易混淆：</p><p>代理模式是结构模式、委托模式是行为模式。</p><ul><li><strong>代理</strong> = 包裹 + 控制： 像快递员，帮你拿包裹，顺便检查一下。</li><li><strong>委托</strong> = 包裹 + 转发： 像邮局柜台，你交给他，他转手就交给快递公司。</li><li></li></ul><p>快递送货上门是代理，他要对包裹负责，并且要确定送给你；你晚上要加班不方便，让家人帮你去取快递是委托，家人拿了就丢那放着，也可能家人都不一定去拿。</p></blockquote><h3 id="功能角度分类"><a class="header-anchor" href="#功能角度分类">¶</a>功能角度分类</h3><table><thead><tr><th style="text-align:left"><strong>类型</strong></th><th style="text-align:left"><strong>场景</strong></th><th style="text-align:left"><strong>示例</strong></th><th style="text-align:left"><strong>特点</strong></th></tr></thead><tbody><tr><td style="text-align:left">远程代理(Remote Proxy)</td><td style="text-align:left">访问不同地址空间的对象、远程服务通信</td><td style="text-align:left">RMI、gRPC、</td><td style="text-align:left"></td></tr><tr><td style="text-align:left">虚拟代理(Virtual Proxy)</td><td style="text-align:left">创建真实对象的成本较高时，延迟加载(Lazy Load)<br/> 只有在真正需要时才创建目标对象</td><td style="text-align:left">图片加载<br/>大文件读取</td><td style="text-align:left">减少资源浪费<br/>提升相应速度</td></tr><tr><td style="text-align:left">保护代理(Protection Proxy)</td><td style="text-align:left">权限控制</td><td style="text-align:left">鉴权</td><td style="text-align:left">增强安全性<br/>细颗粒度控制</td></tr></tbody></table><h3 id="根据实现技术分类-Java常见"><a class="header-anchor" href="#根据实现技术分类-Java常见">¶</a>根据实现技术分类(Java常见)</h3><table><thead><tr><th style="text-align:left"><strong>类型</strong></th><th style="text-align:left"><strong>描述</strong></th></tr></thead><tbody><tr><td style="text-align:left">静态代理(Static Proxy)</td><td style="text-align:left">手动编写代理类，编译时确定</td></tr><tr><td style="text-align:left">动态代理(Dynamic Proxy)</td><td style="text-align:left">运行时生成代理类，使用<code>java.lang.reflect.Proxy</code></td></tr><tr><td style="text-align:left">CGLIB代理</td><td style="text-align:left">基于字节玛增强技术，适用于没有接口的类</td></tr></tbody></table><h3 id="代理实现方法"><a class="header-anchor" href="#代理实现方法">¶</a>代理实现方法</h3><ul><li>静态代理</li></ul><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">interface</span> <span class="title class_">Subject</span> &#123;</span><br><span class="line">  <span class="keyword">void</span> <span class="title function_">request</span><span class="params">()</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">RealSubject</span> <span class="keyword">implements</span> <span class="title class_">Subject</span> &#123;</span><br><span class="line">  <span class="keyword">void</span> <span class="title function_">request</span><span class="params">()</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Proxy</span> <span class="keyword">implements</span> <span class="title class_">Subject</span> &#123;</span><br><span class="line">  <span class="keyword">private</span> Subject realSubject;</span><br><span class="line">  </span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">request</span><span class="params">()</span> &#123;</span><br><span class="line">    realSubject.request();</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><ul><li>动态代理</li></ul><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Proxy</span> <span class="keyword">implements</span> <span class="title class_">InvocationHandler</span> &#123;</span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  pubilc Object <span class="title function_">invoke</span><span class="params">(Method method, Object[] args, Object proxy)</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> method.invoke(target, args);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><ul><li>CBLIB代理(字节增强)</li></ul><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Proxy</span> <span class="keyword">implements</span> <span class="title class_">MethodInterceptor</span> &#123;</span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="keyword">public</span> Object <span class="title function_">intercept</span><span class="params">(Object obj, Method method, MethodProxy proxy)</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> proxy.invokeSuper(obj, args);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="type">Enhancer</span> <span class="variable">enhancer</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Enhancer</span>();</span><br><span class="line">enhancer.setSuperclass(RealSubject.class);</span><br><span class="line">enhancer.setCallback(<span class="keyword">new</span> <span class="title class_">Proxy</span>());</span><br><span class="line"><span class="type">RealSubject</span> <span class="variable">proxy</span> <span class="operator">=</span> enhancer.create();</span><br><span class="line">proxy.request();</span><br></pre></td></tr></table></figure><p><strong>差异对别</strong>：</p><table><thead><tr><th style="text-align:left"><strong>类型</strong></th><th style="text-align:left"><strong>是否需要接口</strong></th><th style="text-align:left"><strong>是否手动写代理类</strong></th><th style="text-align:left"><strong>技术基础</strong></th><th style="text-align:left"><strong>应用场景</strong></th></tr></thead><tbody><tr><td style="text-align:left">静态代理</td><td style="text-align:left">是</td><td style="text-align:left">是</td><td style="text-align:left">接口/抽象类</td><td style="text-align:left">简单封装、学习</td></tr><tr><td style="text-align:left">JDK动态代理</td><td style="text-align:left">是</td><td style="text-align:left">否</td><td style="text-align:left">反射+<code>Proxy</code></td><td style="text-align:left">AOP、Spring(可选)</td></tr><tr><td style="text-align:left">CGLIB代理</td><td style="text-align:left">否</td><td style="text-align:left">否</td><td style="text-align:left">ASM字节玛增强</td><td style="text-align:left">无接口代理、Spring(默认)</td></tr></tbody></table><h2 id="总结"><a class="header-anchor" href="#总结">¶</a>总结</h2><blockquote><p>代理模式从<strong>功能角度</strong>可以分为： 远程代理、虚拟代理、保护代理；从<strong>实现技术角度</strong>可分为： 静态代理、动态代理(JDK)、CGLIB代理。</p></blockquote>]]></content>
    
    
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;一个类代表另一个类的功能。在代理模式中，我们创建具有现有对象的对象，以便向外界提供功能接口。可以理解为内存中没有这个对象就创建，有就直接返回这个对象。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;img src=&quot;/assert/puml/ad121bfbedb1b584aa4e204d4c03c0baebf11c5faf26fbcaff2fab9db54314ab.svg&quot;/&gt;</summary>
    
    
    <content src="https://galudisu.info/%3Cblockquote%3E%3Cp%3E%E4%B8%80%E4%B8%AA%E7%B1%BB%E4%BB%A3%E8%A1%A8%E5%8F%A6%E4%B8%80%E4%B8%AA%E7%B1%BB%E7%9A%84%E5%8A%9F%E8%83%BD%E3%80%82%E5%9C%A8%E4%BB%A3%E7%90%86%E6%A8%A1%E5%BC%8F%E4%B8%AD%EF%BC%8C%E6%88%91%E4%BB%AC%E5%88%9B%E5%BB%BA%E5%85%B7%E6%9C%89%E7%8E%B0%E6%9C%89%E5%AF%B9%E8%B1%A1%E7%9A%84%E5%AF%B9%E8%B1%A1%EF%BC%8C%E4%BB%A5%E4%BE%BF%E5%90%91%E5%A4%96%E7%95%8C%E6%8F%90%E4%BE%9B%E5%8A%9F%E8%83%BD%E6%8E%A5%E5%8F%A3%E3%80%82%E5%8F%AF%E4%BB%A5%E7%90%86%E8%A7%A3%E4%B8%BA%E5%86%85%E5%AD%98%E4%B8%AD%E6%B2%A1%E6%9C%89%E8%BF%99%E4%B8%AA%E5%AF%B9%E8%B1%A1%E5%B0%B1%E5%88%9B%E5%BB%BA%EF%BC%8C%E6%9C%89%E5%B0%B1%E7%9B%B4%E6%8E%A5%E8%BF%94%E5%9B%9E%E8%BF%99%E4%B8%AA%E5%AF%B9%E8%B1%A1%E3%80%82%3C/p%3E%3C/blockquote%3E%3Cimg%20src=%22/assert/puml/ad121bfbedb1b584aa4e204d4c03c0baebf11c5faf26fbcaff2fab9db54314ab.svg%22/%3E%3Cspan%20id=%22more%22%3E%3C/span%3E%3Cp%3E%3Cstrong%3E%E4%BB%A3%E7%90%86%E6%A8%A1%E5%BC%8F(Proxy%20Pattern)%3C/strong%3E%20%E5%9C%A8%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1%E7%B3%BB%E7%BB%9F%E4%B8%AD%EF%BC%8C%E6%9C%89%E4%BA%9B%E5%AF%B9%E8%B1%A1%E7%94%B1%E4%BA%8E%E6%9F%90%E4%BA%9B%E5%8E%9F%E5%9B%A0(%E6%AF%94%E5%A6%82%E5%AF%B9%E8%B1%A1%E5%88%9B%E5%BB%BA%E5%BC%80%E9%94%80%E5%BE%88%E5%A4%A7%EF%BC%8C%E6%9F%90%E4%BA%9B%E6%93%8D%E4%BD%9C%E9%9C%80%E8%A6%81%E5%AE%89%E5%85%A8%E6%8E%A7%E5%88%B6)%EF%BC%8C%E7%9B%B4%E6%8E%A5%E8%AE%BF%E9%97%AE%E4%BC%9A%E7%BB%99%E4%BD%BF%E7%94%A8%E8%80%85%E6%88%96%E7%B3%BB%E7%BB%9F%E7%BB%93%E6%9E%84%E5%B8%A6%E6%9D%A5%E5%BE%88%E5%A4%9A%E9%BA%BB%E7%83%A6%EF%BC%8C%E6%88%91%E4%BB%AC%E5%8F%AF%E4%BB%A5%E5%9C%A8%E8%AE%BF%E9%97%AE%E6%AD%A4%E5%AF%B9%E8%B1%A1%E6%97%B6%E5%8A%A0%E4%B8%8A%E4%B8%80%E4%B8%AA%E8%AF%A5%E5%AF%B9%E8%B1%A1%E7%9A%84%E8%AE%BF%E9%97%AE%E5%B1%82%E3%80%82%3C/p%3E%3Cblockquote%3E%3Cp%3E%E2%9A%A0%EF%B8%8F%20%3Cstrong%3E%E6%B3%A8%E6%84%8F%3C/strong%3E%3Cbr%3E%E4%BB%A3%E7%90%86%E6%A8%A1%E5%BC%8F%E5%92%8C%E5%A7%94%E6%B4%BE%E6%A8%A1%E5%BC%8F%E6%AF%94%E8%BE%83%E5%AE%B9%E6%98%93%E6%B7%B7%E6%B7%86%EF%BC%9A%3C/p%3E%3Cp%3E%E4%BB%A3%E7%90%86%E6%A8%A1%E5%BC%8F%E6%98%AF%E7%BB%93%E6%9E%84%E6%A8%A1%E5%BC%8F%E3%80%81%E5%A7%94%E6%89%98%E6%A8%A1%E5%BC%8F%E6%98%AF%E8%A1%8C%E4%B8%BA%E6%A8%A1%E5%BC%8F%E3%80%82%3C/p%3E%3Cul%3E%3Cli%3E%3Cstrong%3E%E4%BB%A3%E7%90%86%3C/strong%3E%20=%20%E5%8C%85%E8%A3%B9%20+%20%E6%8E%A7%E5%88%B6%EF%BC%9A%20%E5%83%8F%E5%BF%AB%E9%80%92%E5%91%98%EF%BC%8C%E5%B8%AE%E4%BD%A0%E6%8B%BF%E5%8C%85%E8%A3%B9%EF%BC%8C%E9%A1%BA%E4%BE%BF%E6%A3%80%E6%9F%A5%E4%B8%80%E4%B8%8B%E3%80%82%3C/li%3E%3Cli%3E%3Cstrong%3E%E5%A7%94%E6%89%98%3C/strong%3E%20=%20%E5%8C%85%E8%A3%B9%20+%20%E8%BD%AC%E5%8F%91%EF%BC%9A%20%E5%83%8F%E9%82%AE%E5%B1%80%E6%9F%9C%E5%8F%B0%EF%BC%8C%E4%BD%A0%E4%BA%A4%E7%BB%99%E4%BB%96%EF%BC%8C%E4%BB%96%E8%BD%AC%E6%89%8B%E5%B0%B1%E4%BA%A4%E7%BB%99%E5%BF%AB%E9%80%92%E5%85%AC%E5%8F%B8%E3%80%82%3C/li%3E%3Cli%3E%3C/li%3E%3C/ul%3E%3Cp%3E%E5%BF%AB%E9%80%92%E9%80%81%E8%B4%A7%E4%B8%8A%E9%97%A8%E6%98%AF%E4%BB%A3%E7%90%86%EF%BC%8C%E4%BB%96%E8%A6%81%E5%AF%B9%E5%8C%85%E8%A3%B9%E8%B4%9F%E8%B4%A3%EF%BC%8C%E5%B9%B6%E4%B8%94%E8%A6%81%E7%A1%AE%E5%AE%9A%E9%80%81%E7%BB%99%E4%BD%A0%EF%BC%9B%E4%BD%A0%E6%99%9A%E4%B8%8A%E8%A6%81%E5%8A%A0%E7%8F%AD%E4%B8%8D%E6%96%B9%E4%BE%BF%EF%BC%8C%E8%AE%A9%E5%AE%B6%E4%BA%BA%E5%B8%AE%E4%BD%A0%E5%8E%BB%E5%8F%96%E5%BF%AB%E9%80%92%E6%98%AF%E5%A7%94%E6%89%98%EF%BC%8C%E5%AE%B6%E4%BA%BA%E6%8B%BF%E4%BA%86%E5%B0%B1%E4%B8%A2%E9%82%A3%E6%94%BE%E7%9D%80%EF%BC%8C%E4%B9%9F%E5%8F%AF%E8%83%BD%E5%AE%B6%E4%BA%BA%E9%83%BD%E4%B8%8D%E4%B8%80%E5%AE%9A%E5%8E%BB%E6%8B%BF%E3%80%82%3C/p%3E%3C/blockquote%3E%3Ch3%20id=%22%E5%8A%9F%E8%83%BD%E8%A7%92%E5%BA%A6%E5%88%86%E7%B1%BB%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E5%8A%9F%E8%83%BD%E8%A7%92%E5%BA%A6%E5%88%86%E7%B1%BB%22%3E%C2%B6%3C/a%3E%E5%8A%9F%E8%83%BD%E8%A7%92%E5%BA%A6%E5%88%86%E7%B1%BB%3C/h3%3E%3Ctable%3E%3Cthead%3E%3Ctr%3E%3Cth%20style=%22text-align:left%22%3E%3Cstrong%3E%E7%B1%BB%E5%9E%8B%3C/strong%3E%3C/th%3E%3Cth%20style=%22text-align:left%22%3E%3Cstrong%3E%E5%9C%BA%E6%99%AF%3C/strong%3E%3C/th%3E%3Cth%20style=%22text-align:left%22%3E%3Cstrong%3E%E7%A4%BA%E4%BE%8B%3C/strong%3E%3C/th%3E%3Cth%20style=%22text-align:left%22%3E%3Cstrong%3E%E7%89%B9%E7%82%B9%3C/strong%3E%3C/th%3E%3C/tr%3E%3C/thead%3E%3Ctbody%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%E8%BF%9C%E7%A8%8B%E4%BB%A3%E7%90%86(Remote%20Proxy)%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E8%AE%BF%E9%97%AE%E4%B8%8D%E5%90%8C%E5%9C%B0%E5%9D%80%E7%A9%BA%E9%97%B4%E7%9A%84%E5%AF%B9%E8%B1%A1%E3%80%81%E8%BF%9C%E7%A8%8B%E6%9C%8D%E5%8A%A1%E9%80%9A%E4%BF%A1%3C/td%3E%3Ctd%20style=%22text-align:left%22%3ERMI%E3%80%81gRPC%E3%80%81%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%E8%99%9A%E6%8B%9F%E4%BB%A3%E7%90%86(Virtual%20Proxy)%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E5%88%9B%E5%BB%BA%E7%9C%9F%E5%AE%9E%E5%AF%B9%E8%B1%A1%E7%9A%84%E6%88%90%E6%9C%AC%E8%BE%83%E9%AB%98%E6%97%B6%EF%BC%8C%E5%BB%B6%E8%BF%9F%E5%8A%A0%E8%BD%BD(Lazy%20Load)%3Cbr/%3E%20%E5%8F%AA%E6%9C%89%E5%9C%A8%E7%9C%9F%E6%AD%A3%E9%9C%80%E8%A6%81%E6%97%B6%E6%89%8D%E5%88%9B%E5%BB%BA%E7%9B%AE%E6%A0%87%E5%AF%B9%E8%B1%A1%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E5%9B%BE%E7%89%87%E5%8A%A0%E8%BD%BD%3Cbr/%3E%E5%A4%A7%E6%96%87%E4%BB%B6%E8%AF%BB%E5%8F%96%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E5%87%8F%E5%B0%91%E8%B5%84%E6%BA%90%E6%B5%AA%E8%B4%B9%3Cbr/%3E%E6%8F%90%E5%8D%87%E7%9B%B8%E5%BA%94%E9%80%9F%E5%BA%A6%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%E4%BF%9D%E6%8A%A4%E4%BB%A3%E7%90%86(Protection%20Proxy)%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E6%9D%83%E9%99%90%E6%8E%A7%E5%88%B6%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E9%89%B4%E6%9D%83%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E5%A2%9E%E5%BC%BA%E5%AE%89%E5%85%A8%E6%80%A7%3Cbr/%3E%E7%BB%86%E9%A2%97%E7%B2%92%E5%BA%A6%E6%8E%A7%E5%88%B6%3C/td%3E%3C/tr%3E%3C/tbody%3E%3C/table%3E%3Ch3%20id=%22%E6%A0%B9%E6%8D%AE%E5%AE%9E%E7%8E%B0%E6%8A%80%E6%9C%AF%E5%88%86%E7%B1%BB-Java%E5%B8%B8%E8%A7%81%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E6%A0%B9%E6%8D%AE%E5%AE%9E%E7%8E%B0%E6%8A%80%E6%9C%AF%E5%88%86%E7%B1%BB-Java%E5%B8%B8%E8%A7%81%22%3E%C2%B6%3C/a%3E%E6%A0%B9%E6%8D%AE%E5%AE%9E%E7%8E%B0%E6%8A%80%E6%9C%AF%E5%88%86%E7%B1%BB(Java%E5%B8%B8%E8%A7%81)%3C/h3%3E%3Ctable%3E%3Cthead%3E%3Ctr%3E%3Cth%20style=%22text-align:left%22%3E%3Cstrong%3E%E7%B1%BB%E5%9E%8B%3C/strong%3E%3C/th%3E%3Cth%20style=%22text-align:left%22%3E%3Cstrong%3E%E6%8F%8F%E8%BF%B0%3C/strong%3E%3C/th%3E%3C/tr%3E%3C/thead%3E%3Ctbody%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%E9%9D%99%E6%80%81%E4%BB%A3%E7%90%86(Static%20Proxy)%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E6%89%8B%E5%8A%A8%E7%BC%96%E5%86%99%E4%BB%A3%E7%90%86%E7%B1%BB%EF%BC%8C%E7%BC%96%E8%AF%91%E6%97%B6%E7%A1%AE%E5%AE%9A%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86(Dynamic%20Proxy)%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E8%BF%90%E8%A1%8C%E6%97%B6%E7%94%9F%E6%88%90%E4%BB%A3%E7%90%86%E7%B1%BB%EF%BC%8C%E4%BD%BF%E7%94%A8%3Ccode%3Ejava.lang.reflect.Proxy%3C/code%3E%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3ECGLIB%E4%BB%A3%E7%90%86%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E5%9F%BA%E4%BA%8E%E5%AD%97%E8%8A%82%E7%8E%9B%E5%A2%9E%E5%BC%BA%E6%8A%80%E6%9C%AF%EF%BC%8C%E9%80%82%E7%94%A8%E4%BA%8E%E6%B2%A1%E6%9C%89%E6%8E%A5%E5%8F%A3%E7%9A%84%E7%B1%BB%3C/td%3E%3C/tr%3E%3C/tbody%3E%3C/table%3E%3Ch3%20id=%22%E4%BB%A3%E7%90%86%E5%AE%9E%E7%8E%B0%E6%96%B9%E6%B3%95%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E4%BB%A3%E7%90%86%E5%AE%9E%E7%8E%B0%E6%96%B9%E6%B3%95%22%3E%C2%B6%3C/a%3E%E4%BB%A3%E7%90%86%E5%AE%9E%E7%8E%B0%E6%96%B9%E6%B3%95%3C/h3%3E%3Cul%3E%3Cli%3E%E9%9D%99%E6%80%81%E4%BB%A3%E7%90%86%3C/li%3E%3C/ul%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E8%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E9%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E10%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E11%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E12%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E13%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E14%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Einterface%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3ESubject%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Erequest%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3ERealSubject%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eimplements%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3ESubject%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Erequest%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EProxy%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eimplements%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3ESubject%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Eprivate%3C/span%3E%20Subject%20realSubject;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Erequest%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20realSubject.request();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Cul%3E%3Cli%3E%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86%3C/li%3E%3C/ul%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EProxy%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eimplements%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EInvocationHandler%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20pubilc%20Object%20%3Cspan%20class=%22title%20function_%22%3Einvoke%3C/span%3E%3Cspan%20class=%22params%22%3E(Method%20method,%20Object[]%20args,%20Object%20proxy)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Ereturn%3C/span%3E%20method.invoke(target,%20args);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Cul%3E%3Cli%3ECBLIB%E4%BB%A3%E7%90%86(%E5%AD%97%E8%8A%82%E5%A2%9E%E5%BC%BA)%3C/li%3E%3C/ul%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E8%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E9%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E10%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E11%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E12%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EProxy%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eimplements%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EMethodInterceptor%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20Object%20%3Cspan%20class=%22title%20function_%22%3Eintercept%3C/span%3E%3Cspan%20class=%22params%22%3E(Object%20obj,%20Method%20method,%20MethodProxy%20proxy)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Ereturn%3C/span%3E%20proxy.invokeSuper(obj,%20args);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22type%22%3EEnhancer%3C/span%3E%20%3Cspan%20class=%22variable%22%3Eenhancer%3C/span%3E%20%3Cspan%20class=%22operator%22%3E=%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Enew%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EEnhancer%3C/span%3E();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3Eenhancer.setSuperclass(RealSubject.class);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3Eenhancer.setCallback(%3Cspan%20class=%22keyword%22%3Enew%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EProxy%3C/span%3E());%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22type%22%3ERealSubject%3C/span%3E%20%3Cspan%20class=%22variable%22%3Eproxy%3C/span%3E%20%3Cspan%20class=%22operator%22%3E=%3C/span%3E%20enhancer.create();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3Eproxy.request();%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Cp%3E%3Cstrong%3E%E5%B7%AE%E5%BC%82%E5%AF%B9%E5%88%AB%3C/strong%3E%EF%BC%9A%3C/p%3E%3Ctable%3E%3Cthead%3E%3Ctr%3E%3Cth%20style=%22text-align:left%22%3E%3Cstrong%3E%E7%B1%BB%E5%9E%8B%3C/strong%3E%3C/th%3E%3Cth%20style=%22text-align:left%22%3E%3Cstrong%3E%E6%98%AF%E5%90%A6%E9%9C%80%E8%A6%81%E6%8E%A5%E5%8F%A3%3C/strong%3E%3C/th%3E%3Cth%20style=%22text-align:left%22%3E%3Cstrong%3E%E6%98%AF%E5%90%A6%E6%89%8B%E5%8A%A8%E5%86%99%E4%BB%A3%E7%90%86%E7%B1%BB%3C/strong%3E%3C/th%3E%3Cth%20style=%22text-align:left%22%3E%3Cstrong%3E%E6%8A%80%E6%9C%AF%E5%9F%BA%E7%A1%80%3C/strong%3E%3C/th%3E%3Cth%20style=%22text-align:left%22%3E%3Cstrong%3E%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF%3C/strong%3E%3C/th%3E%3C/tr%3E%3C/thead%3E%3Ctbody%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%E9%9D%99%E6%80%81%E4%BB%A3%E7%90%86%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E6%98%AF%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E6%98%AF%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E6%8E%A5%E5%8F%A3/%E6%8A%BD%E8%B1%A1%E7%B1%BB%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E7%AE%80%E5%8D%95%E5%B0%81%E8%A3%85%E3%80%81%E5%AD%A6%E4%B9%A0%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3EJDK%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E6%98%AF%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E5%90%A6%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E5%8F%8D%E5%B0%84+%3Ccode%3EProxy%3C/code%3E%3C/td%3E%3Ctd%20style=%22text-align:left%22%3EAOP%E3%80%81Spring(%E5%8F%AF%E9%80%89)%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3ECGLIB%E4%BB%A3%E7%90%86%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E5%90%A6%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E5%90%A6%3C/td%3E%3Ctd%20style=%22text-align:left%22%3EASM%E5%AD%97%E8%8A%82%E7%8E%9B%E5%A2%9E%E5%BC%BA%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E6%97%A0%E6%8E%A5%E5%8F%A3%E4%BB%A3%E7%90%86%E3%80%81Spring(%E9%BB%98%E8%AE%A4)%3C/td%3E%3C/tr%3E%3C/tbody%3E%3C/table%3E%3Ch2%20id=%22%E6%80%BB%E7%BB%93%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E6%80%BB%E7%BB%93%22%3E%C2%B6%3C/a%3E%E6%80%BB%E7%BB%93%3C/h2%3E%3Cblockquote%3E%3Cp%3E%E4%BB%A3%E7%90%86%E6%A8%A1%E5%BC%8F%E4%BB%8E%3Cstrong%3E%E5%8A%9F%E8%83%BD%E8%A7%92%E5%BA%A6%3C/strong%3E%E5%8F%AF%E4%BB%A5%E5%88%86%E4%B8%BA%EF%BC%9A%20%E8%BF%9C%E7%A8%8B%E4%BB%A3%E7%90%86%E3%80%81%E8%99%9A%E6%8B%9F%E4%BB%A3%E7%90%86%E3%80%81%E4%BF%9D%E6%8A%A4%E4%BB%A3%E7%90%86%EF%BC%9B%E4%BB%8E%3Cstrong%3E%E5%AE%9E%E7%8E%B0%E6%8A%80%E6%9C%AF%E8%A7%92%E5%BA%A6%3C/strong%3E%E5%8F%AF%E5%88%86%E4%B8%BA%EF%BC%9A%20%E9%9D%99%E6%80%81%E4%BB%A3%E7%90%86%E3%80%81%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86(JDK)%E3%80%81CGLIB%E4%BB%A3%E7%90%86%E3%80%82%3C/p%3E%3C/blockquote%3E" type="image"/>
    
    
    
    <category term="structural" scheme="https://galudisu.info/tags/structural/"/>
    
    <category term="proxy" scheme="https://galudisu.info/tags/proxy/"/>
    
  </entry>
  
  <entry>
    <title>享元模式(Flyweight Pattern)</title>
    <link href="https://galudisu.info/2025/05/10/pattern/basic/structural/Flyweight/"/>
    <id>https://galudisu.info/2025/05/10/pattern/basic/structural/Flyweight/</id>
    <published>2025-05-10T10:25:05.000Z</published>
    <updated>2026-04-14T19:59:34.127Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p><strong>通过共享对象来减少内存使用和提高性能</strong>，适用于大量相似对象需要被创建的场景。</p></blockquote><img src="/assert/puml/223ef670f7cc2ef7938ca57234ee6043412fa8e8ab27eea26fb5f16281b746ba.svg"/><span id="more"></span><h3 id="概念定义"><a class="header-anchor" href="#概念定义">¶</a>概念定义</h3><p><strong>享元模式(Flyweight Pattern)</strong> 的核心是为了解决大量对象存在时，可能造成内存溢出，我们把其中共同的部分抽象出来，如果有相同的业务请求，直接返回内存已有的对象，避免重新创建。</p><h3 id="核心结构"><a class="header-anchor" href="#核心结构">¶</a>核心结构</h3><table><thead><tr><th style="text-align:left"><strong>角色</strong></th><th style="text-align:left"><strong>职责</strong></th></tr></thead><tbody><tr><td style="text-align:left"><code>Flyweight(抽象享元类)</code></td><td style="text-align:left">定义公共接口或抽象类，用于管理内部状态。</td></tr><tr><td style="text-align:left"><code>ConcreteFlyweight(具体享元类)</code></td><td style="text-align:left">实现Flyweight接口，存储内部状态</td></tr><tr><td style="text-align:left"><code>UnsharedConcreteFlyweight(非共享具体享元类)</code></td><td style="text-align:left">不可共享的对象(Option)</td></tr><tr><td style="text-align:left"><code>FlyweightFactory(享元工厂)</code></td><td style="text-align:left">负责创建和管理享元对象，确保对象复用</td></tr></tbody></table><h3 id="示例：围棋棋子渲染系统"><a class="header-anchor" href="#示例：围棋棋子渲染系统">¶</a>示例：围棋棋子渲染系统</h3><p>假设我们开发一个围棋游戏，棋盘上有几百个棋子，它们有相同的形状但不同的颜色和位置。</p><img src="/assert/puml/fc18fe8be046fe2f8e863d706da18448679378a9490a1933d5f89f41bd405231.svg"/><p>伪代码如下，</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">Piece</span> &#123;</span><br><span class="line">  <span class="keyword">void</span> <span class="title function_">render</span><span class="params">(<span class="type">int</span> x, <span class="type">int</span> y)</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">WhitePiece</span> <span class="keyword">implements</span> <span class="title class_">Piece</span> &#123;</span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">render</span><span class="params">(<span class="type">int</span> x, <span class="type">int</span> y)</span>; <span class="comment">// 绘制白色棋子</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">BlackPiece</span> <span class="keyword">implements</span> <span class="title class_">Piece</span> &#123;</span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">render</span><span class="params">(<span class="type">int</span> x, <span class="type">int</span> y)</span>; <span class="comment">// 绘制黑色棋子</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">PieceFactory</span> &#123;</span><br><span class="line">  <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> Map&lt;String, Piece&gt; pieces = <span class="keyword">new</span> <span class="title class_">HashMap</span>&lt;&gt;();</span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">static</span> Piece <span class="title function_">getPiece</span><span class="params">(String type)</span> &#123;</span><br><span class="line">    <span class="keyword">if</span> (!pieces.containsKey(type)) &#123;</span><br><span class="line">      <span class="keyword">switch</span> (type) &#123;</span><br><span class="line">        <span class="keyword">case</span> <span class="string">&quot;white&quot;</span>:</span><br><span class="line">          pieces.put(type, <span class="keyword">new</span> <span class="title class_">WhitePiece</span>());  <span class="comment">// <i class="conum" data-value="1"></i></span></span><br><span class="line">          <span class="keyword">break</span>;</span><br><span class="line">        <span class="keyword">case</span> <span class="string">&quot;black&quot;</span>:</span><br><span class="line">          pieces.put(type, <span class="keyword">new</span> <span class="title class_">BlackPiece</span>());</span><br><span class="line">          <span class="keyword">break</span>;</span><br><span class="line">        <span class="keyword">default</span>:</span><br><span class="line">          <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">IllegalArgumentException</span>(<span class="string">&quot;Invalid piece type: &quot;</span> + type);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> pieces.get(type);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><p><i class="conum" data-value="1"></i> 这种暂存的享元模式实际上在开发中非常常见，并且会有意无意中用到。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">void</span> <span class="title function_">main</span><span class="params">()</span> &#123;</span><br><span class="line">  <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; <span class="number">100</span>; i++) &#123;</span><br><span class="line">    <span class="type">var</span> <span class="variable">black</span> <span class="operator">=</span> PieceFactory.getPiece(<span class="string">&quot;black&quot;</span>);</span><br><span class="line">    black.render(i%<span class="number">10</span>, i/<span class="number">10</span>);</span><br><span class="line">    <span class="type">var</span> <span class="variable">white</span> <span class="operator">=</span> PieceFactory.getPiece(<span class="string">&quot;white&quot;</span>);</span><br><span class="line">    white.render(i%<span class="number">10</span>, i/<span class="number">10</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><ul><li>如果不使用享元模式，100黑子+100白子=创建200个对象。</li><li>使用享元后： 只创建2个对象(一个黑子、一个白子)，重复调用<code>render(x, y)</code>即可。</li></ul><h3 id="实际应用场景"><a class="header-anchor" href="#实际应用场景">¶</a>实际应用场景</h3><table><thead><tr><th style="text-align:left">应用</th><th style="text-align:left">描述</th></tr></thead><tbody><tr><td style="text-align:left">文本编辑器</td><td style="text-align:left">字符样式共享(字体、大小、颜色)，位置作为外部 状态</td></tr><tr><td style="text-align:left">游戏开发</td><td style="text-align:left">子弹、敌人、道具等大量重复实体对象(早期像素游戏)</td></tr><tr><td style="text-align:left">图形界面库</td><td style="text-align:left">按钮、图标、字体等图形资源缓存</td></tr><tr><td style="text-align:left">数据库连接池</td><td style="text-align:left">复用数据库连接对象</td></tr></tbody></table><h2 id="总结"><a class="header-anchor" href="#总结">¶</a>总结</h2><blockquote><p>享元模式的核心思想是“共享不变、分离变化”，适用于大量相似对象的复用场景。</p></blockquote>]]></content>
    
    
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;通过共享对象来减少内存使用和提高性能&lt;/strong&gt;，适用于大量相似对象需要被创建的场景。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;img src=&quot;/assert/puml/223ef670f7cc2ef7938ca57234ee6043412fa8e8ab27eea26fb5f16281b746ba.svg&quot;/&gt;</summary>
    
    
    <content src="https://galudisu.info/%3Cblockquote%3E%3Cp%3E%3Cstrong%3E%E9%80%9A%E8%BF%87%E5%85%B1%E4%BA%AB%E5%AF%B9%E8%B1%A1%E6%9D%A5%E5%87%8F%E5%B0%91%E5%86%85%E5%AD%98%E4%BD%BF%E7%94%A8%E5%92%8C%E6%8F%90%E9%AB%98%E6%80%A7%E8%83%BD%3C/strong%3E%EF%BC%8C%E9%80%82%E7%94%A8%E4%BA%8E%E5%A4%A7%E9%87%8F%E7%9B%B8%E4%BC%BC%E5%AF%B9%E8%B1%A1%E9%9C%80%E8%A6%81%E8%A2%AB%E5%88%9B%E5%BB%BA%E7%9A%84%E5%9C%BA%E6%99%AF%E3%80%82%3C/p%3E%3C/blockquote%3E%3Cimg%20src=%22/assert/puml/223ef670f7cc2ef7938ca57234ee6043412fa8e8ab27eea26fb5f16281b746ba.svg%22/%3E%3Cspan%20id=%22more%22%3E%3C/span%3E%3Ch3%20id=%22%E6%A6%82%E5%BF%B5%E5%AE%9A%E4%B9%89%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E6%A6%82%E5%BF%B5%E5%AE%9A%E4%B9%89%22%3E%C2%B6%3C/a%3E%E6%A6%82%E5%BF%B5%E5%AE%9A%E4%B9%89%3C/h3%3E%3Cp%3E%3Cstrong%3E%E4%BA%AB%E5%85%83%E6%A8%A1%E5%BC%8F(Flyweight%20Pattern)%3C/strong%3E%20%E7%9A%84%E6%A0%B8%E5%BF%83%E6%98%AF%E4%B8%BA%E4%BA%86%E8%A7%A3%E5%86%B3%E5%A4%A7%E9%87%8F%E5%AF%B9%E8%B1%A1%E5%AD%98%E5%9C%A8%E6%97%B6%EF%BC%8C%E5%8F%AF%E8%83%BD%E9%80%A0%E6%88%90%E5%86%85%E5%AD%98%E6%BA%A2%E5%87%BA%EF%BC%8C%E6%88%91%E4%BB%AC%E6%8A%8A%E5%85%B6%E4%B8%AD%E5%85%B1%E5%90%8C%E7%9A%84%E9%83%A8%E5%88%86%E6%8A%BD%E8%B1%A1%E5%87%BA%E6%9D%A5%EF%BC%8C%E5%A6%82%E6%9E%9C%E6%9C%89%E7%9B%B8%E5%90%8C%E7%9A%84%E4%B8%9A%E5%8A%A1%E8%AF%B7%E6%B1%82%EF%BC%8C%E7%9B%B4%E6%8E%A5%E8%BF%94%E5%9B%9E%E5%86%85%E5%AD%98%E5%B7%B2%E6%9C%89%E7%9A%84%E5%AF%B9%E8%B1%A1%EF%BC%8C%E9%81%BF%E5%85%8D%E9%87%8D%E6%96%B0%E5%88%9B%E5%BB%BA%E3%80%82%3C/p%3E%3Ch3%20id=%22%E6%A0%B8%E5%BF%83%E7%BB%93%E6%9E%84%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E6%A0%B8%E5%BF%83%E7%BB%93%E6%9E%84%22%3E%C2%B6%3C/a%3E%E6%A0%B8%E5%BF%83%E7%BB%93%E6%9E%84%3C/h3%3E%3Ctable%3E%3Cthead%3E%3Ctr%3E%3Cth%20style=%22text-align:left%22%3E%3Cstrong%3E%E8%A7%92%E8%89%B2%3C/strong%3E%3C/th%3E%3Cth%20style=%22text-align:left%22%3E%3Cstrong%3E%E8%81%8C%E8%B4%A3%3C/strong%3E%3C/th%3E%3C/tr%3E%3C/thead%3E%3Ctbody%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%3Ccode%3EFlyweight(%E6%8A%BD%E8%B1%A1%E4%BA%AB%E5%85%83%E7%B1%BB)%3C/code%3E%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E5%AE%9A%E4%B9%89%E5%85%AC%E5%85%B1%E6%8E%A5%E5%8F%A3%E6%88%96%E6%8A%BD%E8%B1%A1%E7%B1%BB%EF%BC%8C%E7%94%A8%E4%BA%8E%E7%AE%A1%E7%90%86%E5%86%85%E9%83%A8%E7%8A%B6%E6%80%81%E3%80%82%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%3Ccode%3EConcreteFlyweight(%E5%85%B7%E4%BD%93%E4%BA%AB%E5%85%83%E7%B1%BB)%3C/code%3E%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E5%AE%9E%E7%8E%B0Flyweight%E6%8E%A5%E5%8F%A3%EF%BC%8C%E5%AD%98%E5%82%A8%E5%86%85%E9%83%A8%E7%8A%B6%E6%80%81%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%3Ccode%3EUnsharedConcreteFlyweight(%E9%9D%9E%E5%85%B1%E4%BA%AB%E5%85%B7%E4%BD%93%E4%BA%AB%E5%85%83%E7%B1%BB)%3C/code%3E%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E4%B8%8D%E5%8F%AF%E5%85%B1%E4%BA%AB%E7%9A%84%E5%AF%B9%E8%B1%A1(Option)%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%3Ccode%3EFlyweightFactory(%E4%BA%AB%E5%85%83%E5%B7%A5%E5%8E%82)%3C/code%3E%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E8%B4%9F%E8%B4%A3%E5%88%9B%E5%BB%BA%E5%92%8C%E7%AE%A1%E7%90%86%E4%BA%AB%E5%85%83%E5%AF%B9%E8%B1%A1%EF%BC%8C%E7%A1%AE%E4%BF%9D%E5%AF%B9%E8%B1%A1%E5%A4%8D%E7%94%A8%3C/td%3E%3C/tr%3E%3C/tbody%3E%3C/table%3E%3Ch3%20id=%22%E7%A4%BA%E4%BE%8B%EF%BC%9A%E5%9B%B4%E6%A3%8B%E6%A3%8B%E5%AD%90%E6%B8%B2%E6%9F%93%E7%B3%BB%E7%BB%9F%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E7%A4%BA%E4%BE%8B%EF%BC%9A%E5%9B%B4%E6%A3%8B%E6%A3%8B%E5%AD%90%E6%B8%B2%E6%9F%93%E7%B3%BB%E7%BB%9F%22%3E%C2%B6%3C/a%3E%E7%A4%BA%E4%BE%8B%EF%BC%9A%E5%9B%B4%E6%A3%8B%E6%A3%8B%E5%AD%90%E6%B8%B2%E6%9F%93%E7%B3%BB%E7%BB%9F%3C/h3%3E%3Cp%3E%E5%81%87%E8%AE%BE%E6%88%91%E4%BB%AC%E5%BC%80%E5%8F%91%E4%B8%80%E4%B8%AA%E5%9B%B4%E6%A3%8B%E6%B8%B8%E6%88%8F%EF%BC%8C%E6%A3%8B%E7%9B%98%E4%B8%8A%E6%9C%89%E5%87%A0%E7%99%BE%E4%B8%AA%E6%A3%8B%E5%AD%90%EF%BC%8C%E5%AE%83%E4%BB%AC%E6%9C%89%E7%9B%B8%E5%90%8C%E7%9A%84%E5%BD%A2%E7%8A%B6%E4%BD%86%E4%B8%8D%E5%90%8C%E7%9A%84%E9%A2%9C%E8%89%B2%E5%92%8C%E4%BD%8D%E7%BD%AE%E3%80%82%3C/p%3E%3Cimg%20src=%22/assert/puml/fc18fe8be046fe2f8e863d706da18448679378a9490a1933d5f89f41bd405231.svg%22/%3E%3Cp%3E%E4%BC%AA%E4%BB%A3%E7%A0%81%E5%A6%82%E4%B8%8B%EF%BC%8C%3C/p%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E8%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E9%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E10%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E11%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E12%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E13%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E14%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E15%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E16%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E17%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E18%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E19%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E21%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E22%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E23%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E24%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E25%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E26%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E27%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E28%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E29%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E30%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E31%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Einterface%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EPiece%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Erender%3C/span%3E%3Cspan%20class=%22params%22%3E(%3Cspan%20class=%22type%22%3Eint%3C/span%3E%20x,%20%3Cspan%20class=%22type%22%3Eint%3C/span%3E%20y)%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EWhitePiece%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eimplements%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EPiece%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Erender%3C/span%3E%3Cspan%20class=%22params%22%3E(%3Cspan%20class=%22type%22%3Eint%3C/span%3E%20x,%20%3Cspan%20class=%22type%22%3Eint%3C/span%3E%20y)%3C/span%3E;%20%3Cspan%20class=%22comment%22%3E/%20%E7%BB%98%E5%88%B6%E7%99%BD%E8%89%B2%E6%A3%8B%E5%AD%90%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EBlackPiece%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eimplements%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EPiece%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Erender%3C/span%3E%3Cspan%20class=%22params%22%3E(%3Cspan%20class=%22type%22%3Eint%3C/span%3E%20x,%20%3Cspan%20class=%22type%22%3Eint%3C/span%3E%20y)%3C/span%3E;%20%3Cspan%20class=%22comment%22%3E/%20%E7%BB%98%E5%88%B6%E9%BB%91%E8%89%B2%E6%A3%8B%E5%AD%90%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EPieceFactory%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Eprivate%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Estatic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Efinal%3C/span%3E%20Map&amp;lt;String,%20Piece&amp;gt;%20pieces%20=%20%3Cspan%20class=%22keyword%22%3Enew%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EHashMap%3C/span%3E&amp;lt;&amp;gt;();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Estatic%3C/span%3E%20Piece%20%3Cspan%20class=%22title%20function_%22%3EgetPiece%3C/span%3E%3Cspan%20class=%22params%22%3E(String%20type)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Eif%3C/span%3E%20(!pieces.containsKey(type))%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%3Cspan%20class=%22keyword%22%3Eswitch%3C/span%3E%20(type)%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20%3Cspan%20class=%22keyword%22%3Ecase%3C/span%3E%20%3Cspan%20class=%22string%22%3E&amp;quot;white&amp;quot;%3C/span%3E:%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20%20%20pieces.put(type,%20%3Cspan%20class=%22keyword%22%3Enew%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EWhitePiece%3C/span%3E());%20%20%3Cspan%20class=%22comment%22%3E/%20%3Ci%20class=%22conum%22%20data-value=%221%22%3E%3C/i%3E%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20%20%20%3Cspan%20class=%22keyword%22%3Ebreak%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20%3Cspan%20class=%22keyword%22%3Ecase%3C/span%3E%20%3Cspan%20class=%22string%22%3E&amp;quot;black&amp;quot;%3C/span%3E:%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20%20%20pieces.put(type,%20%3Cspan%20class=%22keyword%22%3Enew%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EBlackPiece%3C/span%3E());%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20%20%20%3Cspan%20class=%22keyword%22%3Ebreak%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20%3Cspan%20class=%22keyword%22%3Edefault%3C/span%3E:%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20%20%20%20%20%3Cspan%20class=%22keyword%22%3Ethrow%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Enew%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EIllegalArgumentException%3C/span%3E(%3Cspan%20class=%22string%22%3E&amp;quot;Invalid%20piece%20type:%20&amp;quot;%3C/span%3E%20+%20type);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Ereturn%3C/span%3E%20pieces.get(type);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Cp%3E%3Ci%20class=%22conum%22%20data-value=%221%22%3E%3C/i%3E%20%E8%BF%99%E7%A7%8D%E6%9A%82%E5%AD%98%E7%9A%84%E4%BA%AB%E5%85%83%E6%A8%A1%E5%BC%8F%E5%AE%9E%E9%99%85%E4%B8%8A%E5%9C%A8%E5%BC%80%E5%8F%91%E4%B8%AD%E9%9D%9E%E5%B8%B8%E5%B8%B8%E8%A7%81%EF%BC%8C%E5%B9%B6%E4%B8%94%E4%BC%9A%E6%9C%89%E6%84%8F%E6%97%A0%E6%84%8F%E4%B8%AD%E7%94%A8%E5%88%B0%E3%80%82%3C/p%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E8%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Emain%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Efor%3C/span%3E%20(%3Cspan%20class=%22type%22%3Eint%3C/span%3E%20%3Cspan%20class=%22variable%22%3Ei%3C/span%3E%20%3Cspan%20class=%22operator%22%3E=%3C/span%3E%20%3Cspan%20class=%22number%22%3E0%3C/span%3E;%20i%20&amp;lt;%20%3Cspan%20class=%22number%22%3E100%3C/span%3E;%20i++)%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22type%22%3Evar%3C/span%3E%20%3Cspan%20class=%22variable%22%3Eblack%3C/span%3E%20%3Cspan%20class=%22operator%22%3E=%3C/span%3E%20PieceFactory.getPiece(%3Cspan%20class=%22string%22%3E&amp;quot;black&amp;quot;%3C/span%3E);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20black.render(i%%3Cspan%20class=%22number%22%3E10%3C/span%3E,%20i/%3Cspan%20class=%22number%22%3E10%3C/span%3E);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22type%22%3Evar%3C/span%3E%20%3Cspan%20class=%22variable%22%3Ewhite%3C/span%3E%20%3Cspan%20class=%22operator%22%3E=%3C/span%3E%20PieceFactory.getPiece(%3Cspan%20class=%22string%22%3E&amp;quot;white&amp;quot;%3C/span%3E);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20white.render(i%%3Cspan%20class=%22number%22%3E10%3C/span%3E,%20i/%3Cspan%20class=%22number%22%3E10%3C/span%3E);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Cul%3E%3Cli%3E%E5%A6%82%E6%9E%9C%E4%B8%8D%E4%BD%BF%E7%94%A8%E4%BA%AB%E5%85%83%E6%A8%A1%E5%BC%8F%EF%BC%8C100%E9%BB%91%E5%AD%90+100%E7%99%BD%E5%AD%90=%E5%88%9B%E5%BB%BA200%E4%B8%AA%E5%AF%B9%E8%B1%A1%E3%80%82%3C/li%3E%3Cli%3E%E4%BD%BF%E7%94%A8%E4%BA%AB%E5%85%83%E5%90%8E%EF%BC%9A%20%E5%8F%AA%E5%88%9B%E5%BB%BA2%E4%B8%AA%E5%AF%B9%E8%B1%A1(%E4%B8%80%E4%B8%AA%E9%BB%91%E5%AD%90%E3%80%81%E4%B8%80%E4%B8%AA%E7%99%BD%E5%AD%90)%EF%BC%8C%E9%87%8D%E5%A4%8D%E8%B0%83%E7%94%A8%3Ccode%3Erender(x,%20y)%3C/code%3E%E5%8D%B3%E5%8F%AF%E3%80%82%3C/li%3E%3C/ul%3E%3Ch3%20id=%22%E5%AE%9E%E9%99%85%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E5%AE%9E%E9%99%85%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF%22%3E%C2%B6%3C/a%3E%E5%AE%9E%E9%99%85%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF%3C/h3%3E%3Ctable%3E%3Cthead%3E%3Ctr%3E%3Cth%20style=%22text-align:left%22%3E%E5%BA%94%E7%94%A8%3C/th%3E%3Cth%20style=%22text-align:left%22%3E%E6%8F%8F%E8%BF%B0%3C/th%3E%3C/tr%3E%3C/thead%3E%3Ctbody%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%E6%96%87%E6%9C%AC%E7%BC%96%E8%BE%91%E5%99%A8%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E5%AD%97%E7%AC%A6%E6%A0%B7%E5%BC%8F%E5%85%B1%E4%BA%AB(%E5%AD%97%E4%BD%93%E3%80%81%E5%A4%A7%E5%B0%8F%E3%80%81%E9%A2%9C%E8%89%B2)%EF%BC%8C%E4%BD%8D%E7%BD%AE%E4%BD%9C%E4%B8%BA%E5%A4%96%E9%83%A8%20%E7%8A%B6%E6%80%81%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%E6%B8%B8%E6%88%8F%E5%BC%80%E5%8F%91%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E5%AD%90%E5%BC%B9%E3%80%81%E6%95%8C%E4%BA%BA%E3%80%81%E9%81%93%E5%85%B7%E7%AD%89%E5%A4%A7%E9%87%8F%E9%87%8D%E5%A4%8D%E5%AE%9E%E4%BD%93%E5%AF%B9%E8%B1%A1(%E6%97%A9%E6%9C%9F%E5%83%8F%E7%B4%A0%E6%B8%B8%E6%88%8F)%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%E5%9B%BE%E5%BD%A2%E7%95%8C%E9%9D%A2%E5%BA%93%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E6%8C%89%E9%92%AE%E3%80%81%E5%9B%BE%E6%A0%87%E3%80%81%E5%AD%97%E4%BD%93%E7%AD%89%E5%9B%BE%E5%BD%A2%E8%B5%84%E6%BA%90%E7%BC%93%E5%AD%98%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%20style=%22text-align:left%22%3E%E6%95%B0%E6%8D%AE%E5%BA%93%E8%BF%9E%E6%8E%A5%E6%B1%A0%3C/td%3E%3Ctd%20style=%22text-align:left%22%3E%E5%A4%8D%E7%94%A8%E6%95%B0%E6%8D%AE%E5%BA%93%E8%BF%9E%E6%8E%A5%E5%AF%B9%E8%B1%A1%3C/td%3E%3C/tr%3E%3C/tbody%3E%3C/table%3E%3Ch2%20id=%22%E6%80%BB%E7%BB%93%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E6%80%BB%E7%BB%93%22%3E%C2%B6%3C/a%3E%E6%80%BB%E7%BB%93%3C/h2%3E%3Cblockquote%3E%3Cp%3E%E4%BA%AB%E5%85%83%E6%A8%A1%E5%BC%8F%E7%9A%84%E6%A0%B8%E5%BF%83%E6%80%9D%E6%83%B3%E6%98%AF%E2%80%9C%E5%85%B1%E4%BA%AB%E4%B8%8D%E5%8F%98%E3%80%81%E5%88%86%E7%A6%BB%E5%8F%98%E5%8C%96%E2%80%9D%EF%BC%8C%E9%80%82%E7%94%A8%E4%BA%8E%E5%A4%A7%E9%87%8F%E7%9B%B8%E4%BC%BC%E5%AF%B9%E8%B1%A1%E7%9A%84%E5%A4%8D%E7%94%A8%E5%9C%BA%E6%99%AF%E3%80%82%3C/p%3E%3C/blockquote%3E" type="image"/>
    
    
    
    <category term="structural" scheme="https://galudisu.info/tags/structural/"/>
    
    <category term="flyweight" scheme="https://galudisu.info/tags/flyweight/"/>
    
  </entry>
  
  <entry>
    <title>外观模式(Facade Pattern)</title>
    <link href="https://galudisu.info/2025/05/10/pattern/basic/structural/Facade/"/>
    <id>https://galudisu.info/2025/05/10/pattern/basic/structural/Facade/</id>
    <published>2025-05-10T10:25:04.000Z</published>
    <updated>2026-04-14T19:59:34.033Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>提供了一个统一的接口，用来访问子系统中的一群接口，外观定义了一个高层的接口，让子系统更容易使用。<strong>其实就是为了方便客户的使用，把一群操作，封装成一个方法</strong>。</p></blockquote><img src="/assert/puml/fcabf988403ace7972cf5031702aca934b86568740864ad48f49021f7aa7fcce.svg"/><span id="more"></span><p>外观模式，就是“method”层面上的组合模式，上个章节的<a href="/2025/05/10/pattern/basic/structural/Composite">组合模式</a>是多个类，而外观模式就是多个方法。</p><h3 id="场景描述"><a class="header-anchor" href="#场景描述">¶</a>场景描述</h3><p>你有一个家庭影院系统，包含以下设备：</p><ul><li>影碟机(DVD Player)</li><li>投影仪(Projector)</li><li>音响(Sound System)</li><li>灯光(Lights)</li></ul><p>每次想要看电影时，你需要手动做以下操作：</p><ol><li>关灯</li><li>打开投影仪</li><li>启动音响</li><li>播放DVD</li></ol><p>看完电影后又要一次关闭这些设备。</p><img src="/assert/puml/27983651be2688e8b78c367be911e4ce0f6a3a26a4d97369d9a809bca3607b3d.svg"/><p>这个过程非常繁琐，而<strong>外观模式</strong>可以封装这些复杂逻辑，对外提供一个简单接口，</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">HomeTheaterFacade</span> &#123;</span><br><span class="line">  ...</span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">watchMovie</span><span class="params">(String movie)</span> &#123;</span><br><span class="line">    System.out.println(<span class="string">&quot;Get ready to watch a movie...&quot;</span>);</span><br><span class="line">    lights.dim(<span class="number">10</span>);</span><br><span class="line">    projector.on();</span><br><span class="line">    projector.setInput(dvdPlayer);</span><br><span class="line">    amplifier.on();</span><br><span class="line">    amplifier.setVolume(<span class="number">75</span>);</span><br><span class="line">    amplifier.setInput(dvdPlayer);</span><br><span class="line">    dvdPlayer.on();</span><br><span class="line">    dvdPlayer.play(movie);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">endMovie</span><span class="params">()</span> &#123;</span><br><span class="line">    System.out.println(<span class="string">&quot;Shutting movie theater down...&quot;</span>);</span><br><span class="line">    dvdPlayer.stop();</span><br><span class="line">    dvdPlayer.off();</span><br><span class="line">    amplifier.off();</span><br><span class="line">    projector.off();</span><br><span class="line">    lights.off();</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>我只需要“一键”观影即可。</p><h2 id="总结"><a class="header-anchor" href="#总结">¶</a>总结</h2><p><strong>优点</strong>：</p><ul><li>简化接口，不需要了解每个子系统的细节</li><li>解耦，客户端只依赖外观类，不与具体子系统耦合</li><li>提高维护性，子系统的变化，只需要修改外观类，不影响客户端</li></ul><p><strong>其它常见应用示例</strong></p><ol><li>编译器/解析器，将词法分析、语法分析、语义分析处理封装成一个<code>Compiler</code>外观</li><li>支付系统中对接多个支付渠道(微信、支付宝、银联),统一调用接口</li></ol>]]></content>
    
    
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;提供了一个统一的接口，用来访问子系统中的一群接口，外观定义了一个高层的接口，让子系统更容易使用。&lt;strong&gt;其实就是为了方便客户的使用，把一群操作，封装成一个方法&lt;/strong&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;img src=&quot;/assert/puml/fcabf988403ace7972cf5031702aca934b86568740864ad48f49021f7aa7fcce.svg&quot;/&gt;</summary>
    
    
    <content src="https://galudisu.info/%3Cblockquote%3E%3Cp%3E%E6%8F%90%E4%BE%9B%E4%BA%86%E4%B8%80%E4%B8%AA%E7%BB%9F%E4%B8%80%E7%9A%84%E6%8E%A5%E5%8F%A3%EF%BC%8C%E7%94%A8%E6%9D%A5%E8%AE%BF%E9%97%AE%E5%AD%90%E7%B3%BB%E7%BB%9F%E4%B8%AD%E7%9A%84%E4%B8%80%E7%BE%A4%E6%8E%A5%E5%8F%A3%EF%BC%8C%E5%A4%96%E8%A7%82%E5%AE%9A%E4%B9%89%E4%BA%86%E4%B8%80%E4%B8%AA%E9%AB%98%E5%B1%82%E7%9A%84%E6%8E%A5%E5%8F%A3%EF%BC%8C%E8%AE%A9%E5%AD%90%E7%B3%BB%E7%BB%9F%E6%9B%B4%E5%AE%B9%E6%98%93%E4%BD%BF%E7%94%A8%E3%80%82%3Cstrong%3E%E5%85%B6%E5%AE%9E%E5%B0%B1%E6%98%AF%E4%B8%BA%E4%BA%86%E6%96%B9%E4%BE%BF%E5%AE%A2%E6%88%B7%E7%9A%84%E4%BD%BF%E7%94%A8%EF%BC%8C%E6%8A%8A%E4%B8%80%E7%BE%A4%E6%93%8D%E4%BD%9C%EF%BC%8C%E5%B0%81%E8%A3%85%E6%88%90%E4%B8%80%E4%B8%AA%E6%96%B9%E6%B3%95%3C/strong%3E%E3%80%82%3C/p%3E%3C/blockquote%3E%3Cimg%20src=%22/assert/puml/fcabf988403ace7972cf5031702aca934b86568740864ad48f49021f7aa7fcce.svg%22/%3E%3Cspan%20id=%22more%22%3E%3C/span%3E%3Cp%3E%E5%A4%96%E8%A7%82%E6%A8%A1%E5%BC%8F%EF%BC%8C%E5%B0%B1%E6%98%AF%E2%80%9Cmethod%E2%80%9D%E5%B1%82%E9%9D%A2%E4%B8%8A%E7%9A%84%E7%BB%84%E5%90%88%E6%A8%A1%E5%BC%8F%EF%BC%8C%E4%B8%8A%E4%B8%AA%E7%AB%A0%E8%8A%82%E7%9A%84%3Ca%20href=%22/2025/05/10/pattern/basic/structural/Composite%22%3E%E7%BB%84%E5%90%88%E6%A8%A1%E5%BC%8F%3C/a%3E%E6%98%AF%E5%A4%9A%E4%B8%AA%E7%B1%BB%EF%BC%8C%E8%80%8C%E5%A4%96%E8%A7%82%E6%A8%A1%E5%BC%8F%E5%B0%B1%E6%98%AF%E5%A4%9A%E4%B8%AA%E6%96%B9%E6%B3%95%E3%80%82%3C/p%3E%3Ch3%20id=%22%E5%9C%BA%E6%99%AF%E6%8F%8F%E8%BF%B0%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E5%9C%BA%E6%99%AF%E6%8F%8F%E8%BF%B0%22%3E%C2%B6%3C/a%3E%E5%9C%BA%E6%99%AF%E6%8F%8F%E8%BF%B0%3C/h3%3E%3Cp%3E%E4%BD%A0%E6%9C%89%E4%B8%80%E4%B8%AA%E5%AE%B6%E5%BA%AD%E5%BD%B1%E9%99%A2%E7%B3%BB%E7%BB%9F%EF%BC%8C%E5%8C%85%E5%90%AB%E4%BB%A5%E4%B8%8B%E8%AE%BE%E5%A4%87%EF%BC%9A%3C/p%3E%3Cul%3E%3Cli%3E%E5%BD%B1%E7%A2%9F%E6%9C%BA(DVD%20Player)%3C/li%3E%3Cli%3E%E6%8A%95%E5%BD%B1%E4%BB%AA(Projector)%3C/li%3E%3Cli%3E%E9%9F%B3%E5%93%8D(Sound%20System)%3C/li%3E%3Cli%3E%E7%81%AF%E5%85%89(Lights)%3C/li%3E%3C/ul%3E%3Cp%3E%E6%AF%8F%E6%AC%A1%E6%83%B3%E8%A6%81%E7%9C%8B%E7%94%B5%E5%BD%B1%E6%97%B6%EF%BC%8C%E4%BD%A0%E9%9C%80%E8%A6%81%E6%89%8B%E5%8A%A8%E5%81%9A%E4%BB%A5%E4%B8%8B%E6%93%8D%E4%BD%9C%EF%BC%9A%3C/p%3E%3Col%3E%3Cli%3E%E5%85%B3%E7%81%AF%3C/li%3E%3Cli%3E%E6%89%93%E5%BC%80%E6%8A%95%E5%BD%B1%E4%BB%AA%3C/li%3E%3Cli%3E%E5%90%AF%E5%8A%A8%E9%9F%B3%E5%93%8D%3C/li%3E%3Cli%3E%E6%92%AD%E6%94%BEDVD%3C/li%3E%3C/ol%3E%3Cp%3E%E7%9C%8B%E5%AE%8C%E7%94%B5%E5%BD%B1%E5%90%8E%E5%8F%88%E8%A6%81%E4%B8%80%E6%AC%A1%E5%85%B3%E9%97%AD%E8%BF%99%E4%BA%9B%E8%AE%BE%E5%A4%87%E3%80%82%3C/p%3E%3Cimg%20src=%22/assert/puml/27983651be2688e8b78c367be911e4ce0f6a3a26a4d97369d9a809bca3607b3d.svg%22/%3E%3Cp%3E%E8%BF%99%E4%B8%AA%E8%BF%87%E7%A8%8B%E9%9D%9E%E5%B8%B8%E7%B9%81%E7%90%90%EF%BC%8C%E8%80%8C%3Cstrong%3E%E5%A4%96%E8%A7%82%E6%A8%A1%E5%BC%8F%3C/strong%3E%E5%8F%AF%E4%BB%A5%E5%B0%81%E8%A3%85%E8%BF%99%E4%BA%9B%E5%A4%8D%E6%9D%82%E9%80%BB%E8%BE%91%EF%BC%8C%E5%AF%B9%E5%A4%96%E6%8F%90%E4%BE%9B%E4%B8%80%E4%B8%AA%E7%AE%80%E5%8D%95%E6%8E%A5%E5%8F%A3%EF%BC%8C%3C/p%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E8%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E9%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E10%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E11%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E12%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E13%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E14%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E15%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E16%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E17%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E18%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E19%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E21%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E22%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E23%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EHomeTheaterFacade%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20...%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EwatchMovie%3C/span%3E%3Cspan%20class=%22params%22%3E(String%20movie)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20System.out.println(%3Cspan%20class=%22string%22%3E&amp;quot;Get%20ready%20to%20watch%20a%20movie...&amp;quot;%3C/span%3E);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20lights.dim(%3Cspan%20class=%22number%22%3E10%3C/span%3E);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20projector.on();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20projector.setInput(dvdPlayer);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20amplifier.on();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20amplifier.setVolume(%3Cspan%20class=%22number%22%3E75%3C/span%3E);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20amplifier.setInput(dvdPlayer);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20dvdPlayer.on();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20dvdPlayer.play(movie);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EendMovie%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20System.out.println(%3Cspan%20class=%22string%22%3E&amp;quot;Shutting%20movie%20theater%20down...&amp;quot;%3C/span%3E);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20dvdPlayer.stop();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20dvdPlayer.off();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20amplifier.off();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20projector.off();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20lights.off();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Cp%3E%E6%88%91%E5%8F%AA%E9%9C%80%E8%A6%81%E2%80%9C%E4%B8%80%E9%94%AE%E2%80%9D%E8%A7%82%E5%BD%B1%E5%8D%B3%E5%8F%AF%E3%80%82%3C/p%3E%3Ch2%20id=%22%E6%80%BB%E7%BB%93%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E6%80%BB%E7%BB%93%22%3E%C2%B6%3C/a%3E%E6%80%BB%E7%BB%93%3C/h2%3E%3Cp%3E%3Cstrong%3E%E4%BC%98%E7%82%B9%3C/strong%3E%EF%BC%9A%3C/p%3E%3Cul%3E%3Cli%3E%E7%AE%80%E5%8C%96%E6%8E%A5%E5%8F%A3%EF%BC%8C%E4%B8%8D%E9%9C%80%E8%A6%81%E4%BA%86%E8%A7%A3%E6%AF%8F%E4%B8%AA%E5%AD%90%E7%B3%BB%E7%BB%9F%E7%9A%84%E7%BB%86%E8%8A%82%3C/li%3E%3Cli%3E%E8%A7%A3%E8%80%A6%EF%BC%8C%E5%AE%A2%E6%88%B7%E7%AB%AF%E5%8F%AA%E4%BE%9D%E8%B5%96%E5%A4%96%E8%A7%82%E7%B1%BB%EF%BC%8C%E4%B8%8D%E4%B8%8E%E5%85%B7%E4%BD%93%E5%AD%90%E7%B3%BB%E7%BB%9F%E8%80%A6%E5%90%88%3C/li%3E%3Cli%3E%E6%8F%90%E9%AB%98%E7%BB%B4%E6%8A%A4%E6%80%A7%EF%BC%8C%E5%AD%90%E7%B3%BB%E7%BB%9F%E7%9A%84%E5%8F%98%E5%8C%96%EF%BC%8C%E5%8F%AA%E9%9C%80%E8%A6%81%E4%BF%AE%E6%94%B9%E5%A4%96%E8%A7%82%E7%B1%BB%EF%BC%8C%E4%B8%8D%E5%BD%B1%E5%93%8D%E5%AE%A2%E6%88%B7%E7%AB%AF%3C/li%3E%3C/ul%3E%3Cp%3E%3Cstrong%3E%E5%85%B6%E5%AE%83%E5%B8%B8%E8%A7%81%E5%BA%94%E7%94%A8%E7%A4%BA%E4%BE%8B%3C/strong%3E%3C/p%3E%3Col%3E%3Cli%3E%E7%BC%96%E8%AF%91%E5%99%A8/%E8%A7%A3%E6%9E%90%E5%99%A8%EF%BC%8C%E5%B0%86%E8%AF%8D%E6%B3%95%E5%88%86%E6%9E%90%E3%80%81%E8%AF%AD%E6%B3%95%E5%88%86%E6%9E%90%E3%80%81%E8%AF%AD%E4%B9%89%E5%88%86%E6%9E%90%E5%A4%84%E7%90%86%E5%B0%81%E8%A3%85%E6%88%90%E4%B8%80%E4%B8%AA%3Ccode%3ECompiler%3C/code%3E%E5%A4%96%E8%A7%82%3C/li%3E%3Cli%3E%E6%94%AF%E4%BB%98%E7%B3%BB%E7%BB%9F%E4%B8%AD%E5%AF%B9%E6%8E%A5%E5%A4%9A%E4%B8%AA%E6%94%AF%E4%BB%98%E6%B8%A0%E9%81%93(%E5%BE%AE%E4%BF%A1%E3%80%81%E6%94%AF%E4%BB%98%E5%AE%9D%E3%80%81%E9%93%B6%E8%81%94),%E7%BB%9F%E4%B8%80%E8%B0%83%E7%94%A8%E6%8E%A5%E5%8F%A3%3C/li%3E%3C/ol%3E" type="image"/>
    
    
    
    <category term="structural" scheme="https://galudisu.info/tags/structural/"/>
    
    <category term="facade" scheme="https://galudisu.info/tags/facade/"/>
    
  </entry>
  
  <entry>
    <title>组合模式(Composite Pattern)</title>
    <link href="https://galudisu.info/2025/05/10/pattern/basic/structural/Composite/"/>
    <id>https://galudisu.info/2025/05/10/pattern/basic/structural/Composite/</id>
    <published>2025-05-10T10:25:03.000Z</published>
    <updated>2026-04-14T19:59:33.953Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>又叫部分整体模式，是用于把一组相似的对象当作一个单一的对象。组合模式依据<strong>树形结构</strong>来组合对象，用来表示”整体-部分“层次。这种模式使得客户端可以统一处理单个对象和组合对象，而无需关心它们的具体实现。</p></blockquote><img src="/assert/puml/22f0c50b3b853734516cc232fff2b8220df083e4655e5faa0b28d330d9081478.svg"/><span id="more"></span><h3 id="核心角色"><a class="header-anchor" href="#核心角色">¶</a>核心角色</h3><table><thead><tr><th><strong>角色</strong></th><th><strong>职责</strong></th></tr></thead><tbody><tr><td>Component</td><td>定义所有叶子和组合的公共接口，通常是抽象类或接口</td></tr><tr><td>Leaf</td><td>表示没有子节点的对象，实现基本操作</td></tr><tr><td>Composite</td><td>包含子组件的对象，实现容器行为，如添加、删除子组件等</td></tr></tbody></table><h3 id="适用场景"><a class="header-anchor" href="#适用场景">¶</a>适用场景</h3><ul><li>需要表示“整体-部分”关系的结构(如文件系统目录与文件、学校组织、管理层级)</li><li>希望客户端 <em>以一致方式处理单个对象和组合对象</em>。</li><li>结构具有层级性，并且可能动态变化。</li></ul><h3 id="真实案例"><a class="header-anchor" href="#真实案例">¶</a>真实案例</h3><p>对于某OA系统，中秋节安排了统一假期，但某些部门中秋节必须轮班，但可以节后进行调休申请。另外针对个别人员，比如电工、安防等个别对象需要派一到两个人留守，在节前申报了坚守岗位的名单后，office boy在OA系统上通过拖拽的方式，统一调整的内部员工的假期。</p><img src="/assert/puml/b7c3e9305ac1a7fbd7630176145966f8add3faf0604b9d280b45f1184c618df0.svg"/><p>设计如下：</p><table><thead><tr><th><strong>角色</strong></th><th><strong>实例</strong></th><th><strong>描述</strong></th></tr></thead><tbody><tr><td>Component</td><td>AttendanceComponent</td><td>考勤</td></tr><tr><td>Leaf</td><td>EmployeeLeaf</td><td>员工个人的考勤</td></tr><tr><td>Composite</td><td>DepartmentComposite</td><td>整个部门的考勤</td></tr></tbody></table><p>组合模式(Composite Pattern)和企业级设计模式的“对象-关系”映射相对应，但这里只讨论代码层面的映射关系，设计如下</p><img src="/assert/puml/d9edde97f8418133667e001cd4e9f485cdd0389d979df1b0ef8352bcba66507d.svg"/><p>其中要求<code>DepartmentComposite</code>将描述为一种树结构，下面是部分代码实现，</p><p>Component接口，</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">AttendanceComponent</span> &#123;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">void</span> <span class="title function_">punchIn</span><span class="params">()</span>;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">void</span> <span class="title function_">punchOut</span><span class="params">()</span>;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 当日工时</span></span><br><span class="line">  <span class="type">long</span> <span class="title function_">getAttendance</span><span class="params">()</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>Leaf叶子节点，</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">EmployeeLeaf</span> <span class="keyword">implements</span> <span class="title class_">AttendanceComponent</span> &#123;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">private</span> <span class="type">long</span> <span class="variable">attendance</span> <span class="operator">=</span> <span class="number">0L</span>;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">private</span> OffsetDateTime punchInTime;</span><br><span class="line">  <span class="keyword">private</span> OffsetDateTime punchOutTime;</span><br><span class="line"></span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">punchIn</span><span class="params">()</span> &#123;</span><br><span class="line">    punchInTime = OffsetDateTime.now();</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">punchOut</span><span class="params">()</span> &#123;</span><br><span class="line">    punchOutTime = OffsetDateTime.now();</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="keyword">public</span> <span class="type">long</span> <span class="title function_">getAttendance</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="keyword">if</span> (attendance == <span class="number">0</span> &amp;&amp; (punchOutTime != <span class="literal">null</span> &amp;&amp; punchInTime != <span class="literal">null</span>)) &#123;</span><br><span class="line">      attendance = Duration.between(punchInTime, punchOutTime).toMinutes();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> attendance;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>Composite组合类，</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">DepartmentComposite</span> <span class="keyword">implements</span> <span class="title class_">AttendanceComponent</span> &#123;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">private</span> <span class="keyword">final</span> Set&lt;AttendanceComponent&gt; components = <span class="keyword">new</span> <span class="title class_">HashSet</span>&lt;&gt;();</span><br><span class="line"></span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">punchIn</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="keyword">for</span> (AttendanceComponent component : components) &#123;</span><br><span class="line">      component.punchIn();</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">punchOut</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="keyword">for</span> (AttendanceComponent component : components) &#123;</span><br><span class="line">      component.punchOut();</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="keyword">public</span> <span class="type">long</span> <span class="title function_">getAttendance</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> components.stream().mapToLong(AttendanceComponent::getAttendance).sum();</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">add</span><span class="params">(AttendanceComponent component)</span> &#123;</span><br><span class="line">    components.add(component);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">remove</span><span class="params">(AttendanceComponent component)</span> &#123;</span><br><span class="line">    components.remove(component);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="总结"><a class="header-anchor" href="#总结">¶</a>总结</h2><p><strong>组合模式(Composite Pattern)</strong> 通过继承保持了单一职责原则，通过集合操作实现了“整体-部分”的一致性操作。</p>]]></content>
    
    
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;又叫部分整体模式，是用于把一组相似的对象当作一个单一的对象。组合模式依据&lt;strong&gt;树形结构&lt;/strong&gt;来组合对象，用来表示”整体-部分“层次。这种模式使得客户端可以统一处理单个对象和组合对象，而无需关心它们的具体实现。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;img src=&quot;/assert/puml/22f0c50b3b853734516cc232fff2b8220df083e4655e5faa0b28d330d9081478.svg&quot;/&gt;</summary>
    
    
    <content src="https://galudisu.info/%3Cblockquote%3E%3Cp%3E%E5%8F%88%E5%8F%AB%E9%83%A8%E5%88%86%E6%95%B4%E4%BD%93%E6%A8%A1%E5%BC%8F%EF%BC%8C%E6%98%AF%E7%94%A8%E4%BA%8E%E6%8A%8A%E4%B8%80%E7%BB%84%E7%9B%B8%E4%BC%BC%E7%9A%84%E5%AF%B9%E8%B1%A1%E5%BD%93%E4%BD%9C%E4%B8%80%E4%B8%AA%E5%8D%95%E4%B8%80%E7%9A%84%E5%AF%B9%E8%B1%A1%E3%80%82%E7%BB%84%E5%90%88%E6%A8%A1%E5%BC%8F%E4%BE%9D%E6%8D%AE%3Cstrong%3E%E6%A0%91%E5%BD%A2%E7%BB%93%E6%9E%84%3C/strong%3E%E6%9D%A5%E7%BB%84%E5%90%88%E5%AF%B9%E8%B1%A1%EF%BC%8C%E7%94%A8%E6%9D%A5%E8%A1%A8%E7%A4%BA%E2%80%9D%E6%95%B4%E4%BD%93-%E9%83%A8%E5%88%86%E2%80%9C%E5%B1%82%E6%AC%A1%E3%80%82%E8%BF%99%E7%A7%8D%E6%A8%A1%E5%BC%8F%E4%BD%BF%E5%BE%97%E5%AE%A2%E6%88%B7%E7%AB%AF%E5%8F%AF%E4%BB%A5%E7%BB%9F%E4%B8%80%E5%A4%84%E7%90%86%E5%8D%95%E4%B8%AA%E5%AF%B9%E8%B1%A1%E5%92%8C%E7%BB%84%E5%90%88%E5%AF%B9%E8%B1%A1%EF%BC%8C%E8%80%8C%E6%97%A0%E9%9C%80%E5%85%B3%E5%BF%83%E5%AE%83%E4%BB%AC%E7%9A%84%E5%85%B7%E4%BD%93%E5%AE%9E%E7%8E%B0%E3%80%82%3C/p%3E%3C/blockquote%3E%3Cimg%20src=%22/assert/puml/22f0c50b3b853734516cc232fff2b8220df083e4655e5faa0b28d330d9081478.svg%22/%3E%3Cspan%20id=%22more%22%3E%3C/span%3E%3Ch3%20id=%22%E6%A0%B8%E5%BF%83%E8%A7%92%E8%89%B2%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E6%A0%B8%E5%BF%83%E8%A7%92%E8%89%B2%22%3E%C2%B6%3C/a%3E%E6%A0%B8%E5%BF%83%E8%A7%92%E8%89%B2%3C/h3%3E%3Ctable%3E%3Cthead%3E%3Ctr%3E%3Cth%3E%3Cstrong%3E%E8%A7%92%E8%89%B2%3C/strong%3E%3C/th%3E%3Cth%3E%3Cstrong%3E%E8%81%8C%E8%B4%A3%3C/strong%3E%3C/th%3E%3C/tr%3E%3C/thead%3E%3Ctbody%3E%3Ctr%3E%3Ctd%3EComponent%3C/td%3E%3Ctd%3E%E5%AE%9A%E4%B9%89%E6%89%80%E6%9C%89%E5%8F%B6%E5%AD%90%E5%92%8C%E7%BB%84%E5%90%88%E7%9A%84%E5%85%AC%E5%85%B1%E6%8E%A5%E5%8F%A3%EF%BC%8C%E9%80%9A%E5%B8%B8%E6%98%AF%E6%8A%BD%E8%B1%A1%E7%B1%BB%E6%88%96%E6%8E%A5%E5%8F%A3%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%3ELeaf%3C/td%3E%3Ctd%3E%E8%A1%A8%E7%A4%BA%E6%B2%A1%E6%9C%89%E5%AD%90%E8%8A%82%E7%82%B9%E7%9A%84%E5%AF%B9%E8%B1%A1%EF%BC%8C%E5%AE%9E%E7%8E%B0%E5%9F%BA%E6%9C%AC%E6%93%8D%E4%BD%9C%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%3EComposite%3C/td%3E%3Ctd%3E%E5%8C%85%E5%90%AB%E5%AD%90%E7%BB%84%E4%BB%B6%E7%9A%84%E5%AF%B9%E8%B1%A1%EF%BC%8C%E5%AE%9E%E7%8E%B0%E5%AE%B9%E5%99%A8%E8%A1%8C%E4%B8%BA%EF%BC%8C%E5%A6%82%E6%B7%BB%E5%8A%A0%E3%80%81%E5%88%A0%E9%99%A4%E5%AD%90%E7%BB%84%E4%BB%B6%E7%AD%89%3C/td%3E%3C/tr%3E%3C/tbody%3E%3C/table%3E%3Ch3%20id=%22%E9%80%82%E7%94%A8%E5%9C%BA%E6%99%AF%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E9%80%82%E7%94%A8%E5%9C%BA%E6%99%AF%22%3E%C2%B6%3C/a%3E%E9%80%82%E7%94%A8%E5%9C%BA%E6%99%AF%3C/h3%3E%3Cul%3E%3Cli%3E%E9%9C%80%E8%A6%81%E8%A1%A8%E7%A4%BA%E2%80%9C%E6%95%B4%E4%BD%93-%E9%83%A8%E5%88%86%E2%80%9D%E5%85%B3%E7%B3%BB%E7%9A%84%E7%BB%93%E6%9E%84(%E5%A6%82%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F%E7%9B%AE%E5%BD%95%E4%B8%8E%E6%96%87%E4%BB%B6%E3%80%81%E5%AD%A6%E6%A0%A1%E7%BB%84%E7%BB%87%E3%80%81%E7%AE%A1%E7%90%86%E5%B1%82%E7%BA%A7)%3C/li%3E%3Cli%3E%E5%B8%8C%E6%9C%9B%E5%AE%A2%E6%88%B7%E7%AB%AF%20%3Cem%3E%E4%BB%A5%E4%B8%80%E8%87%B4%E6%96%B9%E5%BC%8F%E5%A4%84%E7%90%86%E5%8D%95%E4%B8%AA%E5%AF%B9%E8%B1%A1%E5%92%8C%E7%BB%84%E5%90%88%E5%AF%B9%E8%B1%A1%3C/em%3E%E3%80%82%3C/li%3E%3Cli%3E%E7%BB%93%E6%9E%84%E5%85%B7%E6%9C%89%E5%B1%82%E7%BA%A7%E6%80%A7%EF%BC%8C%E5%B9%B6%E4%B8%94%E5%8F%AF%E8%83%BD%E5%8A%A8%E6%80%81%E5%8F%98%E5%8C%96%E3%80%82%3C/li%3E%3C/ul%3E%3Ch3%20id=%22%E7%9C%9F%E5%AE%9E%E6%A1%88%E4%BE%8B%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E7%9C%9F%E5%AE%9E%E6%A1%88%E4%BE%8B%22%3E%C2%B6%3C/a%3E%E7%9C%9F%E5%AE%9E%E6%A1%88%E4%BE%8B%3C/h3%3E%3Cp%3E%E5%AF%B9%E4%BA%8E%E6%9F%90OA%E7%B3%BB%E7%BB%9F%EF%BC%8C%E4%B8%AD%E7%A7%8B%E8%8A%82%E5%AE%89%E6%8E%92%E4%BA%86%E7%BB%9F%E4%B8%80%E5%81%87%E6%9C%9F%EF%BC%8C%E4%BD%86%E6%9F%90%E4%BA%9B%E9%83%A8%E9%97%A8%E4%B8%AD%E7%A7%8B%E8%8A%82%E5%BF%85%E9%A1%BB%E8%BD%AE%E7%8F%AD%EF%BC%8C%E4%BD%86%E5%8F%AF%E4%BB%A5%E8%8A%82%E5%90%8E%E8%BF%9B%E8%A1%8C%E8%B0%83%E4%BC%91%E7%94%B3%E8%AF%B7%E3%80%82%E5%8F%A6%E5%A4%96%E9%92%88%E5%AF%B9%E4%B8%AA%E5%88%AB%E4%BA%BA%E5%91%98%EF%BC%8C%E6%AF%94%E5%A6%82%E7%94%B5%E5%B7%A5%E3%80%81%E5%AE%89%E9%98%B2%E7%AD%89%E4%B8%AA%E5%88%AB%E5%AF%B9%E8%B1%A1%E9%9C%80%E8%A6%81%E6%B4%BE%E4%B8%80%E5%88%B0%E4%B8%A4%E4%B8%AA%E4%BA%BA%E7%95%99%E5%AE%88%EF%BC%8C%E5%9C%A8%E8%8A%82%E5%89%8D%E7%94%B3%E6%8A%A5%E4%BA%86%E5%9D%9A%E5%AE%88%E5%B2%97%E4%BD%8D%E7%9A%84%E5%90%8D%E5%8D%95%E5%90%8E%EF%BC%8Coffice%20boy%E5%9C%A8OA%E7%B3%BB%E7%BB%9F%E4%B8%8A%E9%80%9A%E8%BF%87%E6%8B%96%E6%8B%BD%E7%9A%84%E6%96%B9%E5%BC%8F%EF%BC%8C%E7%BB%9F%E4%B8%80%E8%B0%83%E6%95%B4%E7%9A%84%E5%86%85%E9%83%A8%E5%91%98%E5%B7%A5%E7%9A%84%E5%81%87%E6%9C%9F%E3%80%82%3C/p%3E%3Cimg%20src=%22/assert/puml/b7c3e9305ac1a7fbd7630176145966f8add3faf0604b9d280b45f1184c618df0.svg%22/%3E%3Cp%3E%E8%AE%BE%E8%AE%A1%E5%A6%82%E4%B8%8B%EF%BC%9A%3C/p%3E%3Ctable%3E%3Cthead%3E%3Ctr%3E%3Cth%3E%3Cstrong%3E%E8%A7%92%E8%89%B2%3C/strong%3E%3C/th%3E%3Cth%3E%3Cstrong%3E%E5%AE%9E%E4%BE%8B%3C/strong%3E%3C/th%3E%3Cth%3E%3Cstrong%3E%E6%8F%8F%E8%BF%B0%3C/strong%3E%3C/th%3E%3C/tr%3E%3C/thead%3E%3Ctbody%3E%3Ctr%3E%3Ctd%3EComponent%3C/td%3E%3Ctd%3EAttendanceComponent%3C/td%3E%3Ctd%3E%E8%80%83%E5%8B%A4%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%3ELeaf%3C/td%3E%3Ctd%3EEmployeeLeaf%3C/td%3E%3Ctd%3E%E5%91%98%E5%B7%A5%E4%B8%AA%E4%BA%BA%E7%9A%84%E8%80%83%E5%8B%A4%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%3EComposite%3C/td%3E%3Ctd%3EDepartmentComposite%3C/td%3E%3Ctd%3E%E6%95%B4%E4%B8%AA%E9%83%A8%E9%97%A8%E7%9A%84%E8%80%83%E5%8B%A4%3C/td%3E%3C/tr%3E%3C/tbody%3E%3C/table%3E%3Cp%3E%E7%BB%84%E5%90%88%E6%A8%A1%E5%BC%8F(Composite%20Pattern)%E5%92%8C%E4%BC%81%E4%B8%9A%E7%BA%A7%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E7%9A%84%E2%80%9C%E5%AF%B9%E8%B1%A1-%E5%85%B3%E7%B3%BB%E2%80%9D%E6%98%A0%E5%B0%84%E7%9B%B8%E5%AF%B9%E5%BA%94%EF%BC%8C%E4%BD%86%E8%BF%99%E9%87%8C%E5%8F%AA%E8%AE%A8%E8%AE%BA%E4%BB%A3%E7%A0%81%E5%B1%82%E9%9D%A2%E7%9A%84%E6%98%A0%E5%B0%84%E5%85%B3%E7%B3%BB%EF%BC%8C%E8%AE%BE%E8%AE%A1%E5%A6%82%E4%B8%8B%3C/p%3E%3Cimg%20src=%22/assert/puml/d9edde97f8418133667e001cd4e9f485cdd0389d979df1b0ef8352bcba66507d.svg%22/%3E%3Cp%3E%E5%85%B6%E4%B8%AD%E8%A6%81%E6%B1%82%3Ccode%3EDepartmentComposite%3C/code%3E%E5%B0%86%E6%8F%8F%E8%BF%B0%E4%B8%BA%E4%B8%80%E7%A7%8D%E6%A0%91%E7%BB%93%E6%9E%84%EF%BC%8C%E4%B8%8B%E9%9D%A2%E6%98%AF%E9%83%A8%E5%88%86%E4%BB%A3%E7%A0%81%E5%AE%9E%E7%8E%B0%EF%BC%8C%3C/p%3E%3Cp%3EComponent%E6%8E%A5%E5%8F%A3%EF%BC%8C%3C/p%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E8%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E9%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Einterface%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EAttendanceComponent%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EpunchIn%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EpunchOut%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22comment%22%3E/%20%E5%BD%93%E6%97%A5%E5%B7%A5%E6%97%B6%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22type%22%3Elong%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EgetAttendance%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Cp%3ELeaf%E5%8F%B6%E5%AD%90%E8%8A%82%E7%82%B9%EF%BC%8C%3C/p%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E8%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E9%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E10%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E11%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E12%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E13%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E14%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E15%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E16%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E17%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E18%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E19%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E21%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E22%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E23%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E24%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E25%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E26%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EEmployeeLeaf%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eimplements%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EAttendanceComponent%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Eprivate%3C/span%3E%20%3Cspan%20class=%22type%22%3Elong%3C/span%3E%20%3Cspan%20class=%22variable%22%3Eattendance%3C/span%3E%20%3Cspan%20class=%22operator%22%3E=%3C/span%3E%20%3Cspan%20class=%22number%22%3E0L%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Eprivate%3C/span%3E%20OffsetDateTime%20punchInTime;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Eprivate%3C/span%3E%20OffsetDateTime%20punchOutTime;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EpunchIn%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20punchInTime%20=%20OffsetDateTime.now();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EpunchOut%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20punchOutTime%20=%20OffsetDateTime.now();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22type%22%3Elong%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EgetAttendance%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Eif%3C/span%3E%20(attendance%20==%20%3Cspan%20class=%22number%22%3E0%3C/span%3E%20&amp;amp;&amp;amp;%20(punchOutTime%20!=%20%3Cspan%20class=%22literal%22%3Enull%3C/span%3E%20&amp;amp;&amp;amp;%20punchInTime%20!=%20%3Cspan%20class=%22literal%22%3Enull%3C/span%3E))%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20attendance%20=%20Duration.between(punchInTime,%20punchOutTime).toMinutes();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Ereturn%3C/span%3E%20attendance;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Cp%3EComposite%E7%BB%84%E5%90%88%E7%B1%BB%EF%BC%8C%3C/p%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E8%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E9%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E10%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E11%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E12%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E13%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E14%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E15%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E16%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E17%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E18%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E19%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E21%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E22%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E23%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E24%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E25%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E26%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E27%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E28%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E29%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E30%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E31%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EDepartmentComposite%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eimplements%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EAttendanceComponent%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Eprivate%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Efinal%3C/span%3E%20Set&amp;lt;AttendanceComponent&amp;gt;%20components%20=%20%3Cspan%20class=%22keyword%22%3Enew%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EHashSet%3C/span%3E&amp;lt;&amp;gt;();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EpunchIn%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Efor%3C/span%3E%20(AttendanceComponent%20component%20:%20components)%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20component.punchIn();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EpunchOut%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Efor%3C/span%3E%20(AttendanceComponent%20component%20:%20components)%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%20%20component.punchOut();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22type%22%3Elong%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EgetAttendance%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Ereturn%3C/span%3E%20components.stream().mapToLong(AttendanceComponent::getAttendance).sum();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Eadd%3C/span%3E%3Cspan%20class=%22params%22%3E(AttendanceComponent%20component)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20components.add(component);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Eremove%3C/span%3E%3Cspan%20class=%22params%22%3E(AttendanceComponent%20component)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20components.remove(component);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Ch2%20id=%22%E6%80%BB%E7%BB%93%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E6%80%BB%E7%BB%93%22%3E%C2%B6%3C/a%3E%E6%80%BB%E7%BB%93%3C/h2%3E%3Cp%3E%3Cstrong%3E%E7%BB%84%E5%90%88%E6%A8%A1%E5%BC%8F(Composite%20Pattern)%3C/strong%3E%20%E9%80%9A%E8%BF%87%E7%BB%A7%E6%89%BF%E4%BF%9D%E6%8C%81%E4%BA%86%E5%8D%95%E4%B8%80%E8%81%8C%E8%B4%A3%E5%8E%9F%E5%88%99%EF%BC%8C%E9%80%9A%E8%BF%87%E9%9B%86%E5%90%88%E6%93%8D%E4%BD%9C%E5%AE%9E%E7%8E%B0%E4%BA%86%E2%80%9C%E6%95%B4%E4%BD%93-%E9%83%A8%E5%88%86%E2%80%9D%E7%9A%84%E4%B8%80%E8%87%B4%E6%80%A7%E6%93%8D%E4%BD%9C%E3%80%82%3C/p%3E" type="image"/>
    
    
    
    <category term="structural" scheme="https://galudisu.info/tags/structural/"/>
    
    <category term="composite" scheme="https://galudisu.info/tags/composite/"/>
    
  </entry>
  
  <entry>
    <title>装饰器模式(Decorator Pattern)</title>
    <link href="https://galudisu.info/2025/05/10/pattern/basic/structural/Decorator/"/>
    <id>https://galudisu.info/2025/05/10/pattern/basic/structural/Decorator/</id>
    <published>2025-05-10T10:25:02.000Z</published>
    <updated>2026-04-14T19:59:34.033Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>若要扩展功能，装饰者提供了比集成更有弹性的替代方案，动态地将责任附加到对象上。</p></blockquote><img src="/assert/puml/02307d672ba01e2fed96d1b7c332747bc72a41cded1a754f25826829437fce6f.svg"/><span id="more"></span><h3 id="核心结构"><a class="header-anchor" href="#核心结构">¶</a>核心结构</h3><p><strong>装饰器模式(Decorator Pattern)</strong> 的核心在于在不修改已有实现的前提下，对其进行增强。这里体现了一个原则：<strong>类应该对扩展开放，对修改关闭</strong>。</p><h3 id="应用场景"><a class="header-anchor" href="#应用场景">¶</a>应用场景</h3><ul><li>当需要在不修改原有对象的前提下为其添加新功能时。</li><li>当子类扩展不切实际时(比如需要多个可选功能组合的情况)。</li><li>在Java IO流中大量使用了装饰器模式，例如<code>BufferedInputStream(InputStream)</code>就是对输入流的一种装饰。</li></ul><h3 id="需求"><a class="header-anchor" href="#需求">¶</a>需求</h3><p>设计游戏的装备系统，要求可以计算出每种装备在镶嵌了各种宝石后的攻击力和描述：</p><ul><li>按照要求，构建如下UML类图，其中包含装备超类<code>Equip</code>、装饰超类<code>EquipDecorator</code>、游戏属性角色如下：</li></ul><table><thead><tr><th><strong>装备</strong></th><th>红宝石(hp+)</th><th>蓝宝石(mp+)</th><th>绿宝石(sp+)</th><th>黄宝石(ak+)</th><th>紫宝石(df+)</th></tr></thead><tbody><tr><td>帽子🧢</td><td></td><td></td><td></td><td></td><td></td></tr><tr><td>上衣👔</td><td></td><td></td><td></td><td></td><td></td></tr><tr><td>护甲🧥</td><td></td><td></td><td></td><td></td><td></td></tr><tr><td>裤子👖</td><td></td><td></td><td></td><td></td><td></td></tr><tr><td>鞋子👢</td><td></td><td></td><td></td><td></td><td></td></tr><tr><td>武器🗡</td><td></td><td></td><td></td><td></td><td></td></tr></tbody></table><p>根据属性栏，设计装备属性，有攻击、敏捷、防御、hp/mp值。其中红宝石+hp，蓝宝石+mp，绿宝石+敏捷，黄宝石+攻击力，紫宝石+防御力。</p><img src="/assert/puml/581374393200909de2218f08bbc1a1f3d60f03d252d409881b8a370d3dd77b5b.svg"/><p>装饰器可以多层嵌套，例如获取得到的宝石都用在武器的加点上，</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">Equip</span> <span class="variable">levelUpWeapon</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">RedGem</span>(<span class="keyword">new</span> <span class="title class_">BlueGem</span>(<span class="keyword">new</span> <span class="title class_">YellowGem</span>(<span class="keyword">new</span> <span class="title class_">GreenGem</span>(<span class="keyword">new</span> <span class="title class_">WwaponEquip</span>()))));</span><br><span class="line"><span class="comment">// 创建剑士并穿戴该氪金武器</span></span><br><span class="line"><span class="type">Swordman</span> <span class="variable">swordman</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Swordman</span>();</span><br><span class="line">swordman.equip(levelUpWeapon);</span><br><span class="line"></span><br><span class="line">System.out.println(swordman);</span><br><span class="line"></span><br><span class="line">Swordman&#123;</span><br><span class="line">  attack=<span class="number">12</span>, </span><br><span class="line">  defense=<span class="number">0</span>, </span><br><span class="line">  speed=<span class="number">5</span>, </span><br><span class="line">  hp=<span class="number">5</span>, </span><br><span class="line">  mp=<span class="number">10</span>, </span><br><span class="line">  equipment=已装备有：🗡</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>下面是示例代码的部分实现：</p><p>被装饰的类以及其超类，</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">Equip</span> &#123;</span><br><span class="line">  EquipType <span class="title function_">getType</span><span class="params">()</span>;</span><br><span class="line">  <span class="type">int</span> <span class="title function_">attack</span><span class="params">()</span>;</span><br><span class="line">  <span class="type">int</span> <span class="title function_">speed</span><span class="params">()</span>;</span><br><span class="line">  <span class="type">int</span> <span class="title function_">defense</span><span class="params">()</span>;</span><br><span class="line">  <span class="type">int</span> <span class="title function_">hp</span><span class="params">()</span>;</span><br><span class="line">  <span class="type">int</span> <span class="title function_">mp</span><span class="params">()</span>;</span><br><span class="line">  String <span class="title function_">description</span><span class="params">()</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">WeaponEquip</span> <span class="keyword">implements</span> <span class="title class_">Equip</span> &#123;</span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="keyword">public</span> EquipType <span class="title function_">getType</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> EquipType.WEAPON;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">attack</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">speed</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">defense</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">hp</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">mp</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="keyword">public</span> String <span class="title function_">description</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="string">&quot;🗡&quot;</span>;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>实现其装饰器，可以为<code>interface</code>或<code>abstract</code>，</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="keyword">class</span> <span class="title class_">EquipDecorator</span> <span class="keyword">implements</span> <span class="title class_">Equip</span> &#123;</span><br><span class="line">  <span class="keyword">protected</span> Equip equip;</span><br><span class="line">  <span class="keyword">protected</span> <span class="title function_">EquipDecorator</span><span class="params">(Equip equip)</span> &#123;</span><br><span class="line">    <span class="built_in">this</span>.equip = equip;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">attack</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> equip.attack();</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">speed</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> equip.speed();</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">defense</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> equip.defense();</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">hp</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> equip.hp();</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">mp</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> equip.mp();</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="keyword">public</span> String <span class="title function_">description</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> equip.description();</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>按照定义，<strong>装饰器模式(decorator pattern)</strong> 在不改变已有类的前提下，对其实现增强。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">BlueGemEquipDecorator</span> <span class="keyword">extends</span> <span class="title class_">EquipDecorator</span> &#123;</span><br><span class="line">  <span class="keyword">public</span> <span class="title function_">BlueGemEquipDecorator</span><span class="params">(Equip equip)</span> &#123;</span><br><span class="line">    <span class="built_in">super</span>(equip);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">mp</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> equip.mp() + <span class="number">10</span>;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>优点</strong>：</p><ul><li>开闭原则： 不修改已有的类。</li><li>组合优于继承：更灵活，可以无限叠加</li><li>运行时可变： 可以在运行时添加或删除功能</li><li>高内聚低耦合： 每个装饰器只关注自己的增强逻辑</li></ul><h3 id="装饰器模式与代理模式的区别"><a class="header-anchor" href="#装饰器模式与代理模式的区别">¶</a>装饰器模式与代理模式的区别</h3><ol><li>目的不同： 装饰器模式是作 <strong>增强功能</strong>；代理模式则是实现 <strong>控制访问</strong>。</li><li>实现方式相同： 都是通过组合+接口一致性方式，都继承了目标的接口。</li><li>关注点不同： 装饰器模式是“添加职责”；代理模式是“封装访问“。</li><li>是否透明： 前者透明并增强；后者控制访问减少透明度</li></ol>]]></content>
    
    
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;若要扩展功能，装饰者提供了比集成更有弹性的替代方案，动态地将责任附加到对象上。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;img src=&quot;/assert/puml/02307d672ba01e2fed96d1b7c332747bc72a41cded1a754f25826829437fce6f.svg&quot;/&gt;</summary>
    
    
    <content src="https://galudisu.info/%3Cblockquote%3E%3Cp%3E%E8%8B%A5%E8%A6%81%E6%89%A9%E5%B1%95%E5%8A%9F%E8%83%BD%EF%BC%8C%E8%A3%85%E9%A5%B0%E8%80%85%E6%8F%90%E4%BE%9B%E4%BA%86%E6%AF%94%E9%9B%86%E6%88%90%E6%9B%B4%E6%9C%89%E5%BC%B9%E6%80%A7%E7%9A%84%E6%9B%BF%E4%BB%A3%E6%96%B9%E6%A1%88%EF%BC%8C%E5%8A%A8%E6%80%81%E5%9C%B0%E5%B0%86%E8%B4%A3%E4%BB%BB%E9%99%84%E5%8A%A0%E5%88%B0%E5%AF%B9%E8%B1%A1%E4%B8%8A%E3%80%82%3C/p%3E%3C/blockquote%3E%3Cimg%20src=%22/assert/puml/02307d672ba01e2fed96d1b7c332747bc72a41cded1a754f25826829437fce6f.svg%22/%3E%3Cspan%20id=%22more%22%3E%3C/span%3E%3Ch3%20id=%22%E6%A0%B8%E5%BF%83%E7%BB%93%E6%9E%84%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E6%A0%B8%E5%BF%83%E7%BB%93%E6%9E%84%22%3E%C2%B6%3C/a%3E%E6%A0%B8%E5%BF%83%E7%BB%93%E6%9E%84%3C/h3%3E%3Cp%3E%3Cstrong%3E%E8%A3%85%E9%A5%B0%E5%99%A8%E6%A8%A1%E5%BC%8F(Decorator%20Pattern)%3C/strong%3E%20%E7%9A%84%E6%A0%B8%E5%BF%83%E5%9C%A8%E4%BA%8E%E5%9C%A8%E4%B8%8D%E4%BF%AE%E6%94%B9%E5%B7%B2%E6%9C%89%E5%AE%9E%E7%8E%B0%E7%9A%84%E5%89%8D%E6%8F%90%E4%B8%8B%EF%BC%8C%E5%AF%B9%E5%85%B6%E8%BF%9B%E8%A1%8C%E5%A2%9E%E5%BC%BA%E3%80%82%E8%BF%99%E9%87%8C%E4%BD%93%E7%8E%B0%E4%BA%86%E4%B8%80%E4%B8%AA%E5%8E%9F%E5%88%99%EF%BC%9A%3Cstrong%3E%E7%B1%BB%E5%BA%94%E8%AF%A5%E5%AF%B9%E6%89%A9%E5%B1%95%E5%BC%80%E6%94%BE%EF%BC%8C%E5%AF%B9%E4%BF%AE%E6%94%B9%E5%85%B3%E9%97%AD%3C/strong%3E%E3%80%82%3C/p%3E%3Ch3%20id=%22%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF%22%3E%C2%B6%3C/a%3E%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF%3C/h3%3E%3Cul%3E%3Cli%3E%E5%BD%93%E9%9C%80%E8%A6%81%E5%9C%A8%E4%B8%8D%E4%BF%AE%E6%94%B9%E5%8E%9F%E6%9C%89%E5%AF%B9%E8%B1%A1%E7%9A%84%E5%89%8D%E6%8F%90%E4%B8%8B%E4%B8%BA%E5%85%B6%E6%B7%BB%E5%8A%A0%E6%96%B0%E5%8A%9F%E8%83%BD%E6%97%B6%E3%80%82%3C/li%3E%3Cli%3E%E5%BD%93%E5%AD%90%E7%B1%BB%E6%89%A9%E5%B1%95%E4%B8%8D%E5%88%87%E5%AE%9E%E9%99%85%E6%97%B6(%E6%AF%94%E5%A6%82%E9%9C%80%E8%A6%81%E5%A4%9A%E4%B8%AA%E5%8F%AF%E9%80%89%E5%8A%9F%E8%83%BD%E7%BB%84%E5%90%88%E7%9A%84%E6%83%85%E5%86%B5)%E3%80%82%3C/li%3E%3Cli%3E%E5%9C%A8Java%20IO%E6%B5%81%E4%B8%AD%E5%A4%A7%E9%87%8F%E4%BD%BF%E7%94%A8%E4%BA%86%E8%A3%85%E9%A5%B0%E5%99%A8%E6%A8%A1%E5%BC%8F%EF%BC%8C%E4%BE%8B%E5%A6%82%3Ccode%3EBufferedInputStream(InputStream)%3C/code%3E%E5%B0%B1%E6%98%AF%E5%AF%B9%E8%BE%93%E5%85%A5%E6%B5%81%E7%9A%84%E4%B8%80%E7%A7%8D%E8%A3%85%E9%A5%B0%E3%80%82%3C/li%3E%3C/ul%3E%3Ch3%20id=%22%E9%9C%80%E6%B1%82%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E9%9C%80%E6%B1%82%22%3E%C2%B6%3C/a%3E%E9%9C%80%E6%B1%82%3C/h3%3E%3Cp%3E%E8%AE%BE%E8%AE%A1%E6%B8%B8%E6%88%8F%E7%9A%84%E8%A3%85%E5%A4%87%E7%B3%BB%E7%BB%9F%EF%BC%8C%E8%A6%81%E6%B1%82%E5%8F%AF%E4%BB%A5%E8%AE%A1%E7%AE%97%E5%87%BA%E6%AF%8F%E7%A7%8D%E8%A3%85%E5%A4%87%E5%9C%A8%E9%95%B6%E5%B5%8C%E4%BA%86%E5%90%84%E7%A7%8D%E5%AE%9D%E7%9F%B3%E5%90%8E%E7%9A%84%E6%94%BB%E5%87%BB%E5%8A%9B%E5%92%8C%E6%8F%8F%E8%BF%B0%EF%BC%9A%3C/p%3E%3Cul%3E%3Cli%3E%E6%8C%89%E7%85%A7%E8%A6%81%E6%B1%82%EF%BC%8C%E6%9E%84%E5%BB%BA%E5%A6%82%E4%B8%8BUML%E7%B1%BB%E5%9B%BE%EF%BC%8C%E5%85%B6%E4%B8%AD%E5%8C%85%E5%90%AB%E8%A3%85%E5%A4%87%E8%B6%85%E7%B1%BB%3Ccode%3EEquip%3C/code%3E%E3%80%81%E8%A3%85%E9%A5%B0%E8%B6%85%E7%B1%BB%3Ccode%3EEquipDecorator%3C/code%3E%E3%80%81%E6%B8%B8%E6%88%8F%E5%B1%9E%E6%80%A7%E8%A7%92%E8%89%B2%E5%A6%82%E4%B8%8B%EF%BC%9A%3C/li%3E%3C/ul%3E%3Ctable%3E%3Cthead%3E%3Ctr%3E%3Cth%3E%3Cstrong%3E%E8%A3%85%E5%A4%87%3C/strong%3E%3C/th%3E%3Cth%3E%E7%BA%A2%E5%AE%9D%E7%9F%B3(hp+)%3C/th%3E%3Cth%3E%E8%93%9D%E5%AE%9D%E7%9F%B3(mp+)%3C/th%3E%3Cth%3E%E7%BB%BF%E5%AE%9D%E7%9F%B3(sp+)%3C/th%3E%3Cth%3E%E9%BB%84%E5%AE%9D%E7%9F%B3(ak+)%3C/th%3E%3Cth%3E%E7%B4%AB%E5%AE%9D%E7%9F%B3(df+)%3C/th%3E%3C/tr%3E%3C/thead%3E%3Ctbody%3E%3Ctr%3E%3Ctd%3E%E5%B8%BD%E5%AD%90%F0%9F%A7%A2%3C/td%3E%3Ctd%3E%3C/td%3E%3Ctd%3E%3C/td%3E%3Ctd%3E%3C/td%3E%3Ctd%3E%3C/td%3E%3Ctd%3E%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%3E%E4%B8%8A%E8%A1%A3%F0%9F%91%94%3C/td%3E%3Ctd%3E%3C/td%3E%3Ctd%3E%3C/td%3E%3Ctd%3E%3C/td%3E%3Ctd%3E%3C/td%3E%3Ctd%3E%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%3E%E6%8A%A4%E7%94%B2%F0%9F%A7%A5%3C/td%3E%3Ctd%3E%3C/td%3E%3Ctd%3E%3C/td%3E%3Ctd%3E%3C/td%3E%3Ctd%3E%3C/td%3E%3Ctd%3E%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%3E%E8%A3%A4%E5%AD%90%F0%9F%91%96%3C/td%3E%3Ctd%3E%3C/td%3E%3Ctd%3E%3C/td%3E%3Ctd%3E%3C/td%3E%3Ctd%3E%3C/td%3E%3Ctd%3E%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%3E%E9%9E%8B%E5%AD%90%F0%9F%91%A2%3C/td%3E%3Ctd%3E%3C/td%3E%3Ctd%3E%3C/td%3E%3Ctd%3E%3C/td%3E%3Ctd%3E%3C/td%3E%3Ctd%3E%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%3E%E6%AD%A6%E5%99%A8%F0%9F%97%A1%3C/td%3E%3Ctd%3E%3C/td%3E%3Ctd%3E%3C/td%3E%3Ctd%3E%3C/td%3E%3Ctd%3E%3C/td%3E%3Ctd%3E%3C/td%3E%3C/tr%3E%3C/tbody%3E%3C/table%3E%3Cp%3E%E6%A0%B9%E6%8D%AE%E5%B1%9E%E6%80%A7%E6%A0%8F%EF%BC%8C%E8%AE%BE%E8%AE%A1%E8%A3%85%E5%A4%87%E5%B1%9E%E6%80%A7%EF%BC%8C%E6%9C%89%E6%94%BB%E5%87%BB%E3%80%81%E6%95%8F%E6%8D%B7%E3%80%81%E9%98%B2%E5%BE%A1%E3%80%81hp/mp%E5%80%BC%E3%80%82%E5%85%B6%E4%B8%AD%E7%BA%A2%E5%AE%9D%E7%9F%B3+hp%EF%BC%8C%E8%93%9D%E5%AE%9D%E7%9F%B3+mp%EF%BC%8C%E7%BB%BF%E5%AE%9D%E7%9F%B3+%E6%95%8F%E6%8D%B7%EF%BC%8C%E9%BB%84%E5%AE%9D%E7%9F%B3+%E6%94%BB%E5%87%BB%E5%8A%9B%EF%BC%8C%E7%B4%AB%E5%AE%9D%E7%9F%B3+%E9%98%B2%E5%BE%A1%E5%8A%9B%E3%80%82%3C/p%3E%3Cimg%20src=%22/assert/puml/581374393200909de2218f08bbc1a1f3d60f03d252d409881b8a370d3dd77b5b.svg%22/%3E%3Cp%3E%E8%A3%85%E9%A5%B0%E5%99%A8%E5%8F%AF%E4%BB%A5%E5%A4%9A%E5%B1%82%E5%B5%8C%E5%A5%97%EF%BC%8C%E4%BE%8B%E5%A6%82%E8%8E%B7%E5%8F%96%E5%BE%97%E5%88%B0%E7%9A%84%E5%AE%9D%E7%9F%B3%E9%83%BD%E7%94%A8%E5%9C%A8%E6%AD%A6%E5%99%A8%E7%9A%84%E5%8A%A0%E7%82%B9%E4%B8%8A%EF%BC%8C%3C/p%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E8%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E9%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E10%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E11%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E12%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E13%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E14%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E15%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22type%22%3EEquip%3C/span%3E%20%3Cspan%20class=%22variable%22%3ElevelUpWeapon%3C/span%3E%20%3Cspan%20class=%22operator%22%3E=%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Enew%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3ERedGem%3C/span%3E(%3Cspan%20class=%22keyword%22%3Enew%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EBlueGem%3C/span%3E(%3Cspan%20class=%22keyword%22%3Enew%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EYellowGem%3C/span%3E(%3Cspan%20class=%22keyword%22%3Enew%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EGreenGem%3C/span%3E(%3Cspan%20class=%22keyword%22%3Enew%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EWwaponEquip%3C/span%3E()))));%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22comment%22%3E/%20%E5%88%9B%E5%BB%BA%E5%89%91%E5%A3%AB%E5%B9%B6%E7%A9%BF%E6%88%B4%E8%AF%A5%E6%B0%AA%E9%87%91%E6%AD%A6%E5%99%A8%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22type%22%3ESwordman%3C/span%3E%20%3Cspan%20class=%22variable%22%3Eswordman%3C/span%3E%20%3Cspan%20class=%22operator%22%3E=%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Enew%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3ESwordman%3C/span%3E();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3Eswordman.equip(levelUpWeapon);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3ESystem.out.println(swordman);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3ESwordman&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20attack=%3Cspan%20class=%22number%22%3E12%3C/span%3E,%20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20defense=%3Cspan%20class=%22number%22%3E0%3C/span%3E,%20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20speed=%3Cspan%20class=%22number%22%3E5%3C/span%3E,%20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20hp=%3Cspan%20class=%22number%22%3E5%3C/span%3E,%20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20mp=%3Cspan%20class=%22number%22%3E10%3C/span%3E,%20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20equipment=%E5%B7%B2%E8%A3%85%E5%A4%87%E6%9C%89%EF%BC%9A%F0%9F%97%A1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Cp%3E%E4%B8%8B%E9%9D%A2%E6%98%AF%E7%A4%BA%E4%BE%8B%E4%BB%A3%E7%A0%81%E7%9A%84%E9%83%A8%E5%88%86%E5%AE%9E%E7%8E%B0%EF%BC%9A%3C/p%3E%3Cp%3E%E8%A2%AB%E8%A3%85%E9%A5%B0%E7%9A%84%E7%B1%BB%E4%BB%A5%E5%8F%8A%E5%85%B6%E8%B6%85%E7%B1%BB%EF%BC%8C%3C/p%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E8%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E9%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E10%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E11%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E12%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E13%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E14%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E15%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E16%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E17%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E18%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E19%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E21%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E22%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E23%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E24%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E25%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E26%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E27%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E28%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E29%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E30%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E31%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E32%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E33%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E34%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E35%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E36%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E37%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E38%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E39%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E40%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Einterface%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EEquip%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20EquipType%20%3Cspan%20class=%22title%20function_%22%3EgetType%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22type%22%3Eint%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Eattack%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22type%22%3Eint%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Espeed%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22type%22%3Eint%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Edefense%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22type%22%3Eint%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Ehp%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22type%22%3Eint%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Emp%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20String%20%3Cspan%20class=%22title%20function_%22%3Edescription%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EWeaponEquip%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eimplements%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EEquip%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20EquipType%20%3Cspan%20class=%22title%20function_%22%3EgetType%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Ereturn%3C/span%3E%20EquipType.WEAPON;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22type%22%3Eint%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Eattack%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Ereturn%3C/span%3E%20%3Cspan%20class=%22number%22%3E0%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22type%22%3Eint%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Espeed%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Ereturn%3C/span%3E%20%3Cspan%20class=%22number%22%3E0%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22type%22%3Eint%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Edefense%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Ereturn%3C/span%3E%20%3Cspan%20class=%22number%22%3E0%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22type%22%3Eint%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Ehp%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Ereturn%3C/span%3E%20%3Cspan%20class=%22number%22%3E0%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22type%22%3Eint%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Emp%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Ereturn%3C/span%3E%20%3Cspan%20class=%22number%22%3E0%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20String%20%3Cspan%20class=%22title%20function_%22%3Edescription%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Ereturn%3C/span%3E%20%3Cspan%20class=%22string%22%3E&amp;quot;%F0%9F%97%A1&amp;quot;%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Cp%3E%E5%AE%9E%E7%8E%B0%E5%85%B6%E8%A3%85%E9%A5%B0%E5%99%A8%EF%BC%8C%E5%8F%AF%E4%BB%A5%E4%B8%BA%3Ccode%3Einterface%3C/code%3E%E6%88%96%3Ccode%3Eabstract%3C/code%3E%EF%BC%8C%3C/p%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E8%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E9%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E10%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E11%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E12%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E13%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E14%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E15%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E16%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E17%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E18%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E19%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E21%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E22%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E23%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E24%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E25%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E26%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E27%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E28%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E29%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E30%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eabstract%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EEquipDecorator%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eimplements%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EEquip%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Eprotected%3C/span%3E%20Equip%20equip;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Eprotected%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EEquipDecorator%3C/span%3E%3Cspan%20class=%22params%22%3E(Equip%20equip)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22built_in%22%3Ethis%3C/span%3E.equip%20=%20equip;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22type%22%3Eint%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Eattack%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Ereturn%3C/span%3E%20equip.attack();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22type%22%3Eint%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Espeed%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Ereturn%3C/span%3E%20equip.speed();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22type%22%3Eint%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Edefense%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Ereturn%3C/span%3E%20equip.defense();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22type%22%3Eint%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Ehp%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Ereturn%3C/span%3E%20equip.hp();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22type%22%3Eint%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Emp%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Ereturn%3C/span%3E%20equip.mp();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20String%20%3Cspan%20class=%22title%20function_%22%3Edescription%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Ereturn%3C/span%3E%20equip.description();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Cp%3E%E6%8C%89%E7%85%A7%E5%AE%9A%E4%B9%89%EF%BC%8C%3Cstrong%3E%E8%A3%85%E9%A5%B0%E5%99%A8%E6%A8%A1%E5%BC%8F(decorator%20pattern)%3C/strong%3E%20%E5%9C%A8%E4%B8%8D%E6%94%B9%E5%8F%98%E5%B7%B2%E6%9C%89%E7%B1%BB%E7%9A%84%E5%89%8D%E6%8F%90%E4%B8%8B%EF%BC%8C%E5%AF%B9%E5%85%B6%E5%AE%9E%E7%8E%B0%E5%A2%9E%E5%BC%BA%E3%80%82%3C/p%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E8%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E9%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EBlueGemEquipDecorator%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eextends%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EEquipDecorator%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EBlueGemEquipDecorator%3C/span%3E%3Cspan%20class=%22params%22%3E(Equip%20equip)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22built_in%22%3Esuper%3C/span%3E(equip);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22type%22%3Eint%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Emp%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22keyword%22%3Ereturn%3C/span%3E%20equip.mp()%20+%20%3Cspan%20class=%22number%22%3E10%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Cp%3E%3Cstrong%3E%E4%BC%98%E7%82%B9%3C/strong%3E%EF%BC%9A%3C/p%3E%3Cul%3E%3Cli%3E%E5%BC%80%E9%97%AD%E5%8E%9F%E5%88%99%EF%BC%9A%20%E4%B8%8D%E4%BF%AE%E6%94%B9%E5%B7%B2%E6%9C%89%E7%9A%84%E7%B1%BB%E3%80%82%3C/li%3E%3Cli%3E%E7%BB%84%E5%90%88%E4%BC%98%E4%BA%8E%E7%BB%A7%E6%89%BF%EF%BC%9A%E6%9B%B4%E7%81%B5%E6%B4%BB%EF%BC%8C%E5%8F%AF%E4%BB%A5%E6%97%A0%E9%99%90%E5%8F%A0%E5%8A%A0%3C/li%3E%3Cli%3E%E8%BF%90%E8%A1%8C%E6%97%B6%E5%8F%AF%E5%8F%98%EF%BC%9A%20%E5%8F%AF%E4%BB%A5%E5%9C%A8%E8%BF%90%E8%A1%8C%E6%97%B6%E6%B7%BB%E5%8A%A0%E6%88%96%E5%88%A0%E9%99%A4%E5%8A%9F%E8%83%BD%3C/li%3E%3Cli%3E%E9%AB%98%E5%86%85%E8%81%9A%E4%BD%8E%E8%80%A6%E5%90%88%EF%BC%9A%20%E6%AF%8F%E4%B8%AA%E8%A3%85%E9%A5%B0%E5%99%A8%E5%8F%AA%E5%85%B3%E6%B3%A8%E8%87%AA%E5%B7%B1%E7%9A%84%E5%A2%9E%E5%BC%BA%E9%80%BB%E8%BE%91%3C/li%3E%3C/ul%3E%3Ch3%20id=%22%E8%A3%85%E9%A5%B0%E5%99%A8%E6%A8%A1%E5%BC%8F%E4%B8%8E%E4%BB%A3%E7%90%86%E6%A8%A1%E5%BC%8F%E7%9A%84%E5%8C%BA%E5%88%AB%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E8%A3%85%E9%A5%B0%E5%99%A8%E6%A8%A1%E5%BC%8F%E4%B8%8E%E4%BB%A3%E7%90%86%E6%A8%A1%E5%BC%8F%E7%9A%84%E5%8C%BA%E5%88%AB%22%3E%C2%B6%3C/a%3E%E8%A3%85%E9%A5%B0%E5%99%A8%E6%A8%A1%E5%BC%8F%E4%B8%8E%E4%BB%A3%E7%90%86%E6%A8%A1%E5%BC%8F%E7%9A%84%E5%8C%BA%E5%88%AB%3C/h3%3E%3Col%3E%3Cli%3E%E7%9B%AE%E7%9A%84%E4%B8%8D%E5%90%8C%EF%BC%9A%20%E8%A3%85%E9%A5%B0%E5%99%A8%E6%A8%A1%E5%BC%8F%E6%98%AF%E4%BD%9C%20%3Cstrong%3E%E5%A2%9E%E5%BC%BA%E5%8A%9F%E8%83%BD%3C/strong%3E%EF%BC%9B%E4%BB%A3%E7%90%86%E6%A8%A1%E5%BC%8F%E5%88%99%E6%98%AF%E5%AE%9E%E7%8E%B0%20%3Cstrong%3E%E6%8E%A7%E5%88%B6%E8%AE%BF%E9%97%AE%3C/strong%3E%E3%80%82%3C/li%3E%3Cli%3E%E5%AE%9E%E7%8E%B0%E6%96%B9%E5%BC%8F%E7%9B%B8%E5%90%8C%EF%BC%9A%20%E9%83%BD%E6%98%AF%E9%80%9A%E8%BF%87%E7%BB%84%E5%90%88+%E6%8E%A5%E5%8F%A3%E4%B8%80%E8%87%B4%E6%80%A7%E6%96%B9%E5%BC%8F%EF%BC%8C%E9%83%BD%E7%BB%A7%E6%89%BF%E4%BA%86%E7%9B%AE%E6%A0%87%E7%9A%84%E6%8E%A5%E5%8F%A3%E3%80%82%3C/li%3E%3Cli%3E%E5%85%B3%E6%B3%A8%E7%82%B9%E4%B8%8D%E5%90%8C%EF%BC%9A%20%E8%A3%85%E9%A5%B0%E5%99%A8%E6%A8%A1%E5%BC%8F%E6%98%AF%E2%80%9C%E6%B7%BB%E5%8A%A0%E8%81%8C%E8%B4%A3%E2%80%9D%EF%BC%9B%E4%BB%A3%E7%90%86%E6%A8%A1%E5%BC%8F%E6%98%AF%E2%80%9C%E5%B0%81%E8%A3%85%E8%AE%BF%E9%97%AE%E2%80%9C%E3%80%82%3C/li%3E%3Cli%3E%E6%98%AF%E5%90%A6%E9%80%8F%E6%98%8E%EF%BC%9A%20%E5%89%8D%E8%80%85%E9%80%8F%E6%98%8E%E5%B9%B6%E5%A2%9E%E5%BC%BA%EF%BC%9B%E5%90%8E%E8%80%85%E6%8E%A7%E5%88%B6%E8%AE%BF%E9%97%AE%E5%87%8F%E5%B0%91%E9%80%8F%E6%98%8E%E5%BA%A6%3C/li%3E%3C/ol%3E" type="image"/>
    
    
    
    <category term="structural" scheme="https://galudisu.info/tags/structural/"/>
    
    <category term="decorator" scheme="https://galudisu.info/tags/decorator/"/>
    
  </entry>
  
  <entry>
    <title>桥接模式(Bridge Pattern)</title>
    <link href="https://galudisu.info/2025/05/10/pattern/basic/structural/Bridge/"/>
    <id>https://galudisu.info/2025/05/10/pattern/basic/structural/Bridge/</id>
    <published>2025-05-10T10:25:01.000Z</published>
    <updated>2026-04-14T19:59:34.127Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>桥接(Bridge)是<strong>用于把抽象化与实现化解耦</strong>，使得二者可以独立变化。</p></blockquote><img src="/assert/puml/1c7fc28bdf3d3ce828d3a8e69309891daa6330aac3660ea3088ed78c46f2b8c6.svg"/><span id="more"></span><h3 id="适用场景"><a class="header-anchor" href="#适用场景">¶</a>适用场景</h3><p>有多种可能变化的情况下，用继承会造成类爆炸问题，扩展起来不灵活。例如一个类存在两个维度，一个维度可以扩展为2个维度，一个维度可以扩展为3个维度，排列组合后就是2x3个实例。</p><p>以画图为例，要实现一个画图工具，假设可以画圆和矩形，也可以给其进行颜色填充。按照定义，抽象和实现必须分开，</p><ul><li><strong>抽象维度</strong>： 图形(圆、矩形、正方形)</li><li><strong>实现维度</strong>： 颜色(红、绿、蓝)</li></ul><img src="/assert/puml/9b2f07da92406fbd677399c71c6721fd7eb526cf336b4cf135bf322b116c6e4b.svg"/><p>定义不同的颜色，</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">Color</span> &#123;</span><br><span class="line">  <span class="keyword">void</span> <span class="title function_">fill</span><span class="params">()</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Red</span> <span class="keyword">implements</span> <span class="title class_">Color</span> &#123;</span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">fill</span><span class="params">()</span> &#123;</span><br><span class="line">    System.out.println(<span class="string">&quot;fillin red&quot;</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Blue</span> <span class="keyword">implements</span> <span class="title class_">Color</span> &#123;</span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">fill</span><span class="params">()</span> &#123;</span><br><span class="line">    System.out.println(<span class="string">&quot;fillin blue&quot;</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Green</span> <span class="keyword">implements</span> <span class="title class_">Color</span> &#123;</span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">fill</span><span class="params">()</span> &#123;</span><br><span class="line">    System.out.println(<span class="string">&quot;fillin green&quot;</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>定义桥接类，</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="keyword">class</span> <span class="title class_">Shape</span> &#123;</span><br><span class="line">  <span class="keyword">protected</span> Color color;</span><br><span class="line">  </span><br><span class="line">  <span class="keyword">protected</span> <span class="title function_">Shape</span><span class="params">(Color color)</span> &#123;</span><br><span class="line">    <span class="built_in">this</span>.color = color;</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">abstract</span> <span class="keyword">void</span> <span class="title function_">draw</span><span class="params">()</span>;  <span class="comment">// <i class="conum" data-value="1"></i></span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><i class="conum" data-value="1"></i> 分离实现</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Circle</span> <span class="keyword">extends</span> <span class="title class_">Shape</span> &#123;</span><br><span class="line">  <span class="keyword">public</span> <span class="title function_">Circle</span><span class="params">(Color color)</span> &#123;</span><br><span class="line">    <span class="built_in">super</span>(color);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">draw</span><span class="params">()</span> &#123;</span><br><span class="line">    System.out.println(<span class="string">&quot;Circle -&gt;&quot;</span>);</span><br><span class="line">    color.fill();</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Rectangle</span> <span class="keyword">extends</span> <span class="title class_">Shape</span> &#123;</span><br><span class="line">  <span class="keyword">public</span> <span class="title function_">Rectangle</span><span class="params">(Color color)</span> &#123;</span><br><span class="line">    <span class="built_in">super</span>(color);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">draw</span><span class="params">()</span> &#123;</span><br><span class="line">    System.out.println(<span class="string">&quot;Rectangle -&gt;&quot;</span>);</span><br><span class="line">    color.fill();</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Square</span> <span class="keyword">extends</span> <span class="title class_">Shape</span> &#123;</span><br><span class="line">  <span class="keyword">public</span> <span class="title function_">Square</span><span class="params">(Color color)</span> &#123;</span><br><span class="line">    <span class="built_in">super</span>(color);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="meta">@Override</span></span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">draw</span><span class="params">()</span> &#123;</span><br><span class="line">    System.out.println(<span class="string">&quot;Square -&gt;&quot;</span>);</span><br><span class="line">    color.fill();</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>按需所取，</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Client</span> &#123;</span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">    <span class="type">Shape</span> <span class="variable">redCircle</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Circle</span>(<span class="keyword">new</span> <span class="title class_">Red</span>());</span><br><span class="line">    <span class="type">Shape</span> <span class="variable">blueRectangle</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Rectangle</span>(<span class="keyword">new</span> <span class="title class_">Blue</span>());</span><br><span class="line">    <span class="type">Shape</span> <span class="variable">greenSquare</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Square</span>(<span class="keyword">new</span> <span class="title class_">Green</span>());</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="总结"><a class="header-anchor" href="#总结">¶</a>总结</h2><p>桥接模式的核心特征是<strong>两个独立变化的维度</strong></p><blockquote><p>🔵<strong>抽象部分(Abstraction)</strong> 和 🔵<strong>实现部分(Implementor)</strong> 可以各自独立扩展，互不干扰。</p></blockquote><table><thead><tr><th>维度</th><th>描述</th></tr></thead><tbody><tr><td>抽象部分</td><td>定义高层操作，通常是一个类或接口，它包含对实现部分的引用</td></tr><tr><td>实现部分</td><td>定义地层行为，通常是接口或抽象类，用于被多个抽象类组合使用</td></tr></tbody></table><p>口诀：</p><blockquote><p>“一个类里由一个接口变量，并且这个接口决定了它的底层实现”</p></blockquote>]]></content>
    
    
    <summary type="html">&lt;blockquote&gt;
&lt;p&gt;桥接(Bridge)是&lt;strong&gt;用于把抽象化与实现化解耦&lt;/strong&gt;，使得二者可以独立变化。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;img src=&quot;/assert/puml/1c7fc28bdf3d3ce828d3a8e69309891daa6330aac3660ea3088ed78c46f2b8c6.svg&quot;/&gt;</summary>
    
    
    <content src="https://galudisu.info/%3Cblockquote%3E%3Cp%3E%E6%A1%A5%E6%8E%A5(Bridge)%E6%98%AF%3Cstrong%3E%E7%94%A8%E4%BA%8E%E6%8A%8A%E6%8A%BD%E8%B1%A1%E5%8C%96%E4%B8%8E%E5%AE%9E%E7%8E%B0%E5%8C%96%E8%A7%A3%E8%80%A6%3C/strong%3E%EF%BC%8C%E4%BD%BF%E5%BE%97%E4%BA%8C%E8%80%85%E5%8F%AF%E4%BB%A5%E7%8B%AC%E7%AB%8B%E5%8F%98%E5%8C%96%E3%80%82%3C/p%3E%3C/blockquote%3E%3Cimg%20src=%22/assert/puml/1c7fc28bdf3d3ce828d3a8e69309891daa6330aac3660ea3088ed78c46f2b8c6.svg%22/%3E%3Cspan%20id=%22more%22%3E%3C/span%3E%3Ch3%20id=%22%E9%80%82%E7%94%A8%E5%9C%BA%E6%99%AF%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E9%80%82%E7%94%A8%E5%9C%BA%E6%99%AF%22%3E%C2%B6%3C/a%3E%E9%80%82%E7%94%A8%E5%9C%BA%E6%99%AF%3C/h3%3E%3Cp%3E%E6%9C%89%E5%A4%9A%E7%A7%8D%E5%8F%AF%E8%83%BD%E5%8F%98%E5%8C%96%E7%9A%84%E6%83%85%E5%86%B5%E4%B8%8B%EF%BC%8C%E7%94%A8%E7%BB%A7%E6%89%BF%E4%BC%9A%E9%80%A0%E6%88%90%E7%B1%BB%E7%88%86%E7%82%B8%E9%97%AE%E9%A2%98%EF%BC%8C%E6%89%A9%E5%B1%95%E8%B5%B7%E6%9D%A5%E4%B8%8D%E7%81%B5%E6%B4%BB%E3%80%82%E4%BE%8B%E5%A6%82%E4%B8%80%E4%B8%AA%E7%B1%BB%E5%AD%98%E5%9C%A8%E4%B8%A4%E4%B8%AA%E7%BB%B4%E5%BA%A6%EF%BC%8C%E4%B8%80%E4%B8%AA%E7%BB%B4%E5%BA%A6%E5%8F%AF%E4%BB%A5%E6%89%A9%E5%B1%95%E4%B8%BA2%E4%B8%AA%E7%BB%B4%E5%BA%A6%EF%BC%8C%E4%B8%80%E4%B8%AA%E7%BB%B4%E5%BA%A6%E5%8F%AF%E4%BB%A5%E6%89%A9%E5%B1%95%E4%B8%BA3%E4%B8%AA%E7%BB%B4%E5%BA%A6%EF%BC%8C%E6%8E%92%E5%88%97%E7%BB%84%E5%90%88%E5%90%8E%E5%B0%B1%E6%98%AF2x3%E4%B8%AA%E5%AE%9E%E4%BE%8B%E3%80%82%3C/p%3E%3Cp%3E%E4%BB%A5%E7%94%BB%E5%9B%BE%E4%B8%BA%E4%BE%8B%EF%BC%8C%E8%A6%81%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E7%94%BB%E5%9B%BE%E5%B7%A5%E5%85%B7%EF%BC%8C%E5%81%87%E8%AE%BE%E5%8F%AF%E4%BB%A5%E7%94%BB%E5%9C%86%E5%92%8C%E7%9F%A9%E5%BD%A2%EF%BC%8C%E4%B9%9F%E5%8F%AF%E4%BB%A5%E7%BB%99%E5%85%B6%E8%BF%9B%E8%A1%8C%E9%A2%9C%E8%89%B2%E5%A1%AB%E5%85%85%E3%80%82%E6%8C%89%E7%85%A7%E5%AE%9A%E4%B9%89%EF%BC%8C%E6%8A%BD%E8%B1%A1%E5%92%8C%E5%AE%9E%E7%8E%B0%E5%BF%85%E9%A1%BB%E5%88%86%E5%BC%80%EF%BC%8C%3C/p%3E%3Cul%3E%3Cli%3E%3Cstrong%3E%E6%8A%BD%E8%B1%A1%E7%BB%B4%E5%BA%A6%3C/strong%3E%EF%BC%9A%20%E5%9B%BE%E5%BD%A2(%E5%9C%86%E3%80%81%E7%9F%A9%E5%BD%A2%E3%80%81%E6%AD%A3%E6%96%B9%E5%BD%A2)%3C/li%3E%3Cli%3E%3Cstrong%3E%E5%AE%9E%E7%8E%B0%E7%BB%B4%E5%BA%A6%3C/strong%3E%EF%BC%9A%20%E9%A2%9C%E8%89%B2(%E7%BA%A2%E3%80%81%E7%BB%BF%E3%80%81%E8%93%9D)%3C/li%3E%3C/ul%3E%3Cimg%20src=%22/assert/puml/9b2f07da92406fbd677399c71c6721fd7eb526cf336b4cf135bf322b116c6e4b.svg%22/%3E%3Cp%3E%E5%AE%9A%E4%B9%89%E4%B8%8D%E5%90%8C%E7%9A%84%E9%A2%9C%E8%89%B2%EF%BC%8C%3C/p%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E8%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E9%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E10%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E11%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E12%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E13%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E14%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E15%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E16%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E17%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E18%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E19%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E21%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Einterface%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EColor%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Efill%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3ERed%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eimplements%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EColor%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Efill%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20System.out.println(%3Cspan%20class=%22string%22%3E&amp;quot;fillin%20red&amp;quot;%3C/span%3E);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EBlue%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eimplements%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EColor%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Efill%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20System.out.println(%3Cspan%20class=%22string%22%3E&amp;quot;fillin%20blue&amp;quot;%3C/span%3E);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EGreen%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eimplements%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EColor%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Efill%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20System.out.println(%3Cspan%20class=%22string%22%3E&amp;quot;fillin%20green&amp;quot;%3C/span%3E);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Cp%3E%E5%AE%9A%E4%B9%89%E6%A1%A5%E6%8E%A5%E7%B1%BB%EF%BC%8C%3C/p%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E8%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E9%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eabstract%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EShape%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Eprotected%3C/span%3E%20Color%20color;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Eprotected%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3EShape%3C/span%3E%3Cspan%20class=%22params%22%3E(Color%20color)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22built_in%22%3Ethis%3C/span%3E.color%20=%20color;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eabstract%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Edraw%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E;%20%20%3Cspan%20class=%22comment%22%3E/%20%3Ci%20class=%22conum%22%20data-value=%221%22%3E%3C/i%3E%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Cp%3E%3Ci%20class=%22conum%22%20data-value=%221%22%3E%3C/i%3E%20%E5%88%86%E7%A6%BB%E5%AE%9E%E7%8E%B0%3C/p%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E8%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E9%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E10%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E11%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E12%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E13%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E14%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E15%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E16%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E17%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E18%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E19%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E20%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E21%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E22%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E23%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E24%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E25%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E26%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E27%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E28%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E29%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E30%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3ECircle%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eextends%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EShape%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3ECircle%3C/span%3E%3Cspan%20class=%22params%22%3E(Color%20color)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22built_in%22%3Esuper%3C/span%3E(color);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Edraw%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20System.out.println(%3Cspan%20class=%22string%22%3E&amp;quot;Circle%20-&amp;gt;&amp;quot;%3C/span%3E);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20color.fill();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3ERectangle%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eextends%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EShape%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3ERectangle%3C/span%3E%3Cspan%20class=%22params%22%3E(Color%20color)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22built_in%22%3Esuper%3C/span%3E(color);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Edraw%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20System.out.println(%3Cspan%20class=%22string%22%3E&amp;quot;Rectangle%20-&amp;gt;&amp;quot;%3C/span%3E);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20color.fill();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3ESquare%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eextends%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EShape%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3ESquare%3C/span%3E%3Cspan%20class=%22params%22%3E(Color%20color)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22built_in%22%3Esuper%3C/span%3E(color);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22meta%22%3E@Override%3C/span%3E%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Edraw%3C/span%3E%3Cspan%20class=%22params%22%3E()%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20System.out.println(%3Cspan%20class=%22string%22%3E&amp;quot;Square%20-&amp;gt;&amp;quot;%3C/span%3E);%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20color.fill();%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Cp%3E%E6%8C%89%E9%9C%80%E6%89%80%E5%8F%96%EF%BC%8C%3C/p%3E%3Cfigure%20class=%22highlight%20java%22%3E%3Ctable%3E%3Ctr%3E%3Ctd%20class=%22gutter%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E1%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E2%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E3%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E4%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E5%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E6%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E7%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3Ctd%20class=%22code%22%3E%3Cpre%3E%3Cspan%20class=%22line%22%3E%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Eclass%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EClient%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%3Cspan%20class=%22keyword%22%3Epublic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Estatic%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Evoid%3C/span%3E%20%3Cspan%20class=%22title%20function_%22%3Emain%3C/span%3E%3Cspan%20class=%22params%22%3E(String[]%20args)%3C/span%3E%20&amp;#123;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22type%22%3EShape%3C/span%3E%20%3Cspan%20class=%22variable%22%3EredCircle%3C/span%3E%20%3Cspan%20class=%22operator%22%3E=%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Enew%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3ECircle%3C/span%3E(%3Cspan%20class=%22keyword%22%3Enew%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3ERed%3C/span%3E());%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22type%22%3EShape%3C/span%3E%20%3Cspan%20class=%22variable%22%3EblueRectangle%3C/span%3E%20%3Cspan%20class=%22operator%22%3E=%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Enew%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3ERectangle%3C/span%3E(%3Cspan%20class=%22keyword%22%3Enew%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EBlue%3C/span%3E());%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20%20%20%3Cspan%20class=%22type%22%3EShape%3C/span%3E%20%3Cspan%20class=%22variable%22%3EgreenSquare%3C/span%3E%20%3Cspan%20class=%22operator%22%3E=%3C/span%3E%20%3Cspan%20class=%22keyword%22%3Enew%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3ESquare%3C/span%3E(%3Cspan%20class=%22keyword%22%3Enew%3C/span%3E%20%3Cspan%20class=%22title%20class_%22%3EGreen%3C/span%3E());%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E%20%20&amp;#125;%3C/span%3E%3Cbr%3E%3Cspan%20class=%22line%22%3E&amp;#125;%3C/span%3E%3Cbr%3E%3C/pre%3E%3C/td%3E%3C/tr%3E%3C/table%3E%3C/figure%3E%3Ch2%20id=%22%E6%80%BB%E7%BB%93%22%3E%3Ca%20class=%22header-anchor%22%20href=%22#%E6%80%BB%E7%BB%93%22%3E%C2%B6%3C/a%3E%E6%80%BB%E7%BB%93%3C/h2%3E%3Cp%3E%E6%A1%A5%E6%8E%A5%E6%A8%A1%E5%BC%8F%E7%9A%84%E6%A0%B8%E5%BF%83%E7%89%B9%E5%BE%81%E6%98%AF%3Cstrong%3E%E4%B8%A4%E4%B8%AA%E7%8B%AC%E7%AB%8B%E5%8F%98%E5%8C%96%E7%9A%84%E7%BB%B4%E5%BA%A6%3C/strong%3E%3C/p%3E%3Cblockquote%3E%3Cp%3E%F0%9F%94%B5%3Cstrong%3E%E6%8A%BD%E8%B1%A1%E9%83%A8%E5%88%86(Abstraction)%3C/strong%3E%20%E5%92%8C%20%F0%9F%94%B5%3Cstrong%3E%E5%AE%9E%E7%8E%B0%E9%83%A8%E5%88%86(Implementor)%3C/strong%3E%20%E5%8F%AF%E4%BB%A5%E5%90%84%E8%87%AA%E7%8B%AC%E7%AB%8B%E6%89%A9%E5%B1%95%EF%BC%8C%E4%BA%92%E4%B8%8D%E5%B9%B2%E6%89%B0%E3%80%82%3C/p%3E%3C/blockquote%3E%3Ctable%3E%3Cthead%3E%3Ctr%3E%3Cth%3E%E7%BB%B4%E5%BA%A6%3C/th%3E%3Cth%3E%E6%8F%8F%E8%BF%B0%3C/th%3E%3C/tr%3E%3C/thead%3E%3Ctbody%3E%3Ctr%3E%3Ctd%3E%E6%8A%BD%E8%B1%A1%E9%83%A8%E5%88%86%3C/td%3E%3Ctd%3E%E5%AE%9A%E4%B9%89%E9%AB%98%E5%B1%82%E6%93%8D%E4%BD%9C%EF%BC%8C%E9%80%9A%E5%B8%B8%E6%98%AF%E4%B8%80%E4%B8%AA%E7%B1%BB%E6%88%96%E6%8E%A5%E5%8F%A3%EF%BC%8C%E5%AE%83%E5%8C%85%E5%90%AB%E5%AF%B9%E5%AE%9E%E7%8E%B0%E9%83%A8%E5%88%86%E7%9A%84%E5%BC%95%E7%94%A8%3C/td%3E%3C/tr%3E%3Ctr%3E%3Ctd%3E%E5%AE%9E%E7%8E%B0%E9%83%A8%E5%88%86%3C/td%3E%3Ctd%3E%E5%AE%9A%E4%B9%89%E5%9C%B0%E5%B1%82%E8%A1%8C%E4%B8%BA%EF%BC%8C%E9%80%9A%E5%B8%B8%E6%98%AF%E6%8E%A5%E5%8F%A3%E6%88%96%E6%8A%BD%E8%B1%A1%E7%B1%BB%EF%BC%8C%E7%94%A8%E4%BA%8E%E8%A2%AB%E5%A4%9A%E4%B8%AA%E6%8A%BD%E8%B1%A1%E7%B1%BB%E7%BB%84%E5%90%88%E4%BD%BF%E7%94%A8%3C/td%3E%3C/tr%3E%3C/tbody%3E%3C/table%3E%3Cp%3E%E5%8F%A3%E8%AF%80%EF%BC%9A%3C/p%3E%3Cblockquote%3E%3Cp%3E%E2%80%9C%E4%B8%80%E4%B8%AA%E7%B1%BB%E9%87%8C%E7%94%B1%E4%B8%80%E4%B8%AA%E6%8E%A5%E5%8F%A3%E5%8F%98%E9%87%8F%EF%BC%8C%E5%B9%B6%E4%B8%94%E8%BF%99%E4%B8%AA%E6%8E%A5%E5%8F%A3%E5%86%B3%E5%AE%9A%E4%BA%86%E5%AE%83%E7%9A%84%E5%BA%95%E5%B1%82%E5%AE%9E%E7%8E%B0%E2%80%9D%3C/p%3E%3C/blockquote%3E" type="image"/>
    
    
    
    <category term="structural" scheme="https://galudisu.info/tags/structural/"/>
    
    <category term="bridge" scheme="https://galudisu.info/tags/bridge/"/>
    
  </entry>
  
</feed>
