<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://zengl.dev/feed.xml" rel="self" type="application/atom+xml" /><link href="https://zengl.dev/" rel="alternate" type="text/html" /><updated>2026-02-05T06:10:10+00:00</updated><id>https://zengl.dev/feed.xml</id><title type="html">Zeng Liang</title><subtitle>A software developer crafting fast, native tools for Apple platforms and the web</subtitle><author><name>Zeng Liang</name></author><entry xml:lang="en"><title type="html">Complete macOS Release History and Versions (2025 Update)</title><link href="https://zengl.dev/blog/macos-releases.html" rel="alternate" type="text/html" title="Complete macOS Release History and Versions (2025 Update)" /><published>2025-11-20T00:00:00+00:00</published><updated>2025-11-20T00:00:00+00:00</updated><id>https://zengl.dev/blog/macos-releases</id><content type="html" xml:base="https://zengl.dev/blog/macos-releases.html"><![CDATA[<p>I’m still using an Intel Mac on macOS 13 and 14 because I prefer a
stable system rather than upgrading to the latest release every year. I
only upgrade macOS when my work absolutely requires it — not for new
features. To help myself choose the most suitable version when an
upgrade becomes necessary, I keep a list of macOS releases and their
dates as a reference.</p>

<table>
  <thead>
    <tr>
      <th>Year</th>
      <th>Version</th>
      <th>Codename</th>
      <th>Release Date</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>2025</td>
      <td>macOS 26</td>
      <td>Tahoe</td>
      <td>15/09/2025</td>
    </tr>
    <tr>
      <td>2025</td>
      <td>macOS 15</td>
      <td>Sequoia</td>
      <td>16/09/2024</td>
    </tr>
    <tr>
      <td>2024</td>
      <td>macOS 14</td>
      <td>Sonoma</td>
      <td>26/09/2023</td>
    </tr>
    <tr>
      <td>2023</td>
      <td>macOS 13</td>
      <td>Ventura</td>
      <td>24/10/2022</td>
    </tr>
    <tr>
      <td>2022</td>
      <td>macOS 12</td>
      <td>Monterey</td>
      <td>25/10/2021</td>
    </tr>
    <tr>
      <td>2021</td>
      <td>macOS 11</td>
      <td>Big Sur</td>
      <td>12/11/2020</td>
    </tr>
    <tr>
      <td>2020</td>
      <td>macOS 10.15</td>
      <td>Catalina</td>
      <td>07/10/2019</td>
    </tr>
    <tr>
      <td>2019</td>
      <td>macOS 10.14</td>
      <td>Mojave</td>
      <td>24/09/2018</td>
    </tr>
    <tr>
      <td>2018</td>
      <td>macOS 10.13</td>
      <td>High Sierra</td>
      <td>25/09/2017</td>
    </tr>
    <tr>
      <td>2017</td>
      <td>macOS 10.12</td>
      <td>Sierra</td>
      <td>20/09/2016</td>
    </tr>
    <tr>
      <td>2016</td>
      <td>OS X 10.11</td>
      <td>El Capitan</td>
      <td>30/09/2015</td>
    </tr>
    <tr>
      <td>2015</td>
      <td>OS X 10.10</td>
      <td>Yosemite</td>
      <td>16/10/2014</td>
    </tr>
    <tr>
      <td>2014</td>
      <td>OS X 10.9</td>
      <td>Mavericks</td>
      <td>22/10/2013</td>
    </tr>
    <tr>
      <td>2013</td>
      <td>OS X 10.8</td>
      <td>Mountain Lion</td>
      <td>25/07/2012</td>
    </tr>
    <tr>
      <td>2012</td>
      <td>OS X 10.7</td>
      <td>Lion</td>
      <td>20/07/2011</td>
    </tr>
    <tr>
      <td>2011</td>
      <td>OS X 10.6</td>
      <td>Snow Leopard</td>
      <td>28/08/2009</td>
    </tr>
    <tr>
      <td>2009</td>
      <td>OS X 10.5</td>
      <td>Leopard</td>
      <td>26/10/2007</td>
    </tr>
    <tr>
      <td>2007</td>
      <td>OS X 10.4</td>
      <td>Tiger</td>
      <td>29/04/2005</td>
    </tr>
    <tr>
      <td>2005</td>
      <td>OS X 10.3</td>
      <td>Panther</td>
      <td>24/10/2003</td>
    </tr>
    <tr>
      <td>2003</td>
      <td>OS X 10.2</td>
      <td>Jaguar</td>
      <td>24/08/2002</td>
    </tr>
    <tr>
      <td>2002</td>
      <td>OS X 10.1</td>
      <td>Puma</td>
      <td>25/09/2001</td>
    </tr>
    <tr>
      <td>2001</td>
      <td>OS X 10.0</td>
      <td>Cheetah</td>
      <td>24/03/2001</td>
    </tr>
    <tr>
      <td>2000</td>
      <td>Mac OS X Public Beta</td>
      <td>Kodiak</td>
      <td>13/09/2000</td>
    </tr>
    <tr>
      <td>1999</td>
      <td>Mac OS X Server 1.0</td>
      <td>Hera</td>
      <td>16/03/1999</td>
    </tr>
    <tr>
      <td>1999</td>
      <td>Mac OS X Developer Preview</td>
      <td>—</td>
      <td>16/03/1999</td>
    </tr>
    <tr>
      <td>1997</td>
      <td>Rhapsody Developer Release</td>
      <td>—</td>
      <td>31/08/1997</td>
    </tr>
  </tbody>
</table>]]></content><author><name>Zeng Liang</name></author><summary type="html"><![CDATA[I’m still using an Intel Mac on macOS 13 and 14 because I prefer a stable system rather than upgrading to the latest release every year. I only upgrade macOS when my work absolutely requires it — not for new features. To help myself choose the most suitable version when an upgrade becomes necessary, I keep a list of macOS releases and their dates as a reference.]]></summary></entry><entry xml:lang="en"><title type="html">B/O - Visitor</title><link href="https://zengl.dev/blog/visitor.html" rel="alternate" type="text/html" title="B/O - Visitor" /><published>2022-11-24T00:00:00+00:00</published><updated>2022-11-24T00:00:00+00:00</updated><id>https://zengl.dev/blog/visitor</id><content type="html" xml:base="https://zengl.dev/blog/visitor.html"><![CDATA[<ul>
  <li>Category: behavioral</li>
  <li>Type: object</li>
  <li>Motivation: add new visitor without change existed visitor and element
(driver -&gt; print)</li>
</ul>

<p><img src="assets/visitor.jpg" alt="diagram" /></p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">do</span> <span class="p">{</span>
    <span class="k">let</span> <span class="nv">car</span> <span class="o">=</span> <span class="kt">Car</span><span class="p">()</span>
    <span class="n">car</span><span class="o">.</span><span class="nf">accept</span><span class="p">(</span><span class="kt">Driver</span><span class="p">())</span>
    <span class="n">car</span><span class="o">.</span><span class="nf">accept</span><span class="p">(</span><span class="kt">Printer</span><span class="p">())</span>

    <span class="k">let</span> <span class="nv">engine</span> <span class="o">=</span> <span class="kt">Engine</span><span class="p">()</span>
    <span class="n">engine</span><span class="o">.</span><span class="nf">accept</span><span class="p">(</span><span class="kt">Printer</span><span class="p">())</span>
<span class="p">}</span>
</code></pre></div></div>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">protocol</span> <span class="kt">Visitor</span>
<span class="p">{</span>
    <span class="kd">func</span> <span class="nf">visit</span><span class="p">(</span><span class="nv">engine</span><span class="p">:</span> <span class="kt">Engine</span><span class="p">)</span>
    <span class="kd">func</span> <span class="nf">visit</span><span class="p">(</span><span class="nv">body</span><span class="p">:</span> <span class="kt">Body</span><span class="p">)</span>
    <span class="kd">func</span> <span class="nf">visit</span><span class="p">(</span><span class="nv">wheel</span><span class="p">:</span> <span class="kt">Wheel</span><span class="p">)</span>
    <span class="kd">func</span> <span class="nf">visit</span><span class="p">(</span><span class="nv">car</span><span class="p">:</span> <span class="kt">Car</span><span class="p">)</span>
<span class="p">}</span>

<span class="kd">extension</span> <span class="kt">Visitor</span> <span class="p">{</span>
    <span class="kd">func</span> <span class="nf">visit</span><span class="p">(</span><span class="nv">car</span><span class="p">:</span> <span class="kt">Car</span><span class="p">)</span>
    <span class="p">{</span>

    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="kt">Driver</span><span class="p">:</span> <span class="kt">Visitor</span>
<span class="p">{</span>
    <span class="kd">func</span> <span class="nf">visit</span><span class="p">(</span><span class="nv">engine</span><span class="p">:</span> <span class="kt">Engine</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="nf">print</span><span class="p">(</span><span class="s">"start engine"</span><span class="p">)</span>
    <span class="p">}</span>

    <span class="kd">func</span> <span class="nf">visit</span><span class="p">(</span><span class="nv">body</span><span class="p">:</span> <span class="kt">Body</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="nf">print</span><span class="p">(</span><span class="s">"move body"</span><span class="p">)</span>
    <span class="p">}</span>

    <span class="kd">func</span> <span class="nf">visit</span><span class="p">(</span><span class="nv">wheel</span><span class="p">:</span> <span class="kt">Wheel</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="nf">print</span><span class="p">(</span><span class="s">"kick wheel"</span><span class="p">)</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="kt">Printer</span><span class="p">:</span> <span class="kt">Visitor</span>
<span class="p">{</span>
    <span class="kd">func</span> <span class="nf">visit</span><span class="p">(</span><span class="nv">engine</span><span class="p">:</span> <span class="kt">Engine</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="nf">print</span><span class="p">(</span><span class="s">"print engine"</span><span class="p">)</span>
    <span class="p">}</span>

    <span class="kd">func</span> <span class="nf">visit</span><span class="p">(</span><span class="nv">body</span><span class="p">:</span> <span class="kt">Body</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="nf">print</span><span class="p">(</span><span class="s">"print body"</span><span class="p">)</span>
    <span class="p">}</span>

    <span class="kd">func</span> <span class="nf">visit</span><span class="p">(</span><span class="nv">wheel</span><span class="p">:</span> <span class="kt">Wheel</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="nf">print</span><span class="p">(</span><span class="s">"print wheel"</span><span class="p">)</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">protocol</span> <span class="kt">Element</span>
<span class="p">{</span>
    <span class="kd">func</span> <span class="nf">accept</span><span class="p">(</span><span class="n">_</span> <span class="nv">visitor</span><span class="p">:</span> <span class="kt">Visitor</span><span class="p">)</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="kt">Engine</span><span class="p">:</span> <span class="kt">Element</span>
<span class="p">{</span>
    <span class="kd">func</span> <span class="nf">accept</span><span class="p">(</span><span class="n">_</span> <span class="nv">visitor</span><span class="p">:</span> <span class="kt">Visitor</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">visitor</span><span class="o">.</span><span class="nf">visit</span><span class="p">(</span><span class="nv">engine</span><span class="p">:</span> <span class="k">self</span><span class="p">)</span>

    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="kt">Body</span><span class="p">:</span> <span class="kt">Element</span>
<span class="p">{</span>
    <span class="kd">func</span> <span class="nf">accept</span><span class="p">(</span><span class="n">_</span> <span class="nv">visitor</span><span class="p">:</span> <span class="kt">Visitor</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">visitor</span><span class="o">.</span><span class="nf">visit</span><span class="p">(</span><span class="nv">body</span><span class="p">:</span> <span class="k">self</span><span class="p">)</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="kt">Wheel</span><span class="p">:</span> <span class="kt">Element</span>
<span class="p">{</span>
    <span class="kd">func</span> <span class="nf">accept</span><span class="p">(</span><span class="n">_</span> <span class="nv">visitor</span><span class="p">:</span> <span class="kt">Visitor</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">visitor</span><span class="o">.</span><span class="nf">visit</span><span class="p">(</span><span class="nv">wheel</span><span class="p">:</span> <span class="k">self</span><span class="p">)</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="kt">Car</span><span class="p">:</span> <span class="kt">Element</span>
<span class="p">{</span>
    <span class="kd">private</span> <span class="k">var</span> <span class="nv">elements</span><span class="p">:</span> <span class="p">[</span><span class="kt">Element</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>

    <span class="nf">init</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="k">self</span><span class="o">.</span><span class="n">elements</span> <span class="o">=</span> <span class="p">[</span>
            <span class="kt">Engine</span><span class="p">(),</span>
            <span class="kt">Wheel</span><span class="p">(),</span>
            <span class="kt">Body</span><span class="p">(),</span>
        <span class="p">]</span>
    <span class="p">}</span>

    <span class="kd">func</span> <span class="nf">accept</span><span class="p">(</span><span class="n">_</span> <span class="nv">visitor</span><span class="p">:</span> <span class="kt">Visitor</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">for</span> <span class="n">elt</span> <span class="k">in</span> <span class="n">elements</span> <span class="p">{</span>
            <span class="n">elt</span><span class="o">.</span><span class="nf">accept</span><span class="p">(</span><span class="n">visitor</span><span class="p">)</span>
        <span class="p">}</span>
        <span class="n">visitor</span><span class="o">.</span><span class="nf">visit</span><span class="p">(</span><span class="nv">car</span><span class="p">:</span> <span class="k">self</span><span class="p">)</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>]]></content><author><name>Zeng Liang</name></author><category term="behavioral" /><category term="object" /><summary type="html"><![CDATA[Category: behavioral Type: object Motivation: add new visitor without change existed visitor and element (driver -&gt; print)]]></summary></entry><entry xml:lang="en"><title type="html">B/O - Strategy</title><link href="https://zengl.dev/blog/strategy.html" rel="alternate" type="text/html" title="B/O - Strategy" /><published>2022-11-21T00:00:00+00:00</published><updated>2022-11-21T00:00:00+00:00</updated><id>https://zengl.dev/blog/strategy</id><content type="html" xml:base="https://zengl.dev/blog/strategy.html"><![CDATA[<ul>
  <li>Category: behavioral</li>
  <li>Type: object</li>
  <li>Motivation: allow you to switch the algorithm based upon the situation</li>
</ul>

<p><img src="assets/strategy.jpg" alt="diagram" /></p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">do</span> <span class="p">{</span>
    <span class="k">let</span> <span class="nv">sedan</span> <span class="o">=</span> <span class="kt">Sedan</span><span class="p">(</span><span class="kt">Simple</span><span class="p">())</span>
    <span class="n">sedan</span><span class="o">.</span><span class="nf">applyBrake</span><span class="p">()</span>

    <span class="k">let</span> <span class="nv">sedan2</span> <span class="o">=</span> <span class="kt">Sedan</span><span class="p">(</span><span class="kt">ABS</span><span class="p">())</span>
    <span class="n">sedan2</span><span class="o">.</span><span class="nf">applyBrake</span><span class="p">()</span>
<span class="p">}</span>
</code></pre></div></div>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">protocol</span> <span class="kt">Brake</span>
<span class="p">{</span>
    <span class="kd">func</span> <span class="nf">brake</span><span class="p">()</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="kt">Simple</span><span class="p">:</span> <span class="kt">Brake</span>
<span class="p">{</span>
    <span class="kd">func</span> <span class="nf">brake</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="nf">print</span><span class="p">(</span><span class="s">"simple brake applied"</span><span class="p">)</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="kt">ABS</span><span class="p">:</span> <span class="kt">Brake</span>
<span class="p">{</span>
    <span class="kd">func</span> <span class="nf">brake</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="nf">print</span><span class="p">(</span><span class="s">"brake with ABS applied"</span><span class="p">)</span>
    <span class="p">}</span>
<span class="p">}</span>

</code></pre></div></div>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">protocol</span> <span class="kt">Car</span>
<span class="p">{</span>
    <span class="k">var</span> <span class="nv">brake</span><span class="p">:</span> <span class="kt">Brake</span> <span class="p">{</span> <span class="k">get</span> <span class="p">}</span>
    <span class="kd">func</span> <span class="nf">applyBrake</span><span class="p">()</span>
<span class="p">}</span>

<span class="kd">extension</span> <span class="kt">Car</span>
<span class="p">{</span>
    <span class="kd">func</span> <span class="nf">applyBrake</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="n">brake</span><span class="o">.</span><span class="nf">brake</span><span class="p">()</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="kt">Sedan</span><span class="p">:</span> <span class="kt">Car</span>
<span class="p">{</span>
    <span class="kd">private(set)</span> <span class="k">var</span> <span class="nv">brake</span><span class="p">:</span> <span class="kt">Brake</span>

    <span class="nf">init</span><span class="p">(</span><span class="n">_</span> <span class="nv">brake</span><span class="p">:</span> <span class="kt">Brake</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">self</span><span class="o">.</span><span class="n">brake</span> <span class="o">=</span> <span class="n">brake</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>]]></content><author><name>Zeng Liang</name></author><category term="behavioral" /><category term="object" /><summary type="html"><![CDATA[Category: behavioral Type: object Motivation: allow you to switch the algorithm based upon the situation]]></summary></entry><entry xml:lang="en"><title type="html">B/O - State</title><link href="https://zengl.dev/blog/state.html" rel="alternate" type="text/html" title="B/O - State" /><published>2022-11-19T00:00:00+00:00</published><updated>2022-11-19T00:00:00+00:00</updated><id>https://zengl.dev/blog/state</id><content type="html" xml:base="https://zengl.dev/blog/state.html"><![CDATA[<ul>
  <li>Category: behavioral</li>
  <li>Type: object</li>
  <li>Motivation: change the behavior of a class when the state changes
    <ul>
      <li>implements a state machine in an object-oriented way</li>
      <li>invoke the method in state object</li>
    </ul>
  </li>
</ul>

<p><img src="assets/state.jpg" alt="diagram" /></p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">do</span> <span class="p">{</span>
    <span class="k">let</span> <span class="nv">editor</span> <span class="o">=</span> <span class="kt">Editor</span><span class="p">()</span>
    <span class="n">editor</span><span class="o">.</span><span class="nf">type</span><span class="p">(</span><span class="s">"hello WORLD"</span><span class="p">)</span>

    <span class="n">editor</span><span class="o">.</span><span class="n">state</span> <span class="o">=</span> <span class="kt">Upppercase</span><span class="p">()</span>
    <span class="n">editor</span><span class="o">.</span><span class="nf">type</span><span class="p">(</span><span class="s">"hello world"</span><span class="p">)</span>

    <span class="n">editor</span><span class="o">.</span><span class="n">state</span> <span class="o">=</span> <span class="kt">Lowercase</span><span class="p">()</span>
    <span class="n">editor</span><span class="o">.</span><span class="nf">type</span><span class="p">(</span><span class="s">"hello world"</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div></div>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="kt">Editor</span>
<span class="p">{</span>
    <span class="k">var</span> <span class="nv">state</span><span class="p">:</span> <span class="kt">Writing</span> <span class="o">=</span> <span class="kt">Default</span><span class="p">()</span>

    <span class="kd">func</span> <span class="nf">type</span><span class="p">(</span><span class="n">_</span> <span class="nv">words</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">state</span><span class="o">.</span><span class="nf">write</span><span class="p">(</span><span class="n">words</span><span class="p">)</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">protocol</span> <span class="kt">Writing</span>
<span class="p">{</span>
    <span class="kd">func</span> <span class="nf">write</span><span class="p">(</span><span class="n">_</span> <span class="nv">words</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="kt">Default</span><span class="p">:</span> <span class="kt">Writing</span>
<span class="p">{</span>
    <span class="kd">func</span> <span class="nf">write</span><span class="p">(</span><span class="n">_</span> <span class="nv">words</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="nf">print</span><span class="p">(</span><span class="n">words</span><span class="p">)</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="kt">Upppercase</span><span class="p">:</span> <span class="kt">Writing</span>
<span class="p">{</span>
    <span class="kd">func</span> <span class="nf">write</span><span class="p">(</span><span class="n">_</span> <span class="nv">words</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="nf">print</span><span class="p">(</span><span class="n">words</span><span class="o">.</span><span class="nf">uppercased</span><span class="p">())</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="kt">Lowercase</span><span class="p">:</span> <span class="kt">Writing</span>
<span class="p">{</span>
    <span class="kd">func</span> <span class="nf">write</span><span class="p">(</span><span class="n">_</span> <span class="nv">words</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="nf">print</span><span class="p">(</span><span class="n">words</span><span class="o">.</span><span class="nf">lowercased</span><span class="p">())</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>]]></content><author><name>Zeng Liang</name></author><category term="behavioral" /><category term="object" /><summary type="html"><![CDATA[Category: behavioral Type: object Motivation: change the behavior of a class when the state changes implements a state machine in an object-oriented way invoke the method in state object]]></summary></entry><entry xml:lang="en"><title type="html">B/O - Observer</title><link href="https://zengl.dev/blog/observer.html" rel="alternate" type="text/html" title="B/O - Observer" /><published>2022-11-16T00:00:00+00:00</published><updated>2022-11-16T00:00:00+00:00</updated><id>https://zengl.dev/blog/observer</id><content type="html" xml:base="https://zengl.dev/blog/observer.html"><![CDATA[<ul>
  <li>Category: behavioral</li>
  <li>Type: object</li>
  <li>Motivation: defines a dependency between objects so that whenever an object
change its state, all its dependents are notified</li>
</ul>

<p><img src="assets/observer.jpg" alt="diagram" /></p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">do</span> <span class="p">{</span>
    <span class="k">var</span> <span class="nv">podcast</span> <span class="o">=</span> <span class="kt">Podcast</span><span class="p">()</span>
    <span class="k">let</span> <span class="nv">foo</span> <span class="o">=</span> <span class="kt">Listener</span><span class="p">(</span><span class="nv">name</span><span class="p">:</span> <span class="s">"foo"</span><span class="p">)</span>
    <span class="k">let</span> <span class="nv">bar</span> <span class="o">=</span> <span class="kt">Listener</span><span class="p">(</span><span class="nv">name</span><span class="p">:</span> <span class="s">"bar"</span><span class="p">)</span>
    <span class="n">podcast</span><span class="o">.</span><span class="nf">add</span><span class="p">(</span><span class="nv">subscriber</span><span class="p">:</span> <span class="n">foo</span><span class="p">)</span>
    <span class="n">podcast</span><span class="o">.</span><span class="nf">add</span><span class="p">(</span><span class="nv">subscriber</span><span class="p">:</span> <span class="n">bar</span><span class="p">)</span>

    <span class="n">podcast</span><span class="o">.</span><span class="nf">release</span><span class="p">(</span><span class="s">"Episode 1: Hello World"</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div></div>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">protocol</span> <span class="kt">Publisher</span>
<span class="p">{</span>
    <span class="k">var</span> <span class="nv">subscribers</span><span class="p">:</span> <span class="p">[</span><span class="kt">Subscriber</span><span class="p">]</span> <span class="p">{</span><span class="k">get</span> <span class="k">set</span><span class="p">}</span>

    <span class="k">mutating</span> <span class="kd">func</span> <span class="nf">add</span><span class="p">(</span><span class="nv">subscriber</span><span class="p">:</span> <span class="kt">Subscriber</span><span class="p">)</span>
    <span class="k">mutating</span> <span class="kd">func</span> <span class="nf">remove</span><span class="p">(</span><span class="n">at</span> <span class="nv">index</span><span class="p">:</span> <span class="kt">Int</span><span class="p">)</span>
    <span class="kd">func</span> <span class="nf">notify</span><span class="p">()</span>
<span class="p">}</span>

<span class="kd">extension</span> <span class="kt">Publisher</span>
<span class="p">{</span>
    <span class="kd">func</span> <span class="nf">notify</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="k">for</span> <span class="n">listener</span> <span class="k">in</span> <span class="n">subscribers</span> <span class="p">{</span>
            <span class="n">listener</span><span class="o">.</span><span class="nf">update</span><span class="p">(</span><span class="k">self</span><span class="p">)</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="k">mutating</span> <span class="kd">func</span> <span class="nf">add</span><span class="p">(</span><span class="nv">subscriber</span><span class="p">:</span> <span class="kt">Subscriber</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">subscribers</span><span class="o">.</span><span class="nf">append</span><span class="p">(</span><span class="n">subscriber</span><span class="p">)</span>
    <span class="p">}</span>

    <span class="k">mutating</span> <span class="kd">func</span> <span class="nf">remove</span><span class="p">(</span><span class="n">at</span> <span class="nv">index</span><span class="p">:</span> <span class="kt">Int</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">subscribers</span><span class="o">.</span><span class="nf">remove</span><span class="p">(</span><span class="nv">at</span><span class="p">:</span> <span class="n">index</span><span class="p">)</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="kt">Podcast</span><span class="p">:</span> <span class="kt">Publisher</span>
<span class="p">{</span>
    <span class="k">var</span> <span class="nv">subscribers</span><span class="p">:</span> <span class="p">[</span><span class="kt">Subscriber</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
    <span class="k">var</span> <span class="nv">episode</span> <span class="o">=</span> <span class="s">""</span>

    <span class="kd">func</span> <span class="nf">release</span><span class="p">(</span><span class="n">_</span> <span class="nv">episode</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">self</span><span class="o">.</span><span class="n">episode</span> <span class="o">=</span> <span class="n">episode</span>
        <span class="nf">notify</span><span class="p">()</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">protocol</span> <span class="kt">Subscriber</span>
<span class="p">{</span>
    <span class="kd">func</span> <span class="nf">update</span><span class="p">(</span><span class="n">_</span> <span class="nv">publisher</span><span class="p">:</span> <span class="kt">Publisher</span><span class="p">)</span>
<span class="p">}</span>

<span class="kd">struct</span> <span class="kt">Listener</span><span class="p">:</span> <span class="kt">Subscriber</span>
<span class="p">{</span>
    <span class="k">var</span> <span class="nv">name</span><span class="p">:</span> <span class="kt">String</span>

    <span class="kd">func</span> <span class="nf">update</span><span class="p">(</span><span class="n">_</span> <span class="nv">publisher</span><span class="p">:</span> <span class="kt">Publisher</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">guard</span> <span class="k">let</span> <span class="nv">podast</span> <span class="o">=</span> <span class="n">publisher</span> <span class="k">as?</span> <span class="kt">Podcast</span> <span class="k">else</span> <span class="p">{</span>
            <span class="k">return</span>
        <span class="p">}</span>
        <span class="nf">print</span><span class="p">(</span><span class="s">"</span><span class="se">\(</span><span class="n">name</span><span class="se">)</span><span class="s"> receives notification of </span><span class="se">\(</span><span class="n">podast</span><span class="o">.</span><span class="n">episode</span><span class="se">)</span><span class="s">"</span><span class="p">)</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>]]></content><author><name>Zeng Liang</name></author><category term="behavioral" /><category term="object" /><summary type="html"><![CDATA[Category: behavioral Type: object Motivation: defines a dependency between objects so that whenever an object change its state, all its dependents are notified]]></summary></entry><entry xml:lang="en"><title type="html">B/O - Memento</title><link href="https://zengl.dev/blog/memento.html" rel="alternate" type="text/html" title="B/O - Memento" /><published>2022-11-05T00:00:00+00:00</published><updated>2022-11-05T00:00:00+00:00</updated><id>https://zengl.dev/blog/memento</id><content type="html" xml:base="https://zengl.dev/blog/memento.html"><![CDATA[<ul>
  <li>Category: behavioral</li>
  <li>Type: object</li>
  <li>Motivation: memento is capture and storing the current state of an object in
a manner that it can be restored later on in a smooth manner</li>
</ul>

<p><img src="assets/memento.jpg" alt="diagram" /></p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// caretaker</span>
<span class="k">do</span> <span class="p">{</span>
    <span class="k">var</span> <span class="nv">history</span><span class="p">:</span> <span class="p">[</span><span class="kt">Memento</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>

    <span class="k">let</span> <span class="nv">editor</span> <span class="o">=</span> <span class="kt">Editor</span><span class="p">()</span>
    <span class="n">editor</span><span class="o">.</span><span class="nf">type</span><span class="p">(</span><span class="s">"foo"</span><span class="p">)</span>
    <span class="n">history</span><span class="o">.</span><span class="nf">append</span><span class="p">(</span><span class="n">editor</span><span class="o">.</span><span class="nf">save</span><span class="p">())</span>
    <span class="nf">print</span><span class="p">(</span><span class="n">editor</span><span class="o">.</span><span class="n">content</span><span class="p">)</span>

    <span class="n">editor</span><span class="o">.</span><span class="nf">type</span><span class="p">(</span><span class="s">"bar"</span><span class="p">)</span>
    <span class="nf">print</span><span class="p">(</span><span class="n">editor</span><span class="o">.</span><span class="n">content</span><span class="p">)</span>

    <span class="n">editor</span><span class="o">.</span><span class="nf">restore</span><span class="p">(</span><span class="n">history</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
    <span class="nf">print</span><span class="p">(</span><span class="n">editor</span><span class="o">.</span><span class="n">content</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div></div>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// memento</span>
<span class="kd">struct</span> <span class="kt">Memento</span>
<span class="p">{</span>
    <span class="k">let</span> <span class="nv">content</span><span class="p">:</span> <span class="kt">String</span>
<span class="p">}</span>
</code></pre></div></div>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// originator</span>
<span class="kd">class</span> <span class="kt">Editor</span>
<span class="p">{</span>
    <span class="k">var</span> <span class="nv">content</span><span class="p">:</span> <span class="kt">String</span> <span class="o">=</span> <span class="s">""</span>
    <span class="kd">func</span> <span class="nf">type</span><span class="p">(</span><span class="n">_</span> <span class="nv">words</span><span class="p">:</span> <span class="kt">String</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">content</span> <span class="o">+=</span> <span class="n">words</span>
    <span class="p">}</span>

    <span class="kd">func</span> <span class="nf">save</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="kt">Memento</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="kt">Memento</span><span class="p">(</span><span class="nv">content</span><span class="p">:</span> <span class="n">content</span><span class="p">)</span>
    <span class="p">}</span>

    <span class="kd">func</span> <span class="nf">restore</span><span class="p">(</span><span class="n">_</span> <span class="nv">memento</span><span class="p">:</span> <span class="kt">Memento</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">content</span> <span class="o">=</span> <span class="n">memento</span><span class="o">.</span><span class="n">content</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>]]></content><author><name>Zeng Liang</name></author><category term="behavioral" /><category term="object" /><summary type="html"><![CDATA[Category: behavioral Type: object Motivation: memento is capture and storing the current state of an object in a manner that it can be restored later on in a smooth manner]]></summary></entry><entry xml:lang="en"><title type="html">B/O - Mediator</title><link href="https://zengl.dev/blog/mediator.html" rel="alternate" type="text/html" title="B/O - Mediator" /><published>2022-10-19T00:00:00+00:00</published><updated>2022-10-19T00:00:00+00:00</updated><id>https://zengl.dev/blog/mediator</id><content type="html" xml:base="https://zengl.dev/blog/mediator.html"><![CDATA[<ul>
  <li>Category: behavioral</li>
  <li>Type: object</li>
  <li>Motivation: mediator(third part object), as the provide to control between
two objects (called colleagues)</li>
</ul>

<p><img src="assets/mediator.jpg" alt="diagram" /></p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">do</span> <span class="p">{</span>
    <span class="k">let</span> <span class="nv">atc</span> <span class="o">=</span> <span class="kt">ATC</span><span class="p">()</span>
    <span class="k">let</span> <span class="nv">flight</span> <span class="o">=</span> <span class="kt">Flight</span><span class="p">(</span><span class="n">atc</span><span class="p">)</span>
    <span class="k">let</span> <span class="nv">runway</span> <span class="o">=</span> <span class="kt">Runway</span><span class="p">(</span><span class="n">atc</span><span class="p">)</span>

    <span class="n">atc</span><span class="o">.</span><span class="nf">register</span><span class="p">(</span><span class="n">flight</span><span class="p">)</span>
    <span class="n">atc</span><span class="o">.</span><span class="nf">register</span><span class="p">(</span><span class="n">runway</span><span class="p">)</span>

    <span class="n">runway</span><span class="o">.</span><span class="nf">land</span><span class="p">()</span>
    <span class="n">flight</span><span class="o">.</span><span class="nf">land</span><span class="p">()</span>
    <span class="cm">/*
      Output:
      Landing permission granted.
      Sucessfully landed
    */</span>
<span class="p">}</span>
</code></pre></div></div>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">protocol</span> <span class="kt">Mediator</span>
<span class="p">{</span>
	<span class="k">var</span> <span class="nv">isLanding</span><span class="p">:</span> <span class="kt">Bool</span> <span class="p">{</span> <span class="k">get</span> <span class="k">set</span><span class="p">}</span>

	<span class="c1">// just demostrate to add command to mediator, in this example it do</span>
	<span class="c1">// nothing</span>
	<span class="kd">func</span> <span class="nf">register</span><span class="p">(</span><span class="n">_</span> <span class="nv">command</span><span class="p">:</span> <span class="kt">Command</span><span class="p">)</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="kt">ATC</span><span class="p">:</span> <span class="kt">Mediator</span>
<span class="p">{</span>
	<span class="k">var</span> <span class="nv">isLanding</span><span class="p">:</span> <span class="kt">Bool</span> <span class="o">=</span> <span class="kc">false</span>

	<span class="k">var</span> <span class="nv">commands</span><span class="p">:</span> <span class="p">[</span><span class="kt">Command</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>

	<span class="kd">func</span> <span class="nf">register</span><span class="p">(</span><span class="n">_</span> <span class="nv">command</span><span class="p">:</span> <span class="kt">Command</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="n">commands</span><span class="o">.</span><span class="nf">append</span><span class="p">(</span><span class="n">command</span><span class="p">)</span>
	<span class="p">}</span>
<span class="p">}</span>

</code></pre></div></div>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">protocol</span> <span class="kt">Command</span>
<span class="p">{</span>
	<span class="nf">init</span><span class="p">(</span><span class="n">_</span> <span class="nv">atc</span><span class="p">:</span> <span class="kt">Mediator</span><span class="p">)</span>
	<span class="kd">func</span> <span class="nf">land</span><span class="p">()</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="kt">Flight</span><span class="p">:</span> <span class="kt">Command</span>
<span class="p">{</span>
	<span class="kd">private</span> <span class="k">var</span> <span class="nv">atc</span><span class="p">:</span> <span class="kt">Mediator</span>
	<span class="kd">required</span> <span class="nf">init</span><span class="p">(</span><span class="n">_</span> <span class="nv">atc</span><span class="p">:</span> <span class="kt">Mediator</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">self</span><span class="o">.</span><span class="n">atc</span> <span class="o">=</span> <span class="n">atc</span>
	<span class="p">}</span>

	<span class="kd">func</span> <span class="nf">land</span><span class="p">()</span>
	<span class="p">{</span>
		<span class="k">if</span> <span class="n">atc</span><span class="o">.</span><span class="n">isLanding</span> <span class="p">{</span>
			<span class="nf">print</span><span class="p">(</span><span class="s">"Sucessfully landed"</span><span class="p">)</span>
			<span class="n">atc</span><span class="o">.</span><span class="n">isLanding</span> <span class="o">=</span> <span class="kc">true</span>
		<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
			<span class="nf">print</span><span class="p">(</span><span class="s">"Waiting for landing"</span><span class="p">)</span>
		<span class="p">}</span>
	<span class="p">}</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="kt">Runway</span><span class="p">:</span> <span class="kt">Command</span>
<span class="p">{</span>
	<span class="kd">private</span> <span class="k">var</span> <span class="nv">atc</span><span class="p">:</span> <span class="kt">Mediator</span>
	<span class="kd">required</span> <span class="nf">init</span><span class="p">(</span><span class="n">_</span> <span class="nv">atc</span><span class="p">:</span> <span class="kt">Mediator</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">self</span><span class="o">.</span><span class="n">atc</span> <span class="o">=</span> <span class="n">atc</span>
	<span class="p">}</span>

	<span class="kd">func</span> <span class="nf">land</span><span class="p">()</span>
	<span class="p">{</span>
		<span class="n">atc</span><span class="o">.</span><span class="n">isLanding</span> <span class="o">=</span> <span class="kc">true</span>
		<span class="nf">print</span><span class="p">(</span><span class="s">"Landing permission granted."</span><span class="p">)</span>
	<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>]]></content><author><name>Zeng Liang</name></author><category term="behavioral" /><category term="object" /><summary type="html"><![CDATA[Category: behavioral Type: object Motivation: mediator(third part object), as the provide to control between two objects (called colleagues)]]></summary></entry><entry xml:lang="en"><title type="html">B/O - Command</title><link href="https://zengl.dev/blog/command.html" rel="alternate" type="text/html" title="B/O - Command" /><published>2022-10-17T00:00:00+00:00</published><updated>2022-10-17T00:00:00+00:00</updated><id>https://zengl.dev/blog/command</id><content type="html" xml:base="https://zengl.dev/blog/command.html"><![CDATA[<ul>
  <li>Category: behavioral</li>
  <li>Type: object</li>
  <li>Motivation: decouple client from receiver, keep maintaining the history of
commands, e.g. undo/redo</li>
</ul>

<p><img src="assets/command.jpg" alt="diagram" /></p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// client</span>
<span class="k">do</span> <span class="p">{</span>
    <span class="k">let</span> <span class="nv">receiver</span> <span class="o">=</span> <span class="kt">Television</span><span class="p">()</span>
    <span class="k">let</span> <span class="nv">invoker</span> <span class="o">=</span> <span class="kt">RemoteControl</span><span class="p">()</span>

    <span class="k">let</span> <span class="nv">turnOn</span> <span class="o">=</span> <span class="kt">TurnOn</span><span class="p">(</span><span class="n">receiver</span><span class="p">)</span>
    <span class="n">invoker</span><span class="o">.</span><span class="nf">submit</span><span class="p">(</span><span class="n">turnOn</span><span class="p">)</span>

    <span class="k">let</span> <span class="nv">turnOff</span> <span class="o">=</span> <span class="kt">TurnOff</span><span class="p">(</span><span class="n">receiver</span><span class="p">)</span>
    <span class="n">invoker</span><span class="o">.</span><span class="nf">submit</span><span class="p">(</span><span class="n">turnOff</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div></div>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Receiver</span>
<span class="kd">class</span> <span class="kt">Television</span>
<span class="p">{</span>
    <span class="kd">func</span> <span class="nf">turnOn</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="nf">print</span><span class="p">(</span><span class="s">"turn on"</span><span class="p">)</span>
    <span class="p">}</span>

    <span class="kd">func</span> <span class="nf">turnOff</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="nf">print</span><span class="p">(</span><span class="s">"turn off"</span><span class="p">)</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Invoker</span>
<span class="kd">class</span> <span class="kt">RemoteControl</span>
<span class="p">{</span>
    <span class="kd">func</span> <span class="nf">submit</span><span class="p">(</span><span class="n">_</span> <span class="nv">command</span><span class="p">:</span> <span class="kt">Command</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">command</span><span class="o">.</span><span class="nf">execute</span><span class="p">()</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Command</span>
<span class="kd">protocol</span> <span class="kt">Command</span>
<span class="p">{</span>
    <span class="kd">func</span> <span class="nf">execute</span><span class="p">()</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="kt">TurnOn</span><span class="p">:</span> <span class="kt">Command</span>
<span class="p">{</span>
    <span class="kd">private</span> <span class="k">let</span> <span class="nv">receiver</span><span class="p">:</span> <span class="kt">Television</span>

    <span class="nf">init</span><span class="p">(</span><span class="n">_</span> <span class="nv">receiver</span><span class="p">:</span> <span class="kt">Television</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">self</span><span class="o">.</span><span class="n">receiver</span> <span class="o">=</span> <span class="n">receiver</span>
    <span class="p">}</span>

    <span class="kd">func</span> <span class="nf">execute</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="n">receiver</span><span class="o">.</span><span class="nf">turnOn</span><span class="p">()</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kd">class</span> <span class="kt">TurnOff</span><span class="p">:</span> <span class="kt">Command</span>
<span class="p">{</span>
    <span class="kd">private</span> <span class="k">let</span> <span class="nv">receiver</span><span class="p">:</span> <span class="kt">Television</span>

    <span class="nf">init</span><span class="p">(</span><span class="n">_</span> <span class="nv">receiver</span><span class="p">:</span> <span class="kt">Television</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">self</span><span class="o">.</span><span class="n">receiver</span> <span class="o">=</span> <span class="n">receiver</span>
    <span class="p">}</span>

    <span class="kd">func</span> <span class="nf">execute</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="n">receiver</span><span class="o">.</span><span class="nf">turnOff</span><span class="p">()</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>]]></content><author><name>Zeng Liang</name></author><category term="behavioral" /><category term="object" /><summary type="html"><![CDATA[Category: behavioral Type: object Motivation: decouple client from receiver, keep maintaining the history of commands, e.g. undo/redo]]></summary></entry><entry xml:lang="en"><title type="html">B/O - Chain of Responsibility</title><link href="https://zengl.dev/blog/chain-of-responsibility.html" rel="alternate" type="text/html" title="B/O - Chain of Responsibility" /><published>2022-10-14T00:00:00+00:00</published><updated>2022-10-14T00:00:00+00:00</updated><id>https://zengl.dev/blog/chain-of-responsibility</id><content type="html" xml:base="https://zengl.dev/blog/chain-of-responsibility.html"><![CDATA[<ul>
  <li>Category: behavioral</li>
  <li>Type: object</li>
  <li>Motivation: build a chain of object, request from one end and keeps going from
object to object till it finds the suitable handler</li>
</ul>

<p><img src="assets/chain-of-responsibility.jpg" alt="diagram" /></p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">do</span> <span class="p">{</span>
  <span class="k">var</span> <span class="nv">bank</span> <span class="o">=</span> <span class="kt">Bank</span><span class="p">(</span><span class="nv">balance</span><span class="p">:</span> <span class="mi">100</span><span class="p">)</span>
  <span class="k">var</span> <span class="nv">paypal</span> <span class="o">=</span> <span class="kt">Paypal</span><span class="p">(</span><span class="nv">balance</span><span class="p">:</span> <span class="mi">200</span><span class="p">)</span>
  <span class="n">bank</span><span class="o">.</span><span class="nf">setNext</span><span class="p">(</span><span class="n">paypal</span><span class="p">)</span>

  <span class="n">bank</span><span class="o">.</span><span class="nf">pay</span><span class="p">(</span><span class="nv">amount</span><span class="p">:</span> <span class="mi">30</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div></div>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">protocol</span> <span class="kt">Account</span>
<span class="p">{</span>
    <span class="k">var</span> <span class="nv">balance</span><span class="p">:</span> <span class="kt">Float</span> <span class="p">{</span><span class="k">set</span> <span class="k">get</span><span class="p">}</span>
    <span class="k">var</span> <span class="nv">sucessor</span><span class="p">:</span> <span class="kt">Account</span><span class="p">?</span> <span class="p">{</span><span class="k">set</span> <span class="k">get</span><span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">extension</span> <span class="kt">Account</span>
<span class="p">{</span>
    <span class="k">mutating</span> <span class="kd">func</span> <span class="nf">pay</span><span class="p">(</span><span class="nv">amount</span><span class="p">:</span> <span class="kt">Float</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">if</span> <span class="nf">canPay</span><span class="p">(</span><span class="n">amount</span><span class="p">)</span> <span class="p">{</span>
            <span class="n">balance</span> <span class="o">-=</span> <span class="n">amount</span>
            <span class="nf">print</span><span class="p">(</span><span class="s">"</span><span class="se">\(</span><span class="kt">String</span><span class="p">(</span><span class="nv">describing</span><span class="p">:</span> <span class="nf">type</span><span class="p">(</span><span class="nv">of</span><span class="p">:</span> <span class="k">self</span><span class="p">))</span><span class="se">)</span><span class="s"> paid, balance: </span><span class="se">\(</span><span class="n">balance</span><span class="se">)</span><span class="s">"</span><span class="p">)</span>
        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="k">var</span> <span class="nv">account</span> <span class="o">=</span> <span class="n">sucessor</span> <span class="p">{</span>
            <span class="n">account</span><span class="o">.</span><span class="nf">pay</span><span class="p">(</span><span class="nv">amount</span><span class="p">:</span> <span class="n">amount</span><span class="p">)</span>
        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
            <span class="nf">print</span><span class="p">(</span><span class="s">"none accounts have enought balance"</span><span class="p">)</span>
        <span class="p">}</span>
    <span class="p">}</span>

    <span class="kd">func</span> <span class="nf">canPay</span><span class="p">(</span><span class="n">_</span> <span class="nv">amount</span><span class="p">:</span> <span class="kt">Float</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Bool</span>
    <span class="p">{</span>
        <span class="n">amount</span> <span class="o">&lt;=</span> <span class="n">balance</span>
    <span class="p">}</span>

    <span class="k">mutating</span> <span class="kd">func</span> <span class="nf">setNext</span><span class="p">(</span><span class="n">_</span> <span class="nv">account</span><span class="p">:</span> <span class="kt">Account</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">sucessor</span> <span class="o">=</span> <span class="n">account</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">struct</span> <span class="kt">Bank</span><span class="p">:</span> <span class="kt">Account</span>
<span class="p">{</span>
    <span class="k">var</span> <span class="nv">balance</span><span class="p">:</span> <span class="kt">Float</span>
    <span class="k">var</span> <span class="nv">sucessor</span><span class="p">:</span> <span class="kt">Account</span><span class="p">?</span>
<span class="p">}</span>

<span class="kd">struct</span> <span class="kt">Paypal</span><span class="p">:</span> <span class="kt">Account</span>
<span class="p">{</span>
    <span class="k">var</span> <span class="nv">balance</span><span class="p">:</span> <span class="kt">Float</span>
    <span class="k">var</span> <span class="nv">sucessor</span><span class="p">:</span> <span class="kt">Account</span><span class="p">?</span>
<span class="p">}</span>
</code></pre></div></div>]]></content><author><name>Zeng Liang</name></author><category term="behavioral" /><category term="object" /><summary type="html"><![CDATA[Category: behavioral Type: object Motivation: build a chain of object, request from one end and keeps going from object to object till it finds the suitable handler]]></summary></entry><entry xml:lang="en"><title type="html">S/C - Template</title><link href="https://zengl.dev/blog/template.html" rel="alternate" type="text/html" title="S/C - Template" /><published>2022-10-10T00:00:00+00:00</published><updated>2022-10-10T00:00:00+00:00</updated><id>https://zengl.dev/blog/template</id><content type="html" xml:base="https://zengl.dev/blog/template.html"><![CDATA[<ul>
  <li>Category: behavioral</li>
  <li>Type: class</li>
  <li>Motivation: define the skeleton of how a certain algorithm could be
preformed, but defers the implementation of those steps to the children
classes</li>
</ul>

<p><img src="assets/template.jpg" alt="diagram" /></p>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">do</span> <span class="p">{</span>
    <span class="k">let</span> <span class="nv">builder</span> <span class="o">=</span> <span class="kt">SwiftBuilder</span><span class="p">()</span>
    <span class="n">builder</span><span class="o">.</span><span class="nf">build</span><span class="p">()</span>
<span class="p">}</span>
</code></pre></div></div>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">protocol</span> <span class="kt">Builder</span>
<span class="p">{</span>
    <span class="kd">func</span> <span class="nf">build</span><span class="p">()</span>

    <span class="kd">func</span> <span class="nf">test</span><span class="p">()</span>
    <span class="kd">func</span> <span class="nf">lint</span><span class="p">()</span>
    <span class="kd">func</span> <span class="nf">assemble</span><span class="p">()</span>
    <span class="kd">func</span> <span class="nf">deploy</span><span class="p">()</span>
<span class="p">}</span>

<span class="kd">extension</span> <span class="kt">Builder</span>
<span class="p">{</span>
    <span class="kd">func</span> <span class="nf">build</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="nf">test</span><span class="p">()</span>
        <span class="nf">lint</span><span class="p">()</span>
        <span class="nf">assemble</span><span class="p">()</span>
        <span class="nf">deploy</span><span class="p">()</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<div class="language-swift highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="kt">SwiftBuilder</span><span class="p">:</span> <span class="kt">Builder</span>
<span class="p">{</span>
    <span class="kd">func</span> <span class="nf">test</span><span class="p">()</span> <span class="p">{</span>
        <span class="nf">print</span><span class="p">(</span><span class="s">"swift test"</span><span class="p">)</span>
    <span class="p">}</span>

    <span class="kd">func</span> <span class="nf">lint</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="nf">print</span><span class="p">(</span><span class="s">"swift lint"</span><span class="p">)</span>
    <span class="p">}</span>

    <span class="kd">func</span> <span class="nf">assemble</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="nf">print</span><span class="p">(</span><span class="s">"swift assemble"</span><span class="p">)</span>
    <span class="p">}</span>

    <span class="kd">func</span> <span class="nf">deploy</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="nf">print</span><span class="p">(</span><span class="s">"swift deploy"</span><span class="p">)</span>
    <span class="p">}</span>

<span class="p">}</span>
</code></pre></div></div>]]></content><author><name>Zeng Liang</name></author><category term="behavioral" /><category term="class" /><summary type="html"><![CDATA[Category: behavioral Type: class Motivation: define the skeleton of how a certain algorithm could be preformed, but defers the implementation of those steps to the children classes]]></summary></entry></feed>