<?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-09-22T05:08:31+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">A Visual Timeline of the History of English</title><link href="https://zengl.dev/blog/history-of-english.html" rel="alternate" type="text/html" title="A Visual Timeline of the History of English" /><published>2026-09-17T00:00:00+00:00</published><updated>2026-09-17T00:00:00+00:00</updated><id>https://zengl.dev/blog/history-of-english</id><content type="html" xml:base="https://zengl.dev/blog/history-of-english.html"><![CDATA[<p>I created a <a href="https://objczl.github.io/eng-history/">visual timeline of the history of English</a> to
show how the language grew from a Germanic foundation into the global
language we use today.</p>

<p>The timeline moves through Celtic Britain, Roman contact, Old English,
Viking influence, the Norman Conquest, Middle English, Early Modern
English, and Modern English. Each era includes a short explanation and
familiar example words, making the different layers easy to compare at a
glance.</p>

<p>It also explains why English often has several words for a similar idea.
Everyday vocabulary is often Germanic, formal vocabulary often comes
from French or Latin, and scientific vocabulary frequently draws from
Latin or Greek.</p>

<p><a href="https://objczl.github.io/eng-history/">Explore the history of English timeline</a>.</p>]]></content><author><name>Zeng Liang</name></author><category term="projects" /><summary type="html"><![CDATA[I created a visual timeline of the history of English to show how the language grew from a Germanic foundation into the global language we use today.]]></summary></entry><entry xml:lang="en"><title type="html">Explore the xv6-riscv Source Architecture</title><link href="https://zengl.dev/blog/xv6-riscv-explorer.html" rel="alternate" type="text/html" title="Explore the xv6-riscv Source Architecture" /><published>2026-09-17T00:00:00+00:00</published><updated>2026-09-17T00:00:00+00:00</updated><id>https://zengl.dev/blog/xv6-riscv-explorer</id><content type="html" xml:base="https://zengl.dev/blog/xv6-riscv-explorer.html"><![CDATA[<p>I built an <a href="https://objczl.github.io/xv6-riscv-explorer/">xv6-riscv source explorer</a> to make the small
operating system easier to understand as a whole. It maps how the files
in <code class="language-plaintext highlighter-rouge">user/</code> and <code class="language-plaintext highlighter-rouge">kernel/</code> work together, from building a user program to
entering the kernel through a trap and system call.</p>

<p>The overview connects the main source layers: user programs, the user
library, system call stubs, traps, kernel services, devices, and the
file-system image. It also traces the runtime path from an <code class="language-plaintext highlighter-rouge">ecall</code> to
the corresponding kernel implementation and return value.</p>

<p>Every file and system call links to the relevant source. There is also
an API index for kernel routines, user library calls, system-call
handlers, and user commands. I made it as a companion for reading xv6:
start with the architecture, follow a path that interests you, and then
jump directly into the code.</p>

<p><a href="https://objczl.github.io/xv6-riscv-explorer/">Open the xv6-riscv source explorer</a>.</p>]]></content><author><name>Zeng Liang</name></author><category term="projects" /><summary type="html"><![CDATA[I built an xv6-riscv source explorer to make the small operating system easier to understand as a whole. It maps how the files in user/ and kernel/ work together, from building a user program to entering the kernel through a trap and system call.]]></summary></entry><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></feed>