<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title>设计模式 - 分类 - ISLAND</title><link>https://youngxhui.top/categories/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/</link><description>设计模式 - 分类 - ISLAND</description><generator>Hugo -- gohugo.io</generator><language>zh-CN</language><managingEditor>youngxhui@gmail.com (youngxhui)</managingEditor><webMaster>youngxhui@gmail.com (youngxhui)</webMaster><copyright>本作品采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可。</copyright><lastBuildDate>Wed, 01 Jul 2020 17:58:01 +0800</lastBuildDate><atom:link href="https://youngxhui.top/categories/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/" rel="self" type="application/rss+xml"/><item><title>单例模式</title><link>https://youngxhui.top/2020/07/singleton/</link><pubDate>Wed, 01 Jul 2020 17:58:01 +0800</pubDate><author><name>youngxhui</name></author><guid>https://youngxhui.top/2020/07/singleton/</guid><description><![CDATA[<h1 id="单例模式singleton" class="headerLink">
    <a href="#%e5%8d%95%e4%be%8b%e6%a8%a1%e5%bc%8fsingleton" class="header-mark"></a>🥇单例模式(Singleton)</h1><h2 id="问题产生" class="headerLink">
    <a href="#%e9%97%ae%e9%a2%98%e4%ba%a7%e7%94%9f" class="header-mark"></a>问题产生</h2><p>很多时候，我们在系统中使用的对象有且仅仅需要一个，如果大量的实例化反而会产生性能问题或其他的不必要的麻烦。在我们的日常使用中有很多单例情况，比如说 windows 操作系统的资源管理器，有且只有一个资源管理器可以被使用。</p>
<p>如何设计该类，使其只能产生一个实例？我们必须保证这个类不能有多余的实例。</p>
<p>我们都知道在进行类的实例的时候，必须使用类构造器来进行，如果我们将类构造器设置为私有（private），禁止外部进行实例化时，便可以很方便的解决该问题。</p>
<h2 id="懒汉模式" class="headerLink">
    <a href="#%e6%87%92%e6%b1%89%e6%a8%a1%e5%bc%8f" class="header-mark"></a>懒汉模式</h2><p>我们将构造器私有化，在类的内部进行实例，并且进行返回。这样便形成了我们的单例，确保了类中间只有一个实例。</p>
<div class="code-block highlight is-open show-line-numbers  tw-group tw-my-2">
  <div class="
    
    tw-flex 
    tw-flex-row
    tw-flex-1 
    tw-justify-between 
    tw-w-full tw-bg-bgColor-secondary
    ">      
    <button 
      class="
        code-block-button
        tw-mx-2 
        tw-flex
        tw-flex-row
        tw-flex-1"
      aria-hidden="true">
          <div class="group-[.is-open]:tw-rotate-90 tw-transition-[transform] tw-duration-500 tw-ease-in-out print:!tw-hidden tw-w-min tw-h-min tw-my-1 tw-mx-1"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"/></svg></div>
          <p class="tw-select-none !tw-my-1">kotlin</p>
      </button>

   <div class="tw-flex">
      <button 
        class="
          line-number-button
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.show-line-numbers]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle line numbers"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M61.77 401l17.5-20.15a19.92 19.92 0 0 0 5.07-14.19v-3.31C84.34 356 80.5 352 73 352H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h22.83a157.41 157.41 0 0 0-11 12.31l-5.61 7c-4 5.07-5.25 10.13-2.8 14.88l1.05 1.93c3 5.76 6.29 7.88 12.25 7.88h4.73c10.33 0 15.94 2.44 15.94 9.09 0 4.72-4.2 8.22-14.36 8.22a41.54 41.54 0 0 1-15.47-3.12c-6.49-3.88-11.74-3.5-15.6 3.12l-5.59 9.31c-3.72 6.13-3.19 11.72 2.63 15.94 7.71 4.69 20.38 9.44 37 9.44 34.16 0 48.5-22.75 48.5-44.12-.03-14.38-9.12-29.76-28.73-34.88zM496 224H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM16 160h64a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H64V40a8 8 0 0 0-8-8H32a8 8 0 0 0-7.14 4.42l-8 16A8 8 0 0 0 24 64h8v64H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8zm-3.91 160H80a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H41.32c3.29-10.29 48.34-18.68 48.34-56.44 0-29.06-25-39.56-44.47-39.56-21.36 0-33.8 10-40.46 18.75-4.37 5.59-3 10.84 2.8 15.37l8.58 6.88c5.61 4.56 11 2.47 16.12-2.44a13.44 13.44 0 0 1 9.46-3.84c3.33 0 9.28 1.56 9.28 8.75C51 248.19 0 257.31 0 304.59v4C0 316 5.08 320 12.09 320z"/></svg></button>

      <button 
        class="
          wrap-code-button
          tw-select-none 
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.is-wrap]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle code wrap"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"/></svg></button>
      
      <button 
        class="
          copy-code-button
          tw-select-none
          tw-mx-2 
          tw-hidden
          group-[.is-open]:tw-block
          hover:tw-text-fgColor-link 
          print:!tw-hidden"
        title="Copy code">
          <span class="copy-icon tw-block"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"/></svg></span>
          <span class="check-icon tw-hidden"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"/></svg></span>
      </button>
        
      <button 
        class="
          tw-select-none 
          tw-mx-2 
          tw-block 
          group-[.is-open]:tw-hidden 
          print:!tw-hidden" 
        disabled
        aria-hidden="true"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"/></svg></button>
    </div>
  </div>
  <pre style="counter-reset: codeblock;" class="tw-block tw-m-0 tw-p-0"><code 
    id="codeblock-id-1" 
    class="
      chroma 
      !tw-block 
      tw-p-0
      tw-m-0
      tw-transition-[max-height] 
      tw-duration-500 
      tw-ease-in-out 
      group-[.is-closed]:!tw-max-h-0 
      group-[.is-wrap]:tw-text-wrap
      tw-overflow-y-hidden
      tw-overflow-x-auto
      tw-scrollbar-thin
      "><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Singleton</span> <span class="k">private</span> <span class="k">constructor</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">companion</span> <span class="k">object</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">private</span> <span class="k">var</span> <span class="py">instance</span><span class="p">:</span> <span class="n">Singleton</span><span class="p">?</span> <span class="p">=</span> <span class="k">null</span>
</span></span><span class="line"><span class="cl">        <span class="k">fun</span> <span class="nf">getInstance</span><span class="p">():</span> <span class="n">Singleton</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="p">(</span><span class="n">instance</span> <span class="o">==</span> <span class="k">null</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="n">instance</span> <span class="p">=</span> <span class="n">Singleton</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="n">instance</span><span class="o">!!</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre>
</div>
<p>这样我们的类就形成了一个单例。</p>
<p>如上的写法是单例模式中的懒汉模式，为什么叫懒汉模式，因为该对象在使用的时候才会初始化。</p>
<h2 id="线程安全的懒汉模式" class="headerLink">
    <a href="#%e7%ba%bf%e7%a8%8b%e5%ae%89%e5%85%a8%e7%9a%84%e6%87%92%e6%b1%89%e6%a8%a1%e5%bc%8f" class="header-mark"></a>线程安全的懒汉模式</h2><p>但是上述的写法存在一定的问题。当线程 A 访问该方法时，代码执行到 <code>getInstance</code> 还没有进行判断或者实例化的时候，线程 B 也开始进行访问该方法。那么此时线程A就会进行一次实例化，线程 B 也会进行一次实例化。此刻就会出现问题，单例不再单例，两个线程创建的实例并不是同一个实例。</p>
<p>为了解决上述问题，我们可以对 <code>getInstance()</code> 进行加锁。确保同一时刻只能由一个线程访问<code>getInstance</code> 方法。这样便解决了线程同步问题。</p>
<div class="code-block highlight is-open show-line-numbers  tw-group tw-my-2">
  <div class="
    
    tw-flex 
    tw-flex-row
    tw-flex-1 
    tw-justify-between 
    tw-w-full tw-bg-bgColor-secondary
    ">      
    <button 
      class="
        code-block-button
        tw-mx-2 
        tw-flex
        tw-flex-row
        tw-flex-1"
      aria-hidden="true">
          <div class="group-[.is-open]:tw-rotate-90 tw-transition-[transform] tw-duration-500 tw-ease-in-out print:!tw-hidden tw-w-min tw-h-min tw-my-1 tw-mx-1"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"/></svg></div>
          <p class="tw-select-none !tw-my-1">kotlin</p>
      </button>

   <div class="tw-flex">
      <button 
        class="
          line-number-button
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.show-line-numbers]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle line numbers"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M61.77 401l17.5-20.15a19.92 19.92 0 0 0 5.07-14.19v-3.31C84.34 356 80.5 352 73 352H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h22.83a157.41 157.41 0 0 0-11 12.31l-5.61 7c-4 5.07-5.25 10.13-2.8 14.88l1.05 1.93c3 5.76 6.29 7.88 12.25 7.88h4.73c10.33 0 15.94 2.44 15.94 9.09 0 4.72-4.2 8.22-14.36 8.22a41.54 41.54 0 0 1-15.47-3.12c-6.49-3.88-11.74-3.5-15.6 3.12l-5.59 9.31c-3.72 6.13-3.19 11.72 2.63 15.94 7.71 4.69 20.38 9.44 37 9.44 34.16 0 48.5-22.75 48.5-44.12-.03-14.38-9.12-29.76-28.73-34.88zM496 224H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM16 160h64a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H64V40a8 8 0 0 0-8-8H32a8 8 0 0 0-7.14 4.42l-8 16A8 8 0 0 0 24 64h8v64H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8zm-3.91 160H80a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H41.32c3.29-10.29 48.34-18.68 48.34-56.44 0-29.06-25-39.56-44.47-39.56-21.36 0-33.8 10-40.46 18.75-4.37 5.59-3 10.84 2.8 15.37l8.58 6.88c5.61 4.56 11 2.47 16.12-2.44a13.44 13.44 0 0 1 9.46-3.84c3.33 0 9.28 1.56 9.28 8.75C51 248.19 0 257.31 0 304.59v4C0 316 5.08 320 12.09 320z"/></svg></button>

      <button 
        class="
          wrap-code-button
          tw-select-none 
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.is-wrap]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle code wrap"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"/></svg></button>
      
      <button 
        class="
          copy-code-button
          tw-select-none
          tw-mx-2 
          tw-hidden
          group-[.is-open]:tw-block
          hover:tw-text-fgColor-link 
          print:!tw-hidden"
        title="Copy code">
          <span class="copy-icon tw-block"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"/></svg></span>
          <span class="check-icon tw-hidden"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"/></svg></span>
      </button>
        
      <button 
        class="
          tw-select-none 
          tw-mx-2 
          tw-block 
          group-[.is-open]:tw-hidden 
          print:!tw-hidden" 
        disabled
        aria-hidden="true"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"/></svg></button>
    </div>
  </div>
  <pre style="counter-reset: codeblock;" class="tw-block tw-m-0 tw-p-0"><code 
    id="codeblock-id-2" 
    class="
      chroma 
      !tw-block 
      tw-p-0
      tw-m-0
      tw-transition-[max-height] 
      tw-duration-500 
      tw-ease-in-out 
      group-[.is-closed]:!tw-max-h-0 
      group-[.is-wrap]:tw-text-wrap
      tw-overflow-y-hidden
      tw-overflow-x-auto
      tw-scrollbar-thin
      "><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Singleton</span> <span class="k">private</span> <span class="k">constructor</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">companion</span> <span class="k">object</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">private</span> <span class="k">var</span> <span class="py">instance</span><span class="p">:</span> <span class="n">Singleton</span><span class="p">?</span> <span class="p">=</span> <span class="k">null</span>
</span></span><span class="line"><span class="cl">        <span class="nd">@Synchronized</span>
</span></span><span class="line"><span class="cl">        <span class="k">fun</span> <span class="nf">getInstance</span><span class="p">():</span> <span class="n">Singleton</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="p">(</span><span class="n">instance</span> <span class="o">==</span> <span class="k">null</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="n">instance</span> <span class="p">=</span> <span class="n">Singleton</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="n">instance</span><span class="o">!!</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre>
</div>
<p>通过 <code>@Synchronized</code> 标记该方法为一个同步方法。</p>
<h2 id="双检查锁" class="headerLink">
    <a href="#%e5%8f%8c%e6%a3%80%e6%9f%a5%e9%94%81" class="header-mark"></a>双检查锁</h2><p>通过 <code>@Synchronized</code> 注解解决了多线程访问问题，但是随之而来的又出现了性能问题。如果线程 A 在执行 <code>getInstance</code> 方法的时候，线程 B 就必须等待。反之亦然。如果是一个高并发系统，那么就会带来巨大的性能损耗，总是有一堆线程在等待中。</p>
<p>面对上述的问题，那么就应该做出新的改变。公共写是危险操作，而公共读确实安全的。所以我们在进行创建的时候加锁，而不是在整个方法上。</p>
<div class="code-block highlight is-open show-line-numbers  tw-group tw-my-2">
  <div class="
    
    tw-flex 
    tw-flex-row
    tw-flex-1 
    tw-justify-between 
    tw-w-full tw-bg-bgColor-secondary
    ">      
    <button 
      class="
        code-block-button
        tw-mx-2 
        tw-flex
        tw-flex-row
        tw-flex-1"
      aria-hidden="true">
          <div class="group-[.is-open]:tw-rotate-90 tw-transition-[transform] tw-duration-500 tw-ease-in-out print:!tw-hidden tw-w-min tw-h-min tw-my-1 tw-mx-1"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"/></svg></div>
          <p class="tw-select-none !tw-my-1">kotlin</p>
      </button>

   <div class="tw-flex">
      <button 
        class="
          line-number-button
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.show-line-numbers]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle line numbers"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M61.77 401l17.5-20.15a19.92 19.92 0 0 0 5.07-14.19v-3.31C84.34 356 80.5 352 73 352H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h22.83a157.41 157.41 0 0 0-11 12.31l-5.61 7c-4 5.07-5.25 10.13-2.8 14.88l1.05 1.93c3 5.76 6.29 7.88 12.25 7.88h4.73c10.33 0 15.94 2.44 15.94 9.09 0 4.72-4.2 8.22-14.36 8.22a41.54 41.54 0 0 1-15.47-3.12c-6.49-3.88-11.74-3.5-15.6 3.12l-5.59 9.31c-3.72 6.13-3.19 11.72 2.63 15.94 7.71 4.69 20.38 9.44 37 9.44 34.16 0 48.5-22.75 48.5-44.12-.03-14.38-9.12-29.76-28.73-34.88zM496 224H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM16 160h64a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H64V40a8 8 0 0 0-8-8H32a8 8 0 0 0-7.14 4.42l-8 16A8 8 0 0 0 24 64h8v64H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8zm-3.91 160H80a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H41.32c3.29-10.29 48.34-18.68 48.34-56.44 0-29.06-25-39.56-44.47-39.56-21.36 0-33.8 10-40.46 18.75-4.37 5.59-3 10.84 2.8 15.37l8.58 6.88c5.61 4.56 11 2.47 16.12-2.44a13.44 13.44 0 0 1 9.46-3.84c3.33 0 9.28 1.56 9.28 8.75C51 248.19 0 257.31 0 304.59v4C0 316 5.08 320 12.09 320z"/></svg></button>

      <button 
        class="
          wrap-code-button
          tw-select-none 
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.is-wrap]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle code wrap"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"/></svg></button>
      
      <button 
        class="
          copy-code-button
          tw-select-none
          tw-mx-2 
          tw-hidden
          group-[.is-open]:tw-block
          hover:tw-text-fgColor-link 
          print:!tw-hidden"
        title="Copy code">
          <span class="copy-icon tw-block"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"/></svg></span>
          <span class="check-icon tw-hidden"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"/></svg></span>
      </button>
        
      <button 
        class="
          tw-select-none 
          tw-mx-2 
          tw-block 
          group-[.is-open]:tw-hidden 
          print:!tw-hidden" 
        disabled
        aria-hidden="true"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"/></svg></button>
    </div>
  </div>
  <pre style="counter-reset: codeblock;" class="tw-block tw-m-0 tw-p-0"><code 
    id="codeblock-id-3" 
    class="
      chroma 
      !tw-block 
      tw-p-0
      tw-m-0
      tw-transition-[max-height] 
      tw-duration-500 
      tw-ease-in-out 
      group-[.is-closed]:!tw-max-h-0 
      group-[.is-wrap]:tw-text-wrap
      tw-overflow-y-hidden
      tw-overflow-x-auto
      tw-scrollbar-thin
      "><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Singleton</span> <span class="k">private</span> <span class="k">constructor</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">companion</span> <span class="k">object</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">private</span> <span class="k">var</span> <span class="py">instance</span><span class="p">:</span> <span class="n">Singleton</span><span class="p">?</span> <span class="p">=</span> <span class="k">null</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">fun</span> <span class="nf">getInstance</span><span class="p">():</span> <span class="n">Singleton</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="p">(</span><span class="n">instance</span> <span class="o">==</span> <span class="k">null</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="n">synchronized</span><span class="p">(</span><span class="n">Singleton</span><span class="o">::</span><span class="k">class</span><span class="p">.</span><span class="n">java</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                    <span class="k">if</span> <span class="p">(</span><span class="n">instance</span> <span class="o">==</span> <span class="k">null</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                        <span class="n">instance</span> <span class="p">=</span> <span class="n">Singleton</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">                    <span class="p">}</span>
</span></span><span class="line"><span class="cl">                <span class="p">}</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="n">instance</span><span class="o">!!</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre>
</div>
<p>这里在加锁前和加锁后都进行了判断，通过这样的双检测来解决了功能上单例问题和性能上问题。</p>
<p>如果加锁后不检查会发生什么？</p>
<p>如果加锁后不检查，那么假设两个线程 A、B 同时进入了 <code>getInstance</code> 并且都执行到加锁前，如果不进行判断，那么只要其中一个线程申请了加锁，那么另外一个就要等待，当前一个释放锁后，后面的就会加锁继续实例化。此时又会产生两个不同的实例。而加锁后判断就避免了这样问题。</p>
<p>然而在 kotlin 中提供了更简单实现方式，通过 by lazy 来实现双检查锁。</p>
<div class="code-block highlight is-open show-line-numbers  tw-group tw-my-2">
  <div class="
    
    tw-flex 
    tw-flex-row
    tw-flex-1 
    tw-justify-between 
    tw-w-full tw-bg-bgColor-secondary
    ">      
    <button 
      class="
        code-block-button
        tw-mx-2 
        tw-flex
        tw-flex-row
        tw-flex-1"
      aria-hidden="true">
          <div class="group-[.is-open]:tw-rotate-90 tw-transition-[transform] tw-duration-500 tw-ease-in-out print:!tw-hidden tw-w-min tw-h-min tw-my-1 tw-mx-1"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"/></svg></div>
          <p class="tw-select-none !tw-my-1">kotlin</p>
      </button>

   <div class="tw-flex">
      <button 
        class="
          line-number-button
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.show-line-numbers]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle line numbers"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M61.77 401l17.5-20.15a19.92 19.92 0 0 0 5.07-14.19v-3.31C84.34 356 80.5 352 73 352H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h22.83a157.41 157.41 0 0 0-11 12.31l-5.61 7c-4 5.07-5.25 10.13-2.8 14.88l1.05 1.93c3 5.76 6.29 7.88 12.25 7.88h4.73c10.33 0 15.94 2.44 15.94 9.09 0 4.72-4.2 8.22-14.36 8.22a41.54 41.54 0 0 1-15.47-3.12c-6.49-3.88-11.74-3.5-15.6 3.12l-5.59 9.31c-3.72 6.13-3.19 11.72 2.63 15.94 7.71 4.69 20.38 9.44 37 9.44 34.16 0 48.5-22.75 48.5-44.12-.03-14.38-9.12-29.76-28.73-34.88zM496 224H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM16 160h64a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H64V40a8 8 0 0 0-8-8H32a8 8 0 0 0-7.14 4.42l-8 16A8 8 0 0 0 24 64h8v64H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8zm-3.91 160H80a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H41.32c3.29-10.29 48.34-18.68 48.34-56.44 0-29.06-25-39.56-44.47-39.56-21.36 0-33.8 10-40.46 18.75-4.37 5.59-3 10.84 2.8 15.37l8.58 6.88c5.61 4.56 11 2.47 16.12-2.44a13.44 13.44 0 0 1 9.46-3.84c3.33 0 9.28 1.56 9.28 8.75C51 248.19 0 257.31 0 304.59v4C0 316 5.08 320 12.09 320z"/></svg></button>

      <button 
        class="
          wrap-code-button
          tw-select-none 
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.is-wrap]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle code wrap"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"/></svg></button>
      
      <button 
        class="
          copy-code-button
          tw-select-none
          tw-mx-2 
          tw-hidden
          group-[.is-open]:tw-block
          hover:tw-text-fgColor-link 
          print:!tw-hidden"
        title="Copy code">
          <span class="copy-icon tw-block"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"/></svg></span>
          <span class="check-icon tw-hidden"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"/></svg></span>
      </button>
        
      <button 
        class="
          tw-select-none 
          tw-mx-2 
          tw-block 
          group-[.is-open]:tw-hidden 
          print:!tw-hidden" 
        disabled
        aria-hidden="true"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"/></svg></button>
    </div>
  </div>
  <pre style="counter-reset: codeblock;" class="tw-block tw-m-0 tw-p-0"><code 
    id="codeblock-id-4" 
    class="
      chroma 
      !tw-block 
      tw-p-0
      tw-m-0
      tw-transition-[max-height] 
      tw-duration-500 
      tw-ease-in-out 
      group-[.is-closed]:!tw-max-h-0 
      group-[.is-wrap]:tw-text-wrap
      tw-overflow-y-hidden
      tw-overflow-x-auto
      tw-scrollbar-thin
      "><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Singleton</span> <span class="k">private</span> <span class="k">constructor</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">companion</span> <span class="k">object</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">val</span> <span class="py">instance</span><span class="p">:</span> <span class="n">Singleton</span> <span class="k">by</span> <span class="n">lazy</span><span class="p">(</span><span class="n">mode</span> <span class="p">=</span> <span class="nc">LazyThreadSafetyMode</span><span class="p">.</span><span class="n">SYNCHRONIZED</span><span class="p">)</span> <span class="p">{</span> <span class="n">Singleton</span><span class="p">()</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre>
</div>
<h2 id="饿汉模式" class="headerLink">
    <a href="#%e9%a5%bf%e6%b1%89%e6%a8%a1%e5%bc%8f" class="header-mark"></a>饿汉模式</h2><p>对于单例的另一个模式那就是饿汉模式。而饿汉模式的名字由来是因为饿了就需要吃，所以提前就都准备好(初始化)。因为已经提前都初始化好了，所以也不存在上述的线程安全问题。</p>
<div class="code-block highlight is-open show-line-numbers  tw-group tw-my-2">
  <div class="
    
    tw-flex 
    tw-flex-row
    tw-flex-1 
    tw-justify-between 
    tw-w-full tw-bg-bgColor-secondary
    ">      
    <button 
      class="
        code-block-button
        tw-mx-2 
        tw-flex
        tw-flex-row
        tw-flex-1"
      aria-hidden="true">
          <div class="group-[.is-open]:tw-rotate-90 tw-transition-[transform] tw-duration-500 tw-ease-in-out print:!tw-hidden tw-w-min tw-h-min tw-my-1 tw-mx-1"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"/></svg></div>
          <p class="tw-select-none !tw-my-1">kotlin</p>
      </button>

   <div class="tw-flex">
      <button 
        class="
          line-number-button
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.show-line-numbers]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle line numbers"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M61.77 401l17.5-20.15a19.92 19.92 0 0 0 5.07-14.19v-3.31C84.34 356 80.5 352 73 352H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h22.83a157.41 157.41 0 0 0-11 12.31l-5.61 7c-4 5.07-5.25 10.13-2.8 14.88l1.05 1.93c3 5.76 6.29 7.88 12.25 7.88h4.73c10.33 0 15.94 2.44 15.94 9.09 0 4.72-4.2 8.22-14.36 8.22a41.54 41.54 0 0 1-15.47-3.12c-6.49-3.88-11.74-3.5-15.6 3.12l-5.59 9.31c-3.72 6.13-3.19 11.72 2.63 15.94 7.71 4.69 20.38 9.44 37 9.44 34.16 0 48.5-22.75 48.5-44.12-.03-14.38-9.12-29.76-28.73-34.88zM496 224H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM16 160h64a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H64V40a8 8 0 0 0-8-8H32a8 8 0 0 0-7.14 4.42l-8 16A8 8 0 0 0 24 64h8v64H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8zm-3.91 160H80a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H41.32c3.29-10.29 48.34-18.68 48.34-56.44 0-29.06-25-39.56-44.47-39.56-21.36 0-33.8 10-40.46 18.75-4.37 5.59-3 10.84 2.8 15.37l8.58 6.88c5.61 4.56 11 2.47 16.12-2.44a13.44 13.44 0 0 1 9.46-3.84c3.33 0 9.28 1.56 9.28 8.75C51 248.19 0 257.31 0 304.59v4C0 316 5.08 320 12.09 320z"/></svg></button>

      <button 
        class="
          wrap-code-button
          tw-select-none 
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.is-wrap]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle code wrap"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"/></svg></button>
      
      <button 
        class="
          copy-code-button
          tw-select-none
          tw-mx-2 
          tw-hidden
          group-[.is-open]:tw-block
          hover:tw-text-fgColor-link 
          print:!tw-hidden"
        title="Copy code">
          <span class="copy-icon tw-block"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"/></svg></span>
          <span class="check-icon tw-hidden"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"/></svg></span>
      </button>
        
      <button 
        class="
          tw-select-none 
          tw-mx-2 
          tw-block 
          group-[.is-open]:tw-hidden 
          print:!tw-hidden" 
        disabled
        aria-hidden="true"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"/></svg></button>
    </div>
  </div>
  <pre style="counter-reset: codeblock;" class="tw-block tw-m-0 tw-p-0"><code 
    id="codeblock-id-5" 
    class="
      chroma 
      !tw-block 
      tw-p-0
      tw-m-0
      tw-transition-[max-height] 
      tw-duration-500 
      tw-ease-in-out 
      group-[.is-closed]:!tw-max-h-0 
      group-[.is-wrap]:tw-text-wrap
      tw-overflow-y-hidden
      tw-overflow-x-auto
      tw-scrollbar-thin
      "><span class="line"><span class="cl"><span class="k">object</span> <span class="nc">Singleton</span></span></span></code></pre>
</div>
<h2 id="总结" class="headerLink">
    <a href="#%e6%80%bb%e7%bb%93" class="header-mark"></a>总结</h2><p>单例模式和其他创建型模式不同，单例更重要的是解决多次创建带来的性能上的问题。</p>
]]></description></item><item><title>抽象工厂模式</title><link>https://youngxhui.top/2020/03/%E6%8A%BD%E8%B1%A1%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F/</link><pubDate>Mon, 02 Mar 2020 17:58:01 +0800</pubDate><author><name>youngxhui</name></author><guid>https://youngxhui.top/2020/03/%E6%8A%BD%E8%B1%A1%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F/</guid><description><![CDATA[<p>抽象工厂模式也是一种创建型模式。它是为了创造<strong>一系列</strong>或者<strong>相互依赖</strong>的对象。这便是与之前的<a href="/2020/02/%e5%b7%a5%e5%8e%82%e6%a8%a1%e5%bc%8f/" rel="">工厂模式</a>不同的地方。抽象工厂模式和工厂模式要解决问题的出发点是一样，都是为了使类的创建者和使用者进行分离。</p>
<h2 id="工厂模式" class="headerLink">
    <a href="#%e5%b7%a5%e5%8e%82%e6%a8%a1%e5%bc%8f" class="header-mark"></a>工厂模式</h2><p>要做一个 window 和 scrollBar,但是要有两种风格，传统风格(standard)和高级定制风格(custom)。如果按照之前我们的工厂模式来进行的话。</p>
<div class="code-block highlight is-closed show-line-numbers  tw-group tw-my-2">
  <div class="
    
    tw-flex 
    tw-flex-row
    tw-flex-1 
    tw-justify-between 
    tw-w-full tw-bg-bgColor-secondary
    ">      
    <button 
      class="
        code-block-button
        tw-mx-2 
        tw-flex
        tw-flex-row
        tw-flex-1"
      aria-hidden="true">
          <div class="group-[.is-open]:tw-rotate-90 tw-transition-[transform] tw-duration-500 tw-ease-in-out print:!tw-hidden tw-w-min tw-h-min tw-my-1 tw-mx-1"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"/></svg></div>
          <p class="tw-select-none !tw-my-1">kotlin</p>
      </button>

   <div class="tw-flex">
      <button 
        class="
          line-number-button
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.show-line-numbers]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle line numbers"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M61.77 401l17.5-20.15a19.92 19.92 0 0 0 5.07-14.19v-3.31C84.34 356 80.5 352 73 352H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h22.83a157.41 157.41 0 0 0-11 12.31l-5.61 7c-4 5.07-5.25 10.13-2.8 14.88l1.05 1.93c3 5.76 6.29 7.88 12.25 7.88h4.73c10.33 0 15.94 2.44 15.94 9.09 0 4.72-4.2 8.22-14.36 8.22a41.54 41.54 0 0 1-15.47-3.12c-6.49-3.88-11.74-3.5-15.6 3.12l-5.59 9.31c-3.72 6.13-3.19 11.72 2.63 15.94 7.71 4.69 20.38 9.44 37 9.44 34.16 0 48.5-22.75 48.5-44.12-.03-14.38-9.12-29.76-28.73-34.88zM496 224H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM16 160h64a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H64V40a8 8 0 0 0-8-8H32a8 8 0 0 0-7.14 4.42l-8 16A8 8 0 0 0 24 64h8v64H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8zm-3.91 160H80a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H41.32c3.29-10.29 48.34-18.68 48.34-56.44 0-29.06-25-39.56-44.47-39.56-21.36 0-33.8 10-40.46 18.75-4.37 5.59-3 10.84 2.8 15.37l8.58 6.88c5.61 4.56 11 2.47 16.12-2.44a13.44 13.44 0 0 1 9.46-3.84c3.33 0 9.28 1.56 9.28 8.75C51 248.19 0 257.31 0 304.59v4C0 316 5.08 320 12.09 320z"/></svg></button>

      <button 
        class="
          wrap-code-button
          tw-select-none 
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.is-wrap]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle code wrap"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"/></svg></button>
      
      <button 
        class="
          copy-code-button
          tw-select-none
          tw-mx-2 
          tw-hidden
          group-[.is-open]:tw-block
          hover:tw-text-fgColor-link 
          print:!tw-hidden"
        title="Copy code">
          <span class="copy-icon tw-block"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"/></svg></span>
          <span class="check-icon tw-hidden"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"/></svg></span>
      </button>
        
      <button 
        class="
          tw-select-none 
          tw-mx-2 
          tw-block 
          group-[.is-open]:tw-hidden 
          print:!tw-hidden" 
        disabled
        aria-hidden="true"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"/></svg></button>
    </div>
  </div>
  <pre style="counter-reset: codeblock;" class="tw-block tw-m-0 tw-p-0"><code 
    id="codeblock-id-1" 
    class="
      chroma 
      !tw-block 
      tw-p-0
      tw-m-0
      tw-transition-[max-height] 
      tw-duration-500 
      tw-ease-in-out 
      group-[.is-closed]:!tw-max-h-0 
      group-[.is-wrap]:tw-text-wrap
      tw-overflow-y-hidden
      tw-overflow-x-auto
      tw-scrollbar-thin
      "><span class="line"><span class="cl"><span class="c1">// 定义 window 和 scrollBar 的接口
</span></span></span><span class="line"><span class="cl"><span class="k">interface</span> <span class="nc">Window</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">fun</span> <span class="nf">show</span><span class="p">(</span><span class="n">scrollBar</span><span class="p">:</span> <span class="n">ScrollBar</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">interface</span> <span class="nc">ScrollBar</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">fun</span> <span class="nf">scroll</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// 实现 标准窗口 和 标准滚动条
</span></span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">StandardWindow</span> <span class="p">:</span> <span class="n">Window</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">show</span><span class="p">(</span><span class="n">scrollBar</span><span class="p">:</span> <span class="n">ScrollBar</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">println</span><span class="p">(</span><span class="s2">&#34;标准窗口 </span><span class="si">${scrollBar.scroll()}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">StandardScrollBar</span> <span class="p">:</span> <span class="n">ScrollBar</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">scroll</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">println</span><span class="p">(</span><span class="s2">&#34;标准滚动条&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// 实现 定制化窗口 和 定制化滚动条
</span></span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">CustomWindow</span> <span class="p">:</span> <span class="n">Window</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">show</span><span class="p">(</span><span class="n">scrollBar</span><span class="p">:</span> <span class="n">ScrollBar</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">println</span><span class="p">(</span><span class="s2">&#34;定制窗口 </span><span class="si">${scrollBar.scroll()}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">CustomScrollBar</span> <span class="p">:</span> <span class="n">ScrollBar</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">scroll</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">println</span><span class="p">(</span><span class="s2">&#34;定制滚动条&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// 定制 window 工厂
</span></span></span><span class="line"><span class="cl"><span class="k">interface</span> <span class="nc">WindowFactory</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">fun</span> <span class="nf">create</span><span class="p">():</span> <span class="n">Window</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// 定制 scrollBar 工厂
</span></span></span><span class="line"><span class="cl"><span class="k">interface</span> <span class="nc">ScrollBarFactory</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">fun</span> <span class="nf">create</span><span class="p">():</span> <span class="n">ScrollBar</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// 产生 标准化窗口工厂
</span></span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">StandardWindowFactory</span> <span class="p">:</span> <span class="n">WindowFactory</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">create</span><span class="p">():</span> <span class="n">Window</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">StandardWindow</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// 产生 标准化滚动条工厂
</span></span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">StandardScrollBarFactory</span> <span class="p">:</span> <span class="n">ScrollBarFactory</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">create</span><span class="p">():</span> <span class="n">ScrollBar</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">StandardScrollBar</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// 产生 定制化窗口工厂
</span></span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">CustomWindowFactory</span> <span class="p">:</span> <span class="n">WindowFactory</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">create</span><span class="p">():</span> <span class="n">Window</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">CustomWindow</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// 产生 定制化滚动条工厂
</span></span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">CustomScrollBarFactory</span> <span class="p">:</span> <span class="n">ScrollBarFactory</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">create</span><span class="p">():</span> <span class="n">ScrollBar</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">CustomScrollBar</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">fun</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">val</span> <span class="py">windowFactory</span> <span class="p">=</span> <span class="n">StandardWindowFactory</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="k">val</span> <span class="py">barFactory</span> <span class="p">=</span> <span class="n">StandardScrollBarFactory</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="k">val</span> <span class="py">window</span> <span class="p">=</span> <span class="n">windowFactory</span><span class="p">.</span><span class="n">create</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="k">val</span> <span class="py">bar</span> <span class="p">=</span> <span class="n">barFactory</span><span class="p">.</span><span class="n">create</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="n">window</span><span class="p">.</span><span class="n">show</span><span class="p">(</span><span class="n">bar</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre>
</div>
<p>进行这样的调整，表面看是完成了功能的设计，也将对象的产生者和使用者分离，同时扩展性增强。但是，也出现了新的问题。如果使用不正确，或者客户端调用时一不留神，客户端的代码将可能成为标准窗口中出现定制滚动条，或者定制窗口中是标准滚动条。</p>
<div class="code-block highlight is-open show-line-numbers  tw-group tw-my-2">
  <div class="
    
    tw-flex 
    tw-flex-row
    tw-flex-1 
    tw-justify-between 
    tw-w-full tw-bg-bgColor-secondary
    ">      
    <button 
      class="
        code-block-button
        tw-mx-2 
        tw-flex
        tw-flex-row
        tw-flex-1"
      aria-hidden="true">
          <div class="group-[.is-open]:tw-rotate-90 tw-transition-[transform] tw-duration-500 tw-ease-in-out print:!tw-hidden tw-w-min tw-h-min tw-my-1 tw-mx-1"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"/></svg></div>
          <p class="tw-select-none !tw-my-1">kotlin</p>
      </button>

   <div class="tw-flex">
      <button 
        class="
          line-number-button
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.show-line-numbers]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle line numbers"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M61.77 401l17.5-20.15a19.92 19.92 0 0 0 5.07-14.19v-3.31C84.34 356 80.5 352 73 352H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h22.83a157.41 157.41 0 0 0-11 12.31l-5.61 7c-4 5.07-5.25 10.13-2.8 14.88l1.05 1.93c3 5.76 6.29 7.88 12.25 7.88h4.73c10.33 0 15.94 2.44 15.94 9.09 0 4.72-4.2 8.22-14.36 8.22a41.54 41.54 0 0 1-15.47-3.12c-6.49-3.88-11.74-3.5-15.6 3.12l-5.59 9.31c-3.72 6.13-3.19 11.72 2.63 15.94 7.71 4.69 20.38 9.44 37 9.44 34.16 0 48.5-22.75 48.5-44.12-.03-14.38-9.12-29.76-28.73-34.88zM496 224H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM16 160h64a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H64V40a8 8 0 0 0-8-8H32a8 8 0 0 0-7.14 4.42l-8 16A8 8 0 0 0 24 64h8v64H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8zm-3.91 160H80a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H41.32c3.29-10.29 48.34-18.68 48.34-56.44 0-29.06-25-39.56-44.47-39.56-21.36 0-33.8 10-40.46 18.75-4.37 5.59-3 10.84 2.8 15.37l8.58 6.88c5.61 4.56 11 2.47 16.12-2.44a13.44 13.44 0 0 1 9.46-3.84c3.33 0 9.28 1.56 9.28 8.75C51 248.19 0 257.31 0 304.59v4C0 316 5.08 320 12.09 320z"/></svg></button>

      <button 
        class="
          wrap-code-button
          tw-select-none 
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.is-wrap]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle code wrap"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"/></svg></button>
      
      <button 
        class="
          copy-code-button
          tw-select-none
          tw-mx-2 
          tw-hidden
          group-[.is-open]:tw-block
          hover:tw-text-fgColor-link 
          print:!tw-hidden"
        title="Copy code">
          <span class="copy-icon tw-block"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"/></svg></span>
          <span class="check-icon tw-hidden"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"/></svg></span>
      </button>
        
      <button 
        class="
          tw-select-none 
          tw-mx-2 
          tw-block 
          group-[.is-open]:tw-hidden 
          print:!tw-hidden" 
        disabled
        aria-hidden="true"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"/></svg></button>
    </div>
  </div>
  <pre style="counter-reset: codeblock;" class="tw-block tw-m-0 tw-p-0"><code 
    id="codeblock-id-2" 
    class="
      chroma 
      !tw-block 
      tw-p-0
      tw-m-0
      tw-transition-[max-height] 
      tw-duration-500 
      tw-ease-in-out 
      group-[.is-closed]:!tw-max-h-0 
      group-[.is-wrap]:tw-text-wrap
      tw-overflow-y-hidden
      tw-overflow-x-auto
      tw-scrollbar-thin
      "><span class="line"><span class="cl"><span class="k">fun</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">val</span> <span class="py">windowFactory</span> <span class="p">=</span> <span class="n">StandardWindowFactory</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="k">val</span> <span class="py">barFactory</span> <span class="p">=</span> <span class="n">CustomScrollBarFactory</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="k">val</span> <span class="py">window</span> <span class="p">=</span> <span class="n">windowFactory</span><span class="p">.</span><span class="n">create</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="k">val</span> <span class="py">bar</span> <span class="p">=</span> <span class="n">barFactory</span><span class="p">.</span><span class="n">create</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="n">window</span><span class="p">.</span><span class="n">show</span><span class="p">(</span><span class="n">bar</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre>
</div>
<p>按照这个情况来说，生成的对象并不是匹配的。所以我们要进行优化。</p>
<h2 id="工厂合并" class="headerLink">
    <a href="#%e5%b7%a5%e5%8e%82%e5%90%88%e5%b9%b6" class="header-mark"></a>工厂合并</h2><p>如果将相同的工厂合并在一起，那就不会出现当前的这样情况。将相同风格的界面存放到一个工厂内，这样就不会出现上述的混搭的问题。通过同样的一个工厂生成相同的一系列</p>
<div class="code-block highlight is-open show-line-numbers  tw-group tw-my-2">
  <div class="
    
    tw-flex 
    tw-flex-row
    tw-flex-1 
    tw-justify-between 
    tw-w-full tw-bg-bgColor-secondary
    ">      
    <button 
      class="
        code-block-button
        tw-mx-2 
        tw-flex
        tw-flex-row
        tw-flex-1"
      aria-hidden="true">
          <div class="group-[.is-open]:tw-rotate-90 tw-transition-[transform] tw-duration-500 tw-ease-in-out print:!tw-hidden tw-w-min tw-h-min tw-my-1 tw-mx-1"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"/></svg></div>
          <p class="tw-select-none !tw-my-1">kotlin</p>
      </button>

   <div class="tw-flex">
      <button 
        class="
          line-number-button
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.show-line-numbers]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle line numbers"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M61.77 401l17.5-20.15a19.92 19.92 0 0 0 5.07-14.19v-3.31C84.34 356 80.5 352 73 352H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h22.83a157.41 157.41 0 0 0-11 12.31l-5.61 7c-4 5.07-5.25 10.13-2.8 14.88l1.05 1.93c3 5.76 6.29 7.88 12.25 7.88h4.73c10.33 0 15.94 2.44 15.94 9.09 0 4.72-4.2 8.22-14.36 8.22a41.54 41.54 0 0 1-15.47-3.12c-6.49-3.88-11.74-3.5-15.6 3.12l-5.59 9.31c-3.72 6.13-3.19 11.72 2.63 15.94 7.71 4.69 20.38 9.44 37 9.44 34.16 0 48.5-22.75 48.5-44.12-.03-14.38-9.12-29.76-28.73-34.88zM496 224H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM16 160h64a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H64V40a8 8 0 0 0-8-8H32a8 8 0 0 0-7.14 4.42l-8 16A8 8 0 0 0 24 64h8v64H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8zm-3.91 160H80a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H41.32c3.29-10.29 48.34-18.68 48.34-56.44 0-29.06-25-39.56-44.47-39.56-21.36 0-33.8 10-40.46 18.75-4.37 5.59-3 10.84 2.8 15.37l8.58 6.88c5.61 4.56 11 2.47 16.12-2.44a13.44 13.44 0 0 1 9.46-3.84c3.33 0 9.28 1.56 9.28 8.75C51 248.19 0 257.31 0 304.59v4C0 316 5.08 320 12.09 320z"/></svg></button>

      <button 
        class="
          wrap-code-button
          tw-select-none 
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.is-wrap]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle code wrap"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"/></svg></button>
      
      <button 
        class="
          copy-code-button
          tw-select-none
          tw-mx-2 
          tw-hidden
          group-[.is-open]:tw-block
          hover:tw-text-fgColor-link 
          print:!tw-hidden"
        title="Copy code">
          <span class="copy-icon tw-block"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"/></svg></span>
          <span class="check-icon tw-hidden"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"/></svg></span>
      </button>
        
      <button 
        class="
          tw-select-none 
          tw-mx-2 
          tw-block 
          group-[.is-open]:tw-hidden 
          print:!tw-hidden" 
        disabled
        aria-hidden="true"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"/></svg></button>
    </div>
  </div>
  <pre style="counter-reset: codeblock;" class="tw-block tw-m-0 tw-p-0"><code 
    id="codeblock-id-3" 
    class="
      chroma 
      !tw-block 
      tw-p-0
      tw-m-0
      tw-transition-[max-height] 
      tw-duration-500 
      tw-ease-in-out 
      group-[.is-closed]:!tw-max-h-0 
      group-[.is-wrap]:tw-text-wrap
      tw-overflow-y-hidden
      tw-overflow-x-auto
      tw-scrollbar-thin
      "><span class="line"><span class="cl"><span class="k">interface</span> <span class="nc">Factory</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">fun</span> <span class="nf">createBar</span><span class="p">():</span> <span class="n">ScrollBar</span>
</span></span><span class="line"><span class="cl">    <span class="k">fun</span> <span class="nf">createWindow</span><span class="p">():</span> <span class="n">Window</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">CustomFactory</span> <span class="p">:</span> <span class="n">Factory</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">createBar</span><span class="p">():</span> <span class="n">ScrollBar</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">CustomScrollBar</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">createWindow</span><span class="p">():</span> <span class="n">Window</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">CustomWindow</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">StandardFactory</span><span class="p">:</span><span class="n">Factory</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">createBar</span><span class="p">():</span> <span class="n">ScrollBar</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">StandardScrollBar</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">createWindow</span><span class="p">():</span> <span class="n">Window</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">StandardWindow</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre>
</div>
<p>当工厂完成合并的时候，这样通过一个工厂就可以创造出一系列相关的类。</p>
<p>同时完成了在运行时完对工厂和具体类的依赖，而在编译时不会产生依赖，从而进一步进行了解耦。之前的工厂模式更像是抽象工厂模式的特例，每个工厂只生产一类型产品。</p>
]]></description></item><item><title>工厂模式</title><link>https://youngxhui.top/2020/02/%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F/</link><pubDate>Sat, 29 Feb 2020 21:17:50 +0800</pubDate><author><name>youngxhui</name></author><guid>https://youngxhui.top/2020/02/%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F/</guid><description><![CDATA[<p>工厂模式是一种对象创造模式。定义一个用户创建对象的接口，让子类决定实例化那些类。</p>
<p>将对象的创建和使用过程分开，并且有时候创建一个对象并不只是单独的调用其类构造函数，我们可能需要进行很多初始化的设置，这样势必会出现代码重复的问题。以后进行修改时，需要多处修改，从而增加维护难度。</p>
<h2 id="参数化工厂" class="headerLink">
    <a href="#%e5%8f%82%e6%95%b0%e5%8c%96%e5%b7%a5%e5%8e%82" class="header-mark"></a>参数化工厂</h2><p>有些地方也叫做个这个方法为<strong>简单工厂模式</strong>。该模式使得工厂方法可以创建多种产品。采用一个标识要被创建的对象种类,，通过标识来让工厂确定创造哪个类。</p>
<div class="code-block highlight is-closed show-line-numbers  tw-group tw-my-2">
  <div class="
    
    tw-flex 
    tw-flex-row
    tw-flex-1 
    tw-justify-between 
    tw-w-full tw-bg-bgColor-secondary
    ">      
    <button 
      class="
        code-block-button
        tw-mx-2 
        tw-flex
        tw-flex-row
        tw-flex-1"
      aria-hidden="true">
          <div class="group-[.is-open]:tw-rotate-90 tw-transition-[transform] tw-duration-500 tw-ease-in-out print:!tw-hidden tw-w-min tw-h-min tw-my-1 tw-mx-1"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"/></svg></div>
          <p class="tw-select-none !tw-my-1">kotlin</p>
      </button>

   <div class="tw-flex">
      <button 
        class="
          line-number-button
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.show-line-numbers]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle line numbers"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M61.77 401l17.5-20.15a19.92 19.92 0 0 0 5.07-14.19v-3.31C84.34 356 80.5 352 73 352H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h22.83a157.41 157.41 0 0 0-11 12.31l-5.61 7c-4 5.07-5.25 10.13-2.8 14.88l1.05 1.93c3 5.76 6.29 7.88 12.25 7.88h4.73c10.33 0 15.94 2.44 15.94 9.09 0 4.72-4.2 8.22-14.36 8.22a41.54 41.54 0 0 1-15.47-3.12c-6.49-3.88-11.74-3.5-15.6 3.12l-5.59 9.31c-3.72 6.13-3.19 11.72 2.63 15.94 7.71 4.69 20.38 9.44 37 9.44 34.16 0 48.5-22.75 48.5-44.12-.03-14.38-9.12-29.76-28.73-34.88zM496 224H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM16 160h64a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H64V40a8 8 0 0 0-8-8H32a8 8 0 0 0-7.14 4.42l-8 16A8 8 0 0 0 24 64h8v64H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8zm-3.91 160H80a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H41.32c3.29-10.29 48.34-18.68 48.34-56.44 0-29.06-25-39.56-44.47-39.56-21.36 0-33.8 10-40.46 18.75-4.37 5.59-3 10.84 2.8 15.37l8.58 6.88c5.61 4.56 11 2.47 16.12-2.44a13.44 13.44 0 0 1 9.46-3.84c3.33 0 9.28 1.56 9.28 8.75C51 248.19 0 257.31 0 304.59v4C0 316 5.08 320 12.09 320z"/></svg></button>

      <button 
        class="
          wrap-code-button
          tw-select-none 
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.is-wrap]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle code wrap"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"/></svg></button>
      
      <button 
        class="
          copy-code-button
          tw-select-none
          tw-mx-2 
          tw-hidden
          group-[.is-open]:tw-block
          hover:tw-text-fgColor-link 
          print:!tw-hidden"
        title="Copy code">
          <span class="copy-icon tw-block"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"/></svg></span>
          <span class="check-icon tw-hidden"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"/></svg></span>
      </button>
        
      <button 
        class="
          tw-select-none 
          tw-mx-2 
          tw-block 
          group-[.is-open]:tw-hidden 
          print:!tw-hidden" 
        disabled
        aria-hidden="true"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"/></svg></button>
    </div>
  </div>
  <pre style="counter-reset: codeblock;" class="tw-block tw-m-0 tw-p-0"><code 
    id="codeblock-id-1" 
    class="
      chroma 
      !tw-block 
      tw-p-0
      tw-m-0
      tw-transition-[max-height] 
      tw-duration-500 
      tw-ease-in-out 
      group-[.is-closed]:!tw-max-h-0 
      group-[.is-wrap]:tw-text-wrap
      tw-overflow-y-hidden
      tw-overflow-x-auto
      tw-scrollbar-thin
      "><span class="line"><span class="cl"><span class="k">interface</span> <span class="nc">Product</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">fun</span> <span class="nf">show</span><span class="p">();</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">MyProduct</span> <span class="p">:</span> <span class="n">Product</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">show</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">println</span><span class="p">(</span><span class="s2">&#34;my product&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">YourProduct</span> <span class="p">:</span> <span class="n">Product</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">show</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">println</span><span class="p">(</span><span class="s2">&#34;your product&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">OtherProduct</span> <span class="p">:</span> <span class="n">Product</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">show</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">println</span><span class="p">(</span><span class="s2">&#34;other product&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">ProductFactory</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">fun</span> <span class="nf">create</span><span class="p">(</span><span class="n">name</span><span class="p">:</span> <span class="n">String</span><span class="p">):</span> <span class="n">Product</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="k">when</span> <span class="p">(</span><span class="n">name</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="s2">&#34;my&#34;</span> <span class="o">-&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="n">MyProduct</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">            <span class="s2">&#34;your&#34;</span> <span class="o">-&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="n">YourProduct</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">            <span class="k">else</span> <span class="o">-&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="n">OtherProduct</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">fun</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">val</span> <span class="py">factory</span> <span class="p">=</span> <span class="n">ProductFactory</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="k">val</span> <span class="py">product</span> <span class="p">=</span> <span class="n">factory</span><span class="p">.</span><span class="n">create</span><span class="p">(</span><span class="s2">&#34;my&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">product</span><span class="p">.</span><span class="n">show</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre>
</div>
<p>那么如果之后需要继续增加或减少一个产品，那么就需要在 <code>ProductFactory</code> 中 <code>when</code> 语句进行更改。看似简单的操作，其实已经违反了我们的设计原则<strong>开闭原则</strong>，对修改应该是关闭的。所以说简单工厂模式是存在一定的缺陷的，并不能符合我们日后的扩展性。</p>
<h2 id="工厂模式" class="headerLink">
    <a href="#%e5%b7%a5%e5%8e%82%e6%a8%a1%e5%bc%8f" class="header-mark"></a>工厂模式</h2><p>针对上述问题，我们可以采取不同的方式去实现。来符合开闭原则。针对不同的 <code>Product</code> 采用不同的工厂方法。通过 <code>Factory</code> 接口来设定子类工厂。这样通过客户端的调用，便可以完成对象的产生。</p>
<div class="code-block highlight is-closed show-line-numbers  tw-group tw-my-2">
  <div class="
    
    tw-flex 
    tw-flex-row
    tw-flex-1 
    tw-justify-between 
    tw-w-full tw-bg-bgColor-secondary
    ">      
    <button 
      class="
        code-block-button
        tw-mx-2 
        tw-flex
        tw-flex-row
        tw-flex-1"
      aria-hidden="true">
          <div class="group-[.is-open]:tw-rotate-90 tw-transition-[transform] tw-duration-500 tw-ease-in-out print:!tw-hidden tw-w-min tw-h-min tw-my-1 tw-mx-1"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"/></svg></div>
          <p class="tw-select-none !tw-my-1">kotlin</p>
      </button>

   <div class="tw-flex">
      <button 
        class="
          line-number-button
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.show-line-numbers]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle line numbers"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M61.77 401l17.5-20.15a19.92 19.92 0 0 0 5.07-14.19v-3.31C84.34 356 80.5 352 73 352H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h22.83a157.41 157.41 0 0 0-11 12.31l-5.61 7c-4 5.07-5.25 10.13-2.8 14.88l1.05 1.93c3 5.76 6.29 7.88 12.25 7.88h4.73c10.33 0 15.94 2.44 15.94 9.09 0 4.72-4.2 8.22-14.36 8.22a41.54 41.54 0 0 1-15.47-3.12c-6.49-3.88-11.74-3.5-15.6 3.12l-5.59 9.31c-3.72 6.13-3.19 11.72 2.63 15.94 7.71 4.69 20.38 9.44 37 9.44 34.16 0 48.5-22.75 48.5-44.12-.03-14.38-9.12-29.76-28.73-34.88zM496 224H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM16 160h64a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H64V40a8 8 0 0 0-8-8H32a8 8 0 0 0-7.14 4.42l-8 16A8 8 0 0 0 24 64h8v64H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8zm-3.91 160H80a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H41.32c3.29-10.29 48.34-18.68 48.34-56.44 0-29.06-25-39.56-44.47-39.56-21.36 0-33.8 10-40.46 18.75-4.37 5.59-3 10.84 2.8 15.37l8.58 6.88c5.61 4.56 11 2.47 16.12-2.44a13.44 13.44 0 0 1 9.46-3.84c3.33 0 9.28 1.56 9.28 8.75C51 248.19 0 257.31 0 304.59v4C0 316 5.08 320 12.09 320z"/></svg></button>

      <button 
        class="
          wrap-code-button
          tw-select-none 
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.is-wrap]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle code wrap"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"/></svg></button>
      
      <button 
        class="
          copy-code-button
          tw-select-none
          tw-mx-2 
          tw-hidden
          group-[.is-open]:tw-block
          hover:tw-text-fgColor-link 
          print:!tw-hidden"
        title="Copy code">
          <span class="copy-icon tw-block"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"/></svg></span>
          <span class="check-icon tw-hidden"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"/></svg></span>
      </button>
        
      <button 
        class="
          tw-select-none 
          tw-mx-2 
          tw-block 
          group-[.is-open]:tw-hidden 
          print:!tw-hidden" 
        disabled
        aria-hidden="true"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"/></svg></button>
    </div>
  </div>
  <pre style="counter-reset: codeblock;" class="tw-block tw-m-0 tw-p-0"><code 
    id="codeblock-id-2" 
    class="
      chroma 
      !tw-block 
      tw-p-0
      tw-m-0
      tw-transition-[max-height] 
      tw-duration-500 
      tw-ease-in-out 
      group-[.is-closed]:!tw-max-h-0 
      group-[.is-wrap]:tw-text-wrap
      tw-overflow-y-hidden
      tw-overflow-x-auto
      tw-scrollbar-thin
      "><span class="line"><span class="cl"><span class="k">interface</span> <span class="nc">Product</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">fun</span> <span class="nf">show</span><span class="p">();</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">interface</span> <span class="nc">Factory</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">fun</span> <span class="nf">create</span><span class="p">():</span> <span class="n">Product</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">MyProduct</span> <span class="p">:</span> <span class="n">Product</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">show</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">println</span><span class="p">(</span><span class="s2">&#34;my product&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">MyProductFactory</span> <span class="p">:</span> <span class="n">Factory</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">create</span><span class="p">():</span> <span class="n">Product</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">val</span> <span class="py">product</span> <span class="p">=</span> <span class="n">MyProduct</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">        <span class="c1">// 其他初始化操作
</span></span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">product</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">YourProduct</span> <span class="p">:</span> <span class="n">Product</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">show</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">println</span><span class="p">(</span><span class="s2">&#34;your product&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">YourProductFactory</span> <span class="p">:</span> <span class="n">Factory</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">create</span><span class="p">():</span> <span class="n">Product</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">val</span> <span class="py">product</span> <span class="p">=</span> <span class="n">YourProduct</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">        <span class="c1">// 其他初始化操作
</span></span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">product</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">OtherProduct</span> <span class="p">:</span> <span class="n">Product</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">show</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">println</span><span class="p">(</span><span class="s2">&#34;other product&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">OtherProductFactory</span> <span class="p">:</span> <span class="n">Factory</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">create</span><span class="p">():</span> <span class="n">Product</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">val</span> <span class="py">product</span> <span class="p">=</span> <span class="n">OtherProduct</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">        <span class="c1">// 其他初始化操作
</span></span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">product</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">fun</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">val</span> <span class="py">factory</span> <span class="p">=</span> <span class="n">YourProductFactory</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="k">val</span> <span class="py">product</span> <span class="p">=</span> <span class="n">factory</span><span class="p">.</span><span class="n">create</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="n">product</span><span class="p">.</span><span class="n">show</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre>
</div>
<h2 id="uml" class="headerLink">
    <a href="#uml" class="header-mark"></a>UML</h2><p><img class="tw-inline" loading="lazy" src='https://island-hexo.oss-cn-beijing.aliyuncs.com/factory.jpg'     ></p>
<p>无论是参数化方法的工厂模式，还是通过单独的工厂去逐步生成，都做到了使用者和生产者的解耦。同时工厂模式还对开闭原则做了很好的完善。</p>
]]></description></item><item><title>装饰模式</title><link>https://youngxhui.top/2020/02/%E8%A3%85%E9%A5%B0%E6%A8%A1%E5%BC%8F/</link><pubDate>Tue, 25 Feb 2020 21:48:13 +0800</pubDate><author><name>youngxhui</name></author><guid>https://youngxhui.top/2020/02/%E8%A3%85%E9%A5%B0%E6%A8%A1%E5%BC%8F/</guid><description><![CDATA[<blockquote>
  <p>动态的给一个对象添加一些额外的职责。就增加功能来说，Decorator模式现必生成子类更加灵活。&ndash;GOF 设计模式</p>

</blockquote><p>该设计模式是让子类更加灵活，给某个<strong>对象</strong>而不是<strong>类</strong>添加功能。</p>
<h2 id="坏代码" class="headerLink">
    <a href="#%e5%9d%8f%e4%bb%a3%e7%a0%81" class="header-mark"></a>坏代码</h2><p>例如当前有一个流操作(Stream)，分别有文件流(FileStream)、内存流(NetStream),而我们分别要对这些流进行编码(Ascii7)和压缩(Compressing) 或者还要编码和压缩一起搞，如果我们按照正常思维来写的话，将会产生很多很多的类，UML如下：</p>
<p><img class="tw-inline" loading="lazy" src='https://island-hexo.oss-cn-beijing.aliyuncs.com/decorator-no-design-uml.jpg'     ></p>
<p>如果按照这种思维，以后再给流继续添加功能，有着更多功能的组合，那么就会产生更多的类，并随着日后代码的扩展，子类会不断的膨胀。这些类除了部分功能不同外，基本代码都极其相似。</p>
<div class="code-block highlight is-closed show-line-numbers  tw-group tw-my-2">
  <div class="
    
    tw-flex 
    tw-flex-row
    tw-flex-1 
    tw-justify-between 
    tw-w-full tw-bg-bgColor-secondary
    ">      
    <button 
      class="
        code-block-button
        tw-mx-2 
        tw-flex
        tw-flex-row
        tw-flex-1"
      aria-hidden="true">
          <div class="group-[.is-open]:tw-rotate-90 tw-transition-[transform] tw-duration-500 tw-ease-in-out print:!tw-hidden tw-w-min tw-h-min tw-my-1 tw-mx-1"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"/></svg></div>
          <p class="tw-select-none !tw-my-1">kotlin</p>
      </button>

   <div class="tw-flex">
      <button 
        class="
          line-number-button
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.show-line-numbers]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle line numbers"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M61.77 401l17.5-20.15a19.92 19.92 0 0 0 5.07-14.19v-3.31C84.34 356 80.5 352 73 352H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h22.83a157.41 157.41 0 0 0-11 12.31l-5.61 7c-4 5.07-5.25 10.13-2.8 14.88l1.05 1.93c3 5.76 6.29 7.88 12.25 7.88h4.73c10.33 0 15.94 2.44 15.94 9.09 0 4.72-4.2 8.22-14.36 8.22a41.54 41.54 0 0 1-15.47-3.12c-6.49-3.88-11.74-3.5-15.6 3.12l-5.59 9.31c-3.72 6.13-3.19 11.72 2.63 15.94 7.71 4.69 20.38 9.44 37 9.44 34.16 0 48.5-22.75 48.5-44.12-.03-14.38-9.12-29.76-28.73-34.88zM496 224H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM16 160h64a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H64V40a8 8 0 0 0-8-8H32a8 8 0 0 0-7.14 4.42l-8 16A8 8 0 0 0 24 64h8v64H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8zm-3.91 160H80a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H41.32c3.29-10.29 48.34-18.68 48.34-56.44 0-29.06-25-39.56-44.47-39.56-21.36 0-33.8 10-40.46 18.75-4.37 5.59-3 10.84 2.8 15.37l8.58 6.88c5.61 4.56 11 2.47 16.12-2.44a13.44 13.44 0 0 1 9.46-3.84c3.33 0 9.28 1.56 9.28 8.75C51 248.19 0 257.31 0 304.59v4C0 316 5.08 320 12.09 320z"/></svg></button>

      <button 
        class="
          wrap-code-button
          tw-select-none 
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.is-wrap]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle code wrap"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"/></svg></button>
      
      <button 
        class="
          copy-code-button
          tw-select-none
          tw-mx-2 
          tw-hidden
          group-[.is-open]:tw-block
          hover:tw-text-fgColor-link 
          print:!tw-hidden"
        title="Copy code">
          <span class="copy-icon tw-block"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"/></svg></span>
          <span class="check-icon tw-hidden"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"/></svg></span>
      </button>
        
      <button 
        class="
          tw-select-none 
          tw-mx-2 
          tw-block 
          group-[.is-open]:tw-hidden 
          print:!tw-hidden" 
        disabled
        aria-hidden="true"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"/></svg></button>
    </div>
  </div>
  <pre style="counter-reset: codeblock;" class="tw-block tw-m-0 tw-p-0"><code 
    id="codeblock-id-1" 
    class="
      chroma 
      !tw-block 
      tw-p-0
      tw-m-0
      tw-transition-[max-height] 
      tw-duration-500 
      tw-ease-in-out 
      group-[.is-closed]:!tw-max-h-0 
      group-[.is-wrap]:tw-text-wrap
      tw-overflow-y-hidden
      tw-overflow-x-auto
      tw-scrollbar-thin
      "><span class="line"><span class="cl"><span class="k">interface</span> <span class="nc">Stream</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">fun</span> <span class="nf">read</span><span class="p">(</span><span class="n">path</span><span class="p">:</span> <span class="n">String</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">open</span> <span class="k">class</span> <span class="nc">FileStream</span> <span class="p">:</span> <span class="n">Stream</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">read</span><span class="p">(</span><span class="n">path</span><span class="p">:</span> <span class="n">String</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">println</span><span class="p">(</span><span class="s2">&#34;FileStream.read </span><span class="si">$path</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">open</span> <span class="k">class</span> <span class="nc">MemoryStream</span> <span class="p">:</span> <span class="n">Stream</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">read</span><span class="p">(</span><span class="n">path</span><span class="p">:</span> <span class="n">String</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">println</span><span class="p">(</span><span class="s2">&#34;MemoryStream.read </span><span class="si">$path</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Ascii7FileStream</span> <span class="p">:</span> <span class="n">FileStream</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">read</span><span class="p">(</span><span class="n">path</span><span class="p">:</span> <span class="n">String</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">println</span><span class="p">(</span><span class="s2">&#34;编码&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">super</span><span class="p">.</span><span class="n">read</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Ascii7MemoryStream</span> <span class="p">:</span> <span class="n">MemoryStream</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">read</span><span class="p">(</span><span class="n">path</span><span class="p">:</span> <span class="n">String</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">println</span><span class="p">(</span><span class="s2">&#34;编码&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">super</span><span class="p">.</span><span class="n">read</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">CompressingFileStream</span> <span class="p">:</span> <span class="n">FileStream</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">read</span><span class="p">(</span><span class="n">path</span><span class="p">:</span> <span class="n">String</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">println</span><span class="p">(</span><span class="s2">&#34;压缩&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">super</span><span class="p">.</span><span class="n">read</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">CompressingMemoryStream</span> <span class="p">:</span> <span class="n">MemoryStream</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">read</span><span class="p">(</span><span class="n">path</span><span class="p">:</span> <span class="n">String</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">println</span><span class="p">(</span><span class="s2">&#34;压缩&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">super</span><span class="p">.</span><span class="n">read</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">CompressingAscii7FileStream</span> <span class="p">:</span> <span class="n">FileStream</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">read</span><span class="p">(</span><span class="n">path</span><span class="p">:</span> <span class="n">String</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">println</span><span class="p">(</span><span class="s2">&#34;压缩&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">println</span><span class="p">(</span><span class="s2">&#34;编码&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">super</span><span class="p">.</span><span class="n">read</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">CompressingAscii7MemoryStream</span> <span class="p">:</span> <span class="n">MemoryStream</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">read</span><span class="p">(</span><span class="n">path</span><span class="p">:</span> <span class="n">String</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">println</span><span class="p">(</span><span class="s2">&#34;压缩&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">println</span><span class="p">(</span><span class="s2">&#34;编码&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">super</span><span class="p">.</span><span class="n">read</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre>
</div>
<h2 id="划分职责" class="headerLink">
    <a href="#%e5%88%92%e5%88%86%e8%81%8c%e8%b4%a3" class="header-mark"></a>划分职责</h2><p>此时，可以看到类<code>Ascii7FileStream</code> 和 <code>Ascii7MemoryStream</code> 的 <code>read</code> 操作中编码操作是相同的，唯一的不同仅仅是流的读取，一个是从文件读取，一个是从内存读取。产生了代码的冗余，不断的重复。而针对不同点 20 行和 27 行也不是完全的不同。</p>
<p>稍微进行一下代码的修改，将继承改为组合。</p>
<div class="code-block highlight is-open show-line-numbers  tw-group tw-my-2">
  <div class="
    
    tw-flex 
    tw-flex-row
    tw-flex-1 
    tw-justify-between 
    tw-w-full tw-bg-bgColor-secondary
    ">      
    <button 
      class="
        code-block-button
        tw-mx-2 
        tw-flex
        tw-flex-row
        tw-flex-1"
      aria-hidden="true">
          <div class="group-[.is-open]:tw-rotate-90 tw-transition-[transform] tw-duration-500 tw-ease-in-out print:!tw-hidden tw-w-min tw-h-min tw-my-1 tw-mx-1"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"/></svg></div>
          <p class="tw-select-none !tw-my-1">kotlin</p>
      </button>

   <div class="tw-flex">
      <button 
        class="
          line-number-button
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.show-line-numbers]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle line numbers"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M61.77 401l17.5-20.15a19.92 19.92 0 0 0 5.07-14.19v-3.31C84.34 356 80.5 352 73 352H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h22.83a157.41 157.41 0 0 0-11 12.31l-5.61 7c-4 5.07-5.25 10.13-2.8 14.88l1.05 1.93c3 5.76 6.29 7.88 12.25 7.88h4.73c10.33 0 15.94 2.44 15.94 9.09 0 4.72-4.2 8.22-14.36 8.22a41.54 41.54 0 0 1-15.47-3.12c-6.49-3.88-11.74-3.5-15.6 3.12l-5.59 9.31c-3.72 6.13-3.19 11.72 2.63 15.94 7.71 4.69 20.38 9.44 37 9.44 34.16 0 48.5-22.75 48.5-44.12-.03-14.38-9.12-29.76-28.73-34.88zM496 224H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM16 160h64a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H64V40a8 8 0 0 0-8-8H32a8 8 0 0 0-7.14 4.42l-8 16A8 8 0 0 0 24 64h8v64H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8zm-3.91 160H80a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H41.32c3.29-10.29 48.34-18.68 48.34-56.44 0-29.06-25-39.56-44.47-39.56-21.36 0-33.8 10-40.46 18.75-4.37 5.59-3 10.84 2.8 15.37l8.58 6.88c5.61 4.56 11 2.47 16.12-2.44a13.44 13.44 0 0 1 9.46-3.84c3.33 0 9.28 1.56 9.28 8.75C51 248.19 0 257.31 0 304.59v4C0 316 5.08 320 12.09 320z"/></svg></button>

      <button 
        class="
          wrap-code-button
          tw-select-none 
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.is-wrap]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle code wrap"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"/></svg></button>
      
      <button 
        class="
          copy-code-button
          tw-select-none
          tw-mx-2 
          tw-hidden
          group-[.is-open]:tw-block
          hover:tw-text-fgColor-link 
          print:!tw-hidden"
        title="Copy code">
          <span class="copy-icon tw-block"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"/></svg></span>
          <span class="check-icon tw-hidden"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"/></svg></span>
      </button>
        
      <button 
        class="
          tw-select-none 
          tw-mx-2 
          tw-block 
          group-[.is-open]:tw-hidden 
          print:!tw-hidden" 
        disabled
        aria-hidden="true"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"/></svg></button>
    </div>
  </div>
  <pre style="counter-reset: codeblock;" class="tw-block tw-m-0 tw-p-0"><code 
    id="codeblock-id-2" 
    class="
      chroma 
      !tw-block 
      tw-p-0
      tw-m-0
      tw-transition-[max-height] 
      tw-duration-500 
      tw-ease-in-out 
      group-[.is-closed]:!tw-max-h-0 
      group-[.is-wrap]:tw-text-wrap
      tw-overflow-y-hidden
      tw-overflow-x-auto
      tw-scrollbar-thin
      "><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Ascii7FileStream</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">private</span> <span class="k">lateinit</span> <span class="k">var</span> <span class="py">stream</span><span class="p">:</span> <span class="n">FileStream</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">read</span><span class="p">(</span><span class="n">path</span><span class="p">:</span> <span class="n">String</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">println</span><span class="p">(</span><span class="s2">&#34;编码&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">stream</span><span class="p">.</span><span class="n">read</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Ascii7MemoryStream</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">private</span> <span class="k">lateinit</span> <span class="k">var</span> <span class="py">stream</span><span class="p">:</span> <span class="n">MemoryStream</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">read</span><span class="p">(</span><span class="n">path</span><span class="p">:</span> <span class="n">String</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">println</span><span class="p">(</span><span class="s2">&#34;编码&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">stream</span><span class="p">.</span><span class="n">read</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre>
</div>
<p>经过修改的代码，发现针对 <code>read</code> 方法的不同点，此刻也成为了相同点。我们并没有修改了代码的功能，仍旧是原来的功能。而此刻 <code>FileStream</code> 和 <code>MemoryStream</code> 都有公共的父类，那么就可以接着进行修改，将<strong>编译时</strong>依赖，修改为<strong>运行时</strong>依赖。让代码在运行时在确定具体的类型(多态)。</p>
<div class="code-block highlight is-open show-line-numbers  tw-group tw-my-2">
  <div class="
    
    tw-flex 
    tw-flex-row
    tw-flex-1 
    tw-justify-between 
    tw-w-full tw-bg-bgColor-secondary
    ">      
    <button 
      class="
        code-block-button
        tw-mx-2 
        tw-flex
        tw-flex-row
        tw-flex-1"
      aria-hidden="true">
          <div class="group-[.is-open]:tw-rotate-90 tw-transition-[transform] tw-duration-500 tw-ease-in-out print:!tw-hidden tw-w-min tw-h-min tw-my-1 tw-mx-1"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"/></svg></div>
          <p class="tw-select-none !tw-my-1">kotlin</p>
      </button>

   <div class="tw-flex">
      <button 
        class="
          line-number-button
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.show-line-numbers]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle line numbers"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M61.77 401l17.5-20.15a19.92 19.92 0 0 0 5.07-14.19v-3.31C84.34 356 80.5 352 73 352H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h22.83a157.41 157.41 0 0 0-11 12.31l-5.61 7c-4 5.07-5.25 10.13-2.8 14.88l1.05 1.93c3 5.76 6.29 7.88 12.25 7.88h4.73c10.33 0 15.94 2.44 15.94 9.09 0 4.72-4.2 8.22-14.36 8.22a41.54 41.54 0 0 1-15.47-3.12c-6.49-3.88-11.74-3.5-15.6 3.12l-5.59 9.31c-3.72 6.13-3.19 11.72 2.63 15.94 7.71 4.69 20.38 9.44 37 9.44 34.16 0 48.5-22.75 48.5-44.12-.03-14.38-9.12-29.76-28.73-34.88zM496 224H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM16 160h64a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H64V40a8 8 0 0 0-8-8H32a8 8 0 0 0-7.14 4.42l-8 16A8 8 0 0 0 24 64h8v64H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8zm-3.91 160H80a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H41.32c3.29-10.29 48.34-18.68 48.34-56.44 0-29.06-25-39.56-44.47-39.56-21.36 0-33.8 10-40.46 18.75-4.37 5.59-3 10.84 2.8 15.37l8.58 6.88c5.61 4.56 11 2.47 16.12-2.44a13.44 13.44 0 0 1 9.46-3.84c3.33 0 9.28 1.56 9.28 8.75C51 248.19 0 257.31 0 304.59v4C0 316 5.08 320 12.09 320z"/></svg></button>

      <button 
        class="
          wrap-code-button
          tw-select-none 
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.is-wrap]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle code wrap"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"/></svg></button>
      
      <button 
        class="
          copy-code-button
          tw-select-none
          tw-mx-2 
          tw-hidden
          group-[.is-open]:tw-block
          hover:tw-text-fgColor-link 
          print:!tw-hidden"
        title="Copy code">
          <span class="copy-icon tw-block"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"/></svg></span>
          <span class="check-icon tw-hidden"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"/></svg></span>
      </button>
        
      <button 
        class="
          tw-select-none 
          tw-mx-2 
          tw-block 
          group-[.is-open]:tw-hidden 
          print:!tw-hidden" 
        disabled
        aria-hidden="true"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"/></svg></button>
    </div>
  </div>
  <pre style="counter-reset: codeblock;" class="tw-block tw-m-0 tw-p-0"><code 
    id="codeblock-id-3" 
    class="
      chroma 
      !tw-block 
      tw-p-0
      tw-m-0
      tw-transition-[max-height] 
      tw-duration-500 
      tw-ease-in-out 
      group-[.is-closed]:!tw-max-h-0 
      group-[.is-wrap]:tw-text-wrap
      tw-overflow-y-hidden
      tw-overflow-x-auto
      tw-scrollbar-thin
      "><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Ascii7FileStream</span><span class="p">(</span><span class="k">private</span> <span class="k">var</span> <span class="py">stream</span><span class="p">:</span> <span class="n">Stream</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">read</span><span class="p">(</span><span class="n">path</span><span class="p">:</span> <span class="n">String</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">println</span><span class="p">(</span><span class="s2">&#34;编码&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">stream</span><span class="p">.</span><span class="n">read</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Ascii7MemoryStream</span><span class="p">(</span><span class="k">private</span> <span class="k">var</span> <span class="py">stream</span><span class="p">:</span> <span class="n">Stream</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">read</span><span class="p">(</span><span class="n">path</span><span class="p">:</span> <span class="n">String</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">println</span><span class="p">(</span><span class="s2">&#34;编码&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">stream</span><span class="p">.</span><span class="n">read</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre>
</div>
<p>此时，<code>Ascii7FIleStream</code> 和 <code>Ascii7MemoryStream</code> 已经变得完全一样，此刻我们也不再需要两个类，只需要一个类 <code>Ascii7Stream</code>。同理，针对压缩类也可以合并为一个类 <code>CompressingStream</code>。</p>
<div class="code-block highlight is-open show-line-numbers  tw-group tw-my-2">
  <div class="
    
    tw-flex 
    tw-flex-row
    tw-flex-1 
    tw-justify-between 
    tw-w-full tw-bg-bgColor-secondary
    ">      
    <button 
      class="
        code-block-button
        tw-mx-2 
        tw-flex
        tw-flex-row
        tw-flex-1"
      aria-hidden="true">
          <div class="group-[.is-open]:tw-rotate-90 tw-transition-[transform] tw-duration-500 tw-ease-in-out print:!tw-hidden tw-w-min tw-h-min tw-my-1 tw-mx-1"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"/></svg></div>
          <p class="tw-select-none !tw-my-1">kotlin</p>
      </button>

   <div class="tw-flex">
      <button 
        class="
          line-number-button
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.show-line-numbers]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle line numbers"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M61.77 401l17.5-20.15a19.92 19.92 0 0 0 5.07-14.19v-3.31C84.34 356 80.5 352 73 352H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h22.83a157.41 157.41 0 0 0-11 12.31l-5.61 7c-4 5.07-5.25 10.13-2.8 14.88l1.05 1.93c3 5.76 6.29 7.88 12.25 7.88h4.73c10.33 0 15.94 2.44 15.94 9.09 0 4.72-4.2 8.22-14.36 8.22a41.54 41.54 0 0 1-15.47-3.12c-6.49-3.88-11.74-3.5-15.6 3.12l-5.59 9.31c-3.72 6.13-3.19 11.72 2.63 15.94 7.71 4.69 20.38 9.44 37 9.44 34.16 0 48.5-22.75 48.5-44.12-.03-14.38-9.12-29.76-28.73-34.88zM496 224H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM16 160h64a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H64V40a8 8 0 0 0-8-8H32a8 8 0 0 0-7.14 4.42l-8 16A8 8 0 0 0 24 64h8v64H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8zm-3.91 160H80a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H41.32c3.29-10.29 48.34-18.68 48.34-56.44 0-29.06-25-39.56-44.47-39.56-21.36 0-33.8 10-40.46 18.75-4.37 5.59-3 10.84 2.8 15.37l8.58 6.88c5.61 4.56 11 2.47 16.12-2.44a13.44 13.44 0 0 1 9.46-3.84c3.33 0 9.28 1.56 9.28 8.75C51 248.19 0 257.31 0 304.59v4C0 316 5.08 320 12.09 320z"/></svg></button>

      <button 
        class="
          wrap-code-button
          tw-select-none 
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.is-wrap]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle code wrap"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"/></svg></button>
      
      <button 
        class="
          copy-code-button
          tw-select-none
          tw-mx-2 
          tw-hidden
          group-[.is-open]:tw-block
          hover:tw-text-fgColor-link 
          print:!tw-hidden"
        title="Copy code">
          <span class="copy-icon tw-block"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"/></svg></span>
          <span class="check-icon tw-hidden"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"/></svg></span>
      </button>
        
      <button 
        class="
          tw-select-none 
          tw-mx-2 
          tw-block 
          group-[.is-open]:tw-hidden 
          print:!tw-hidden" 
        disabled
        aria-hidden="true"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"/></svg></button>
    </div>
  </div>
  <pre style="counter-reset: codeblock;" class="tw-block tw-m-0 tw-p-0"><code 
    id="codeblock-id-4" 
    class="
      chroma 
      !tw-block 
      tw-p-0
      tw-m-0
      tw-transition-[max-height] 
      tw-duration-500 
      tw-ease-in-out 
      group-[.is-closed]:!tw-max-h-0 
      group-[.is-wrap]:tw-text-wrap
      tw-overflow-y-hidden
      tw-overflow-x-auto
      tw-scrollbar-thin
      "><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Ascii7Stream</span><span class="p">(</span><span class="k">private</span> <span class="k">var</span> <span class="py">stream</span><span class="p">:</span> <span class="n">Stream</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">read</span><span class="p">(</span><span class="n">path</span><span class="p">:</span> <span class="n">String</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">println</span><span class="p">(</span><span class="s2">&#34;编码&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">stream</span><span class="p">.</span><span class="n">read</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">CompressingStream</span><span class="p">(</span><span class="k">private</span> <span class="k">var</span> <span class="py">stream</span><span class="p">:</span> <span class="n">Stream</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">read</span><span class="p">(</span><span class="n">path</span><span class="p">:</span> <span class="n">String</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">println</span><span class="p">(</span><span class="s2">&#34;压缩&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">stream</span><span class="p">.</span><span class="n">read</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre>
</div>
<h2 id="组合加继承" class="headerLink">
    <a href="#%e7%bb%84%e5%90%88%e5%8a%a0%e7%bb%a7%e6%89%bf" class="header-mark"></a>组合加继承</h2><p>此时，细心的朋友肯定发现了，你既没有继承父类或者抽象类，也实现接口，你怎么方法前面还是 <code>override</code>  啊！是啊，这个情况在 kotlin 上是语法错误的。所以就要把 <code>override</code> 去掉吗？当然也不可以，我们既然是实现 <code>Stream</code> 的功能，那就意味着要遵循 <code>Stream</code> 的规范。仍旧需要去实现 <code>Stream</code> 流的接口。</p>
<div class="code-block highlight is-open show-line-numbers  tw-group tw-my-2">
  <div class="
    
    tw-flex 
    tw-flex-row
    tw-flex-1 
    tw-justify-between 
    tw-w-full tw-bg-bgColor-secondary
    ">      
    <button 
      class="
        code-block-button
        tw-mx-2 
        tw-flex
        tw-flex-row
        tw-flex-1"
      aria-hidden="true">
          <div class="group-[.is-open]:tw-rotate-90 tw-transition-[transform] tw-duration-500 tw-ease-in-out print:!tw-hidden tw-w-min tw-h-min tw-my-1 tw-mx-1"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"/></svg></div>
          <p class="tw-select-none !tw-my-1">kotlin</p>
      </button>

   <div class="tw-flex">
      <button 
        class="
          line-number-button
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.show-line-numbers]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle line numbers"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M61.77 401l17.5-20.15a19.92 19.92 0 0 0 5.07-14.19v-3.31C84.34 356 80.5 352 73 352H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h22.83a157.41 157.41 0 0 0-11 12.31l-5.61 7c-4 5.07-5.25 10.13-2.8 14.88l1.05 1.93c3 5.76 6.29 7.88 12.25 7.88h4.73c10.33 0 15.94 2.44 15.94 9.09 0 4.72-4.2 8.22-14.36 8.22a41.54 41.54 0 0 1-15.47-3.12c-6.49-3.88-11.74-3.5-15.6 3.12l-5.59 9.31c-3.72 6.13-3.19 11.72 2.63 15.94 7.71 4.69 20.38 9.44 37 9.44 34.16 0 48.5-22.75 48.5-44.12-.03-14.38-9.12-29.76-28.73-34.88zM496 224H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM16 160h64a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H64V40a8 8 0 0 0-8-8H32a8 8 0 0 0-7.14 4.42l-8 16A8 8 0 0 0 24 64h8v64H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8zm-3.91 160H80a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H41.32c3.29-10.29 48.34-18.68 48.34-56.44 0-29.06-25-39.56-44.47-39.56-21.36 0-33.8 10-40.46 18.75-4.37 5.59-3 10.84 2.8 15.37l8.58 6.88c5.61 4.56 11 2.47 16.12-2.44a13.44 13.44 0 0 1 9.46-3.84c3.33 0 9.28 1.56 9.28 8.75C51 248.19 0 257.31 0 304.59v4C0 316 5.08 320 12.09 320z"/></svg></button>

      <button 
        class="
          wrap-code-button
          tw-select-none 
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.is-wrap]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle code wrap"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"/></svg></button>
      
      <button 
        class="
          copy-code-button
          tw-select-none
          tw-mx-2 
          tw-hidden
          group-[.is-open]:tw-block
          hover:tw-text-fgColor-link 
          print:!tw-hidden"
        title="Copy code">
          <span class="copy-icon tw-block"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"/></svg></span>
          <span class="check-icon tw-hidden"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"/></svg></span>
      </button>
        
      <button 
        class="
          tw-select-none 
          tw-mx-2 
          tw-block 
          group-[.is-open]:tw-hidden 
          print:!tw-hidden" 
        disabled
        aria-hidden="true"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"/></svg></button>
    </div>
  </div>
  <pre style="counter-reset: codeblock;" class="tw-block tw-m-0 tw-p-0"><code 
    id="codeblock-id-5" 
    class="
      chroma 
      !tw-block 
      tw-p-0
      tw-m-0
      tw-transition-[max-height] 
      tw-duration-500 
      tw-ease-in-out 
      group-[.is-closed]:!tw-max-h-0 
      group-[.is-wrap]:tw-text-wrap
      tw-overflow-y-hidden
      tw-overflow-x-auto
      tw-scrollbar-thin
      "><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Ascii7Stream</span><span class="p">(</span><span class="k">private</span> <span class="k">var</span> <span class="py">stream</span><span class="p">:</span> <span class="n">Stream</span><span class="p">)</span> <span class="p">:</span> <span class="n">Stream</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">read</span><span class="p">(</span><span class="n">path</span><span class="p">:</span> <span class="n">String</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">println</span><span class="p">(</span><span class="s2">&#34;编码&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">stream</span><span class="p">.</span><span class="n">read</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre>
</div>
<p>组合是为了更好的完成功能，将编译时依赖成为运行时依赖；而继承则是为第一点是符合 kotlin 语法、第二则是为了满足 <code>Stream</code> 的规范。</p>
<h2 id="运行一下" class="headerLink">
    <a href="#%e8%bf%90%e8%a1%8c%e4%b8%80%e4%b8%8b" class="header-mark"></a>运行一下</h2><div class="code-block highlight is-open show-line-numbers  tw-group tw-my-2">
  <div class="
    
    tw-flex 
    tw-flex-row
    tw-flex-1 
    tw-justify-between 
    tw-w-full tw-bg-bgColor-secondary
    ">      
    <button 
      class="
        code-block-button
        tw-mx-2 
        tw-flex
        tw-flex-row
        tw-flex-1"
      aria-hidden="true">
          <div class="group-[.is-open]:tw-rotate-90 tw-transition-[transform] tw-duration-500 tw-ease-in-out print:!tw-hidden tw-w-min tw-h-min tw-my-1 tw-mx-1"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"/></svg></div>
          <p class="tw-select-none !tw-my-1">kotlin</p>
      </button>

   <div class="tw-flex">
      <button 
        class="
          line-number-button
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.show-line-numbers]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle line numbers"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M61.77 401l17.5-20.15a19.92 19.92 0 0 0 5.07-14.19v-3.31C84.34 356 80.5 352 73 352H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h22.83a157.41 157.41 0 0 0-11 12.31l-5.61 7c-4 5.07-5.25 10.13-2.8 14.88l1.05 1.93c3 5.76 6.29 7.88 12.25 7.88h4.73c10.33 0 15.94 2.44 15.94 9.09 0 4.72-4.2 8.22-14.36 8.22a41.54 41.54 0 0 1-15.47-3.12c-6.49-3.88-11.74-3.5-15.6 3.12l-5.59 9.31c-3.72 6.13-3.19 11.72 2.63 15.94 7.71 4.69 20.38 9.44 37 9.44 34.16 0 48.5-22.75 48.5-44.12-.03-14.38-9.12-29.76-28.73-34.88zM496 224H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM16 160h64a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H64V40a8 8 0 0 0-8-8H32a8 8 0 0 0-7.14 4.42l-8 16A8 8 0 0 0 24 64h8v64H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8zm-3.91 160H80a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H41.32c3.29-10.29 48.34-18.68 48.34-56.44 0-29.06-25-39.56-44.47-39.56-21.36 0-33.8 10-40.46 18.75-4.37 5.59-3 10.84 2.8 15.37l8.58 6.88c5.61 4.56 11 2.47 16.12-2.44a13.44 13.44 0 0 1 9.46-3.84c3.33 0 9.28 1.56 9.28 8.75C51 248.19 0 257.31 0 304.59v4C0 316 5.08 320 12.09 320z"/></svg></button>

      <button 
        class="
          wrap-code-button
          tw-select-none 
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.is-wrap]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle code wrap"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"/></svg></button>
      
      <button 
        class="
          copy-code-button
          tw-select-none
          tw-mx-2 
          tw-hidden
          group-[.is-open]:tw-block
          hover:tw-text-fgColor-link 
          print:!tw-hidden"
        title="Copy code">
          <span class="copy-icon tw-block"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"/></svg></span>
          <span class="check-icon tw-hidden"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"/></svg></span>
      </button>
        
      <button 
        class="
          tw-select-none 
          tw-mx-2 
          tw-block 
          group-[.is-open]:tw-hidden 
          print:!tw-hidden" 
        disabled
        aria-hidden="true"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"/></svg></button>
    </div>
  </div>
  <pre style="counter-reset: codeblock;" class="tw-block tw-m-0 tw-p-0"><code 
    id="codeblock-id-6" 
    class="
      chroma 
      !tw-block 
      tw-p-0
      tw-m-0
      tw-transition-[max-height] 
      tw-duration-500 
      tw-ease-in-out 
      group-[.is-closed]:!tw-max-h-0 
      group-[.is-wrap]:tw-text-wrap
      tw-overflow-y-hidden
      tw-overflow-x-auto
      tw-scrollbar-thin
      "><span class="line"><span class="cl"><span class="k">fun</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">val</span> <span class="py">fileStream</span> <span class="p">=</span> <span class="n">FileStream</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="k">val</span> <span class="py">ascii7Stream</span> <span class="p">=</span> <span class="n">Ascii7Stream</span><span class="p">(</span><span class="n">fileStream</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">ascii7Stream</span><span class="p">.</span><span class="n">read</span><span class="p">(</span><span class="s2">&#34;123&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">val</span> <span class="py">memoryStream</span> <span class="p">=</span> <span class="n">MemoryStream</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="k">val</span> <span class="py">compressingStream</span> <span class="p">=</span> <span class="n">CompressingStream</span><span class="p">(</span><span class="n">memoryStream</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">compressingStream</span><span class="p">.</span><span class="n">read</span><span class="p">(</span><span class="s2">&#34;456&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="c1">// 编码
</span></span></span><span class="line"><span class="cl"><span class="c1">// FileStream.read 123
</span></span></span><span class="line"><span class="cl"><span class="c1">// 压缩
</span></span></span><span class="line"><span class="cl"><span class="c1">// MemoryStream.read 456</span></span></span></code></pre>
</div>
<p>简单运行一下，可以发现编码和压缩都完成了，那么编码加密操作呢？其实我们也已经实现了。</p>
<div class="code-block highlight is-open show-line-numbers  tw-group tw-my-2">
  <div class="
    
    tw-flex 
    tw-flex-row
    tw-flex-1 
    tw-justify-between 
    tw-w-full tw-bg-bgColor-secondary
    ">      
    <button 
      class="
        code-block-button
        tw-mx-2 
        tw-flex
        tw-flex-row
        tw-flex-1"
      aria-hidden="true">
          <div class="group-[.is-open]:tw-rotate-90 tw-transition-[transform] tw-duration-500 tw-ease-in-out print:!tw-hidden tw-w-min tw-h-min tw-my-1 tw-mx-1"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"/></svg></div>
          <p class="tw-select-none !tw-my-1">kotlin</p>
      </button>

   <div class="tw-flex">
      <button 
        class="
          line-number-button
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.show-line-numbers]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle line numbers"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M61.77 401l17.5-20.15a19.92 19.92 0 0 0 5.07-14.19v-3.31C84.34 356 80.5 352 73 352H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h22.83a157.41 157.41 0 0 0-11 12.31l-5.61 7c-4 5.07-5.25 10.13-2.8 14.88l1.05 1.93c3 5.76 6.29 7.88 12.25 7.88h4.73c10.33 0 15.94 2.44 15.94 9.09 0 4.72-4.2 8.22-14.36 8.22a41.54 41.54 0 0 1-15.47-3.12c-6.49-3.88-11.74-3.5-15.6 3.12l-5.59 9.31c-3.72 6.13-3.19 11.72 2.63 15.94 7.71 4.69 20.38 9.44 37 9.44 34.16 0 48.5-22.75 48.5-44.12-.03-14.38-9.12-29.76-28.73-34.88zM496 224H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM16 160h64a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H64V40a8 8 0 0 0-8-8H32a8 8 0 0 0-7.14 4.42l-8 16A8 8 0 0 0 24 64h8v64H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8zm-3.91 160H80a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H41.32c3.29-10.29 48.34-18.68 48.34-56.44 0-29.06-25-39.56-44.47-39.56-21.36 0-33.8 10-40.46 18.75-4.37 5.59-3 10.84 2.8 15.37l8.58 6.88c5.61 4.56 11 2.47 16.12-2.44a13.44 13.44 0 0 1 9.46-3.84c3.33 0 9.28 1.56 9.28 8.75C51 248.19 0 257.31 0 304.59v4C0 316 5.08 320 12.09 320z"/></svg></button>

      <button 
        class="
          wrap-code-button
          tw-select-none 
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.is-wrap]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle code wrap"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"/></svg></button>
      
      <button 
        class="
          copy-code-button
          tw-select-none
          tw-mx-2 
          tw-hidden
          group-[.is-open]:tw-block
          hover:tw-text-fgColor-link 
          print:!tw-hidden"
        title="Copy code">
          <span class="copy-icon tw-block"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"/></svg></span>
          <span class="check-icon tw-hidden"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"/></svg></span>
      </button>
        
      <button 
        class="
          tw-select-none 
          tw-mx-2 
          tw-block 
          group-[.is-open]:tw-hidden 
          print:!tw-hidden" 
        disabled
        aria-hidden="true"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"/></svg></button>
    </div>
  </div>
  <pre style="counter-reset: codeblock;" class="tw-block tw-m-0 tw-p-0"><code 
    id="codeblock-id-7" 
    class="
      chroma 
      !tw-block 
      tw-p-0
      tw-m-0
      tw-transition-[max-height] 
      tw-duration-500 
      tw-ease-in-out 
      group-[.is-closed]:!tw-max-h-0 
      group-[.is-wrap]:tw-text-wrap
      tw-overflow-y-hidden
      tw-overflow-x-auto
      tw-scrollbar-thin
      "><span class="line"><span class="cl">    <span class="k">val</span> <span class="py">fileStream</span> <span class="p">=</span> <span class="n">FileStream</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="k">val</span> <span class="py">ascii7Stream</span> <span class="p">=</span> <span class="n">Ascii7Stream</span><span class="p">(</span><span class="n">fileStream</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">val</span> <span class="py">compressingStream</span> <span class="p">=</span> <span class="n">CompressingStream</span><span class="p">(</span><span class="n">ascii7Stream</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">compressingStream</span><span class="p">.</span><span class="n">read</span><span class="p">(</span><span class="s2">&#34;456&#34;</span><span class="p">)</span></span></span></code></pre>
</div>
<p>只需要将上一步完成的 <code>Stream</code> 在进行新的操作即可。这样意味着 <code>CompressingAscii7...</code>这一系列的类就不需要再进行实现了。</p>
<p>现在再看我们的代码</p>
<div class="code-block highlight is-closed show-line-numbers  tw-group tw-my-2">
  <div class="
    
    tw-flex 
    tw-flex-row
    tw-flex-1 
    tw-justify-between 
    tw-w-full tw-bg-bgColor-secondary
    ">      
    <button 
      class="
        code-block-button
        tw-mx-2 
        tw-flex
        tw-flex-row
        tw-flex-1"
      aria-hidden="true">
          <div class="group-[.is-open]:tw-rotate-90 tw-transition-[transform] tw-duration-500 tw-ease-in-out print:!tw-hidden tw-w-min tw-h-min tw-my-1 tw-mx-1"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"/></svg></div>
          <p class="tw-select-none !tw-my-1">kotlin</p>
      </button>

   <div class="tw-flex">
      <button 
        class="
          line-number-button
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.show-line-numbers]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle line numbers"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M61.77 401l17.5-20.15a19.92 19.92 0 0 0 5.07-14.19v-3.31C84.34 356 80.5 352 73 352H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h22.83a157.41 157.41 0 0 0-11 12.31l-5.61 7c-4 5.07-5.25 10.13-2.8 14.88l1.05 1.93c3 5.76 6.29 7.88 12.25 7.88h4.73c10.33 0 15.94 2.44 15.94 9.09 0 4.72-4.2 8.22-14.36 8.22a41.54 41.54 0 0 1-15.47-3.12c-6.49-3.88-11.74-3.5-15.6 3.12l-5.59 9.31c-3.72 6.13-3.19 11.72 2.63 15.94 7.71 4.69 20.38 9.44 37 9.44 34.16 0 48.5-22.75 48.5-44.12-.03-14.38-9.12-29.76-28.73-34.88zM496 224H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM16 160h64a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H64V40a8 8 0 0 0-8-8H32a8 8 0 0 0-7.14 4.42l-8 16A8 8 0 0 0 24 64h8v64H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8zm-3.91 160H80a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H41.32c3.29-10.29 48.34-18.68 48.34-56.44 0-29.06-25-39.56-44.47-39.56-21.36 0-33.8 10-40.46 18.75-4.37 5.59-3 10.84 2.8 15.37l8.58 6.88c5.61 4.56 11 2.47 16.12-2.44a13.44 13.44 0 0 1 9.46-3.84c3.33 0 9.28 1.56 9.28 8.75C51 248.19 0 257.31 0 304.59v4C0 316 5.08 320 12.09 320z"/></svg></button>

      <button 
        class="
          wrap-code-button
          tw-select-none 
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.is-wrap]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle code wrap"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"/></svg></button>
      
      <button 
        class="
          copy-code-button
          tw-select-none
          tw-mx-2 
          tw-hidden
          group-[.is-open]:tw-block
          hover:tw-text-fgColor-link 
          print:!tw-hidden"
        title="Copy code">
          <span class="copy-icon tw-block"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"/></svg></span>
          <span class="check-icon tw-hidden"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"/></svg></span>
      </button>
        
      <button 
        class="
          tw-select-none 
          tw-mx-2 
          tw-block 
          group-[.is-open]:tw-hidden 
          print:!tw-hidden" 
        disabled
        aria-hidden="true"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"/></svg></button>
    </div>
  </div>
  <pre style="counter-reset: codeblock;" class="tw-block tw-m-0 tw-p-0"><code 
    id="codeblock-id-8" 
    class="
      chroma 
      !tw-block 
      tw-p-0
      tw-m-0
      tw-transition-[max-height] 
      tw-duration-500 
      tw-ease-in-out 
      group-[.is-closed]:!tw-max-h-0 
      group-[.is-wrap]:tw-text-wrap
      tw-overflow-y-hidden
      tw-overflow-x-auto
      tw-scrollbar-thin
      "><span class="line"><span class="cl"><span class="k">interface</span> <span class="nc">Stream</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">fun</span> <span class="nf">read</span><span class="p">(</span><span class="n">path</span><span class="p">:</span> <span class="n">String</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">open</span> <span class="k">class</span> <span class="nc">FileStream</span> <span class="p">:</span> <span class="n">Stream</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">read</span><span class="p">(</span><span class="n">path</span><span class="p">:</span> <span class="n">String</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">println</span><span class="p">(</span><span class="s2">&#34;FileStream.read </span><span class="si">$path</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">open</span> <span class="k">class</span> <span class="nc">MemoryStream</span> <span class="p">:</span> <span class="n">Stream</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">read</span><span class="p">(</span><span class="n">path</span><span class="p">:</span> <span class="n">String</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">println</span><span class="p">(</span><span class="s2">&#34;MemoryStream.read </span><span class="si">$path</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Ascii7Stream</span><span class="p">(</span><span class="k">private</span> <span class="k">var</span> <span class="py">stream</span><span class="p">:</span> <span class="n">Stream</span><span class="p">)</span> <span class="p">:</span> <span class="n">Stream</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">read</span><span class="p">(</span><span class="n">path</span><span class="p">:</span> <span class="n">String</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">println</span><span class="p">(</span><span class="s2">&#34;编码&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">stream</span><span class="p">.</span><span class="n">read</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">CompressingStream</span><span class="p">(</span><span class="k">private</span> <span class="k">var</span> <span class="py">stream</span><span class="p">:</span> <span class="n">Stream</span><span class="p">)</span> <span class="p">:</span> <span class="n">Stream</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">read</span><span class="p">(</span><span class="n">path</span><span class="p">:</span> <span class="n">String</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">println</span><span class="p">(</span><span class="s2">&#34;压缩&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">stream</span><span class="p">.</span><span class="n">read</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre>
</div>
<p>相比于第一个版本的代码 59 行，9个类或者接口，而现在我们仅仅需要31行，5个类或者接口，无论函数还是类都相较于之前减少近一半，而且和之前完成的功能一样。</p>
<h2 id="让代码变得更美一些" class="headerLink">
    <a href="#%e8%ae%a9%e4%bb%a3%e7%a0%81%e5%8f%98%e5%be%97%e6%9b%b4%e7%be%8e%e4%b8%80%e4%ba%9b" class="header-mark"></a>让代码变得更美一些</h2><p>仔细观察代码，发现 <code>CompressingStream</code>和 <code>Ascii7Stream</code> 都有公共的属性(<code>stream</code>) ,我们可以将他们抽取到一个公共父类。</p>
<div class="code-block highlight is-open show-line-numbers  tw-group tw-my-2">
  <div class="
    
    tw-flex 
    tw-flex-row
    tw-flex-1 
    tw-justify-between 
    tw-w-full tw-bg-bgColor-secondary
    ">      
    <button 
      class="
        code-block-button
        tw-mx-2 
        tw-flex
        tw-flex-row
        tw-flex-1"
      aria-hidden="true">
          <div class="group-[.is-open]:tw-rotate-90 tw-transition-[transform] tw-duration-500 tw-ease-in-out print:!tw-hidden tw-w-min tw-h-min tw-my-1 tw-mx-1"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"/></svg></div>
          <p class="tw-select-none !tw-my-1">kotlin</p>
      </button>

   <div class="tw-flex">
      <button 
        class="
          line-number-button
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.show-line-numbers]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle line numbers"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M61.77 401l17.5-20.15a19.92 19.92 0 0 0 5.07-14.19v-3.31C84.34 356 80.5 352 73 352H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h22.83a157.41 157.41 0 0 0-11 12.31l-5.61 7c-4 5.07-5.25 10.13-2.8 14.88l1.05 1.93c3 5.76 6.29 7.88 12.25 7.88h4.73c10.33 0 15.94 2.44 15.94 9.09 0 4.72-4.2 8.22-14.36 8.22a41.54 41.54 0 0 1-15.47-3.12c-6.49-3.88-11.74-3.5-15.6 3.12l-5.59 9.31c-3.72 6.13-3.19 11.72 2.63 15.94 7.71 4.69 20.38 9.44 37 9.44 34.16 0 48.5-22.75 48.5-44.12-.03-14.38-9.12-29.76-28.73-34.88zM496 224H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM16 160h64a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H64V40a8 8 0 0 0-8-8H32a8 8 0 0 0-7.14 4.42l-8 16A8 8 0 0 0 24 64h8v64H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8zm-3.91 160H80a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H41.32c3.29-10.29 48.34-18.68 48.34-56.44 0-29.06-25-39.56-44.47-39.56-21.36 0-33.8 10-40.46 18.75-4.37 5.59-3 10.84 2.8 15.37l8.58 6.88c5.61 4.56 11 2.47 16.12-2.44a13.44 13.44 0 0 1 9.46-3.84c3.33 0 9.28 1.56 9.28 8.75C51 248.19 0 257.31 0 304.59v4C0 316 5.08 320 12.09 320z"/></svg></button>

      <button 
        class="
          wrap-code-button
          tw-select-none 
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.is-wrap]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle code wrap"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"/></svg></button>
      
      <button 
        class="
          copy-code-button
          tw-select-none
          tw-mx-2 
          tw-hidden
          group-[.is-open]:tw-block
          hover:tw-text-fgColor-link 
          print:!tw-hidden"
        title="Copy code">
          <span class="copy-icon tw-block"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"/></svg></span>
          <span class="check-icon tw-hidden"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"/></svg></span>
      </button>
        
      <button 
        class="
          tw-select-none 
          tw-mx-2 
          tw-block 
          group-[.is-open]:tw-hidden 
          print:!tw-hidden" 
        disabled
        aria-hidden="true"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"/></svg></button>
    </div>
  </div>
  <pre style="counter-reset: codeblock;" class="tw-block tw-m-0 tw-p-0"><code 
    id="codeblock-id-9" 
    class="
      chroma 
      !tw-block 
      tw-p-0
      tw-m-0
      tw-transition-[max-height] 
      tw-duration-500 
      tw-ease-in-out 
      group-[.is-closed]:!tw-max-h-0 
      group-[.is-wrap]:tw-text-wrap
      tw-overflow-y-hidden
      tw-overflow-x-auto
      tw-scrollbar-thin
      "><span class="line"><span class="cl"><span class="k">abstract</span> <span class="k">class</span> <span class="nc">StreamDecorator</span><span class="p">(</span><span class="k">protected</span> <span class="k">var</span> <span class="py">stream</span><span class="p">:</span> <span class="n">Stream</span><span class="p">)</span> <span class="p">:</span> <span class="n">Stream</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">read</span><span class="p">(</span><span class="n">path</span><span class="p">:</span> <span class="n">String</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">stream</span><span class="p">.</span><span class="n">read</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre>
</div>
<p>新写一个 abstract 类，让 <code>CompressingStream</code> 和 <code>Ascii7Stream</code> 去继承新的 <code>StreamDecorator</code> 类。通过装饰类，将代码结构分割开来。以后扩展，只需要继承 <code>StreaDecorator</code> 即可。</p>
<p><img class="tw-inline" loading="lazy" src='https://island-hexo.oss-cn-beijing.aliyuncs.com/decorator-uml.jpg'     ></p>
]]></description></item><item><title>设计原则</title><link>https://youngxhui.top/2020/02/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99/</link><pubDate>Tue, 25 Feb 2020 10:59:07 +0000</pubDate><author><name>youngxhui</name></author><guid>https://youngxhui.top/2020/02/%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99/</guid><description><![CDATA[<p>设计原则是设计模式中重要的指导。设计原则往往比设计模式更重要，真是因为设计原则的存在，才指导完成设计模式。所有的设计模式都是通过设计原则推导出来的，如果某一个设计模式违背了设计原则，那么这个模式一定是有问题的。</p>
<h2 id="依赖倒置原则-dip" class="headerLink">
    <a href="#%e4%be%9d%e8%b5%96%e5%80%92%e7%bd%ae%e5%8e%9f%e5%88%99-dip" class="header-mark"></a>依赖倒置原则 (DIP)</h2><p>高层模块(<strong>稳定</strong>)不应该依赖于低层模块(<strong>变化</strong>)，二者都应该依赖于抽象(<strong>稳定</strong>)。</p>
<p>抽象(<strong>稳定</strong>)不应该依赖于实现细节(<strong>变化</strong>)，实现细节(<strong>变化</strong>)应该依赖于抽象(<strong>稳定</strong>)。</p>
<p>例如：</p>
<p><code>class A</code> 依赖 <code>class B</code> ,此时的 <code>class A</code> 为高层模块，<code>class B</code> 为低层模块。如果要进行修改使 <code>class A</code> 依赖 <code>class C</code> ， 那么必须要修改 <code>class A</code> 的源码。此时，就发生了<strong>高层模块依赖低层模块</strong>。如果使用一个公共的接口 <code>interface D</code> 抽象 <code>class B</code> 和 <code>class C</code> , 那么 <code>class A</code> 就可以依赖 <code>interface D</code> ,<strong>高层模块不依赖于低层模块</strong>。如果使 <code>class A</code> 也抽象一个抽象接口 <code>interface IA</code>，那么，只需要了解 <code>interface IA</code> 和 <code>interface D</code> 之间的关系即可，无需关心实现细节。此刻，便完成了<strong>高层模块和低层模块都依赖于接口</strong>，同时也完成了<strong>抽象不依赖于实现细节，实现细节依赖于抽象</strong>。</p>
<p>我们采用抽象接口定义好规则规范，而不需要关系具体实现，提高了设计的稳定性。</p>
<p>我们定义了两个类，一个为 <code>Movie</code> 另一个为 <code>Television</code>,通过 <code>Television.play()</code> 方法进行内容播放。</p>
<div class="code-block highlight is-open show-line-numbers  tw-group tw-my-2">
  <div class="
    
    tw-flex 
    tw-flex-row
    tw-flex-1 
    tw-justify-between 
    tw-w-full tw-bg-bgColor-secondary
    ">      
    <button 
      class="
        code-block-button
        tw-mx-2 
        tw-flex
        tw-flex-row
        tw-flex-1"
      aria-hidden="true">
          <div class="group-[.is-open]:tw-rotate-90 tw-transition-[transform] tw-duration-500 tw-ease-in-out print:!tw-hidden tw-w-min tw-h-min tw-my-1 tw-mx-1"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"/></svg></div>
          <p class="tw-select-none !tw-my-1">kotlin</p>
      </button>

   <div class="tw-flex">
      <button 
        class="
          line-number-button
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.show-line-numbers]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle line numbers"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M61.77 401l17.5-20.15a19.92 19.92 0 0 0 5.07-14.19v-3.31C84.34 356 80.5 352 73 352H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h22.83a157.41 157.41 0 0 0-11 12.31l-5.61 7c-4 5.07-5.25 10.13-2.8 14.88l1.05 1.93c3 5.76 6.29 7.88 12.25 7.88h4.73c10.33 0 15.94 2.44 15.94 9.09 0 4.72-4.2 8.22-14.36 8.22a41.54 41.54 0 0 1-15.47-3.12c-6.49-3.88-11.74-3.5-15.6 3.12l-5.59 9.31c-3.72 6.13-3.19 11.72 2.63 15.94 7.71 4.69 20.38 9.44 37 9.44 34.16 0 48.5-22.75 48.5-44.12-.03-14.38-9.12-29.76-28.73-34.88zM496 224H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM16 160h64a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H64V40a8 8 0 0 0-8-8H32a8 8 0 0 0-7.14 4.42l-8 16A8 8 0 0 0 24 64h8v64H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8zm-3.91 160H80a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H41.32c3.29-10.29 48.34-18.68 48.34-56.44 0-29.06-25-39.56-44.47-39.56-21.36 0-33.8 10-40.46 18.75-4.37 5.59-3 10.84 2.8 15.37l8.58 6.88c5.61 4.56 11 2.47 16.12-2.44a13.44 13.44 0 0 1 9.46-3.84c3.33 0 9.28 1.56 9.28 8.75C51 248.19 0 257.31 0 304.59v4C0 316 5.08 320 12.09 320z"/></svg></button>

      <button 
        class="
          wrap-code-button
          tw-select-none 
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.is-wrap]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle code wrap"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"/></svg></button>
      
      <button 
        class="
          copy-code-button
          tw-select-none
          tw-mx-2 
          tw-hidden
          group-[.is-open]:tw-block
          hover:tw-text-fgColor-link 
          print:!tw-hidden"
        title="Copy code">
          <span class="copy-icon tw-block"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"/></svg></span>
          <span class="check-icon tw-hidden"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"/></svg></span>
      </button>
        
      <button 
        class="
          tw-select-none 
          tw-mx-2 
          tw-block 
          group-[.is-open]:tw-hidden 
          print:!tw-hidden" 
        disabled
        aria-hidden="true"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"/></svg></button>
    </div>
  </div>
  <pre style="counter-reset: codeblock;" class="tw-block tw-m-0 tw-p-0"><code 
    id="codeblock-id-1" 
    class="
      chroma 
      !tw-block 
      tw-p-0
      tw-m-0
      tw-transition-[max-height] 
      tw-duration-500 
      tw-ease-in-out 
      group-[.is-closed]:!tw-max-h-0 
      group-[.is-wrap]:tw-text-wrap
      tw-overflow-y-hidden
      tw-overflow-x-auto
      tw-scrollbar-thin
      "><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Movie</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">fun</span> <span class="nf">show</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">println</span><span class="p">(</span><span class="s2">&#34;这是电影&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Television</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">fun</span> <span class="nf">play</span><span class="p">(</span><span class="n">movie</span><span class="p">:</span> <span class="n">Movie</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">movie</span><span class="p">.</span><span class="n">show</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">fun</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">val</span> <span class="py">television</span> <span class="p">=</span> <span class="n">Television</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="k">val</span> <span class="py">movie</span> <span class="p">=</span> <span class="n">Movie</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="n">television</span><span class="p">.</span><span class="n">play</span><span class="p">(</span><span class="n">movie</span><span class="p">)</span> <span class="c1">// 这是电影
</span></span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre>
</div>
<p>目前来看没有问题，那么如果现在电视剧要播放动画呢？我们需要重新建立一个类 <code>Cartoon</code>，并且修改 <code>play()</code> 方法 和 <code>main</code> 函数。</p>
<p>此刻说明在设计上有问题，我们的高层模块(<code>Television</code>)依赖底层模块(<code>Movie</code>)。</p>
<p>如果先将 <code>Movie</code> 和 <code>Cartoon</code> 进行抽象，使 <code>Television</code> 不去依赖具体实现，而去依赖接口。</p>
<div class="code-block highlight is-open show-line-numbers  tw-group tw-my-2">
  <div class="
    
    tw-flex 
    tw-flex-row
    tw-flex-1 
    tw-justify-between 
    tw-w-full tw-bg-bgColor-secondary
    ">      
    <button 
      class="
        code-block-button
        tw-mx-2 
        tw-flex
        tw-flex-row
        tw-flex-1"
      aria-hidden="true">
          <div class="group-[.is-open]:tw-rotate-90 tw-transition-[transform] tw-duration-500 tw-ease-in-out print:!tw-hidden tw-w-min tw-h-min tw-my-1 tw-mx-1"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"/></svg></div>
          <p class="tw-select-none !tw-my-1">kotlin</p>
      </button>

   <div class="tw-flex">
      <button 
        class="
          line-number-button
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.show-line-numbers]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle line numbers"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M61.77 401l17.5-20.15a19.92 19.92 0 0 0 5.07-14.19v-3.31C84.34 356 80.5 352 73 352H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h22.83a157.41 157.41 0 0 0-11 12.31l-5.61 7c-4 5.07-5.25 10.13-2.8 14.88l1.05 1.93c3 5.76 6.29 7.88 12.25 7.88h4.73c10.33 0 15.94 2.44 15.94 9.09 0 4.72-4.2 8.22-14.36 8.22a41.54 41.54 0 0 1-15.47-3.12c-6.49-3.88-11.74-3.5-15.6 3.12l-5.59 9.31c-3.72 6.13-3.19 11.72 2.63 15.94 7.71 4.69 20.38 9.44 37 9.44 34.16 0 48.5-22.75 48.5-44.12-.03-14.38-9.12-29.76-28.73-34.88zM496 224H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM16 160h64a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H64V40a8 8 0 0 0-8-8H32a8 8 0 0 0-7.14 4.42l-8 16A8 8 0 0 0 24 64h8v64H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8zm-3.91 160H80a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H41.32c3.29-10.29 48.34-18.68 48.34-56.44 0-29.06-25-39.56-44.47-39.56-21.36 0-33.8 10-40.46 18.75-4.37 5.59-3 10.84 2.8 15.37l8.58 6.88c5.61 4.56 11 2.47 16.12-2.44a13.44 13.44 0 0 1 9.46-3.84c3.33 0 9.28 1.56 9.28 8.75C51 248.19 0 257.31 0 304.59v4C0 316 5.08 320 12.09 320z"/></svg></button>

      <button 
        class="
          wrap-code-button
          tw-select-none 
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.is-wrap]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle code wrap"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"/></svg></button>
      
      <button 
        class="
          copy-code-button
          tw-select-none
          tw-mx-2 
          tw-hidden
          group-[.is-open]:tw-block
          hover:tw-text-fgColor-link 
          print:!tw-hidden"
        title="Copy code">
          <span class="copy-icon tw-block"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"/></svg></span>
          <span class="check-icon tw-hidden"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"/></svg></span>
      </button>
        
      <button 
        class="
          tw-select-none 
          tw-mx-2 
          tw-block 
          group-[.is-open]:tw-hidden 
          print:!tw-hidden" 
        disabled
        aria-hidden="true"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"/></svg></button>
    </div>
  </div>
  <pre style="counter-reset: codeblock;" class="tw-block tw-m-0 tw-p-0"><code 
    id="codeblock-id-2" 
    class="
      chroma 
      !tw-block 
      tw-p-0
      tw-m-0
      tw-transition-[max-height] 
      tw-duration-500 
      tw-ease-in-out 
      group-[.is-closed]:!tw-max-h-0 
      group-[.is-wrap]:tw-text-wrap
      tw-overflow-y-hidden
      tw-overflow-x-auto
      tw-scrollbar-thin
      "><span class="line"><span class="cl"><span class="k">interface</span> <span class="nc">ITVContent</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">fun</span> <span class="nf">show</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Movie</span> <span class="p">:</span> <span class="n">ITVContent</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">show</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">println</span><span class="p">(</span><span class="s2">&#34;这是电影&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Cartoon</span> <span class="p">:</span> <span class="n">ITVContent</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">show</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">println</span><span class="p">(</span><span class="s2">&#34;这是卡通&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Television</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">fun</span> <span class="nf">play</span><span class="p">(</span><span class="n">tv</span><span class="p">:</span> <span class="n">ITVContent</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">tv</span><span class="p">.</span><span class="n">show</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">fun</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">val</span> <span class="py">television</span> <span class="p">=</span> <span class="n">Television</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="k">val</span> <span class="py">cartoon</span> <span class="p">=</span> <span class="n">Cartoon</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="n">television</span><span class="p">.</span><span class="n">play</span><span class="p">(</span><span class="n">cartoon</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre>
</div>
<p>经过修改后，<code>Television</code>不在依赖任何一个具体的类，而是依赖他们的抽象接口，以后无论增加播放什么，例如添加一个广告 <code>Ad.class</code> 只需要添加新的类，并且实现 <code>ITVContent</code> 接口，就可以完成新的播放内容的更换。</p>
<p>如果要更换播放平台呢？不在电视上播放，而在电影院进行播放。</p>
<p>我们只需要添加一个 <code>IPlayer</code> 的接口，并且有未实现的 <code>paly</code> 方法。让 <code>Television</code> 和 <code>Cinema</code> 去实现即可。</p>
<div class="code-block highlight is-open show-line-numbers  tw-group tw-my-2">
  <div class="
    
    tw-flex 
    tw-flex-row
    tw-flex-1 
    tw-justify-between 
    tw-w-full tw-bg-bgColor-secondary
    ">      
    <button 
      class="
        code-block-button
        tw-mx-2 
        tw-flex
        tw-flex-row
        tw-flex-1"
      aria-hidden="true">
          <div class="group-[.is-open]:tw-rotate-90 tw-transition-[transform] tw-duration-500 tw-ease-in-out print:!tw-hidden tw-w-min tw-h-min tw-my-1 tw-mx-1"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"/></svg></div>
          <p class="tw-select-none !tw-my-1">kotlin</p>
      </button>

   <div class="tw-flex">
      <button 
        class="
          line-number-button
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.show-line-numbers]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle line numbers"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M61.77 401l17.5-20.15a19.92 19.92 0 0 0 5.07-14.19v-3.31C84.34 356 80.5 352 73 352H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8h22.83a157.41 157.41 0 0 0-11 12.31l-5.61 7c-4 5.07-5.25 10.13-2.8 14.88l1.05 1.93c3 5.76 6.29 7.88 12.25 7.88h4.73c10.33 0 15.94 2.44 15.94 9.09 0 4.72-4.2 8.22-14.36 8.22a41.54 41.54 0 0 1-15.47-3.12c-6.49-3.88-11.74-3.5-15.6 3.12l-5.59 9.31c-3.72 6.13-3.19 11.72 2.63 15.94 7.71 4.69 20.38 9.44 37 9.44 34.16 0 48.5-22.75 48.5-44.12-.03-14.38-9.12-29.76-28.73-34.88zM496 224H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM16 160h64a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H64V40a8 8 0 0 0-8-8H32a8 8 0 0 0-7.14 4.42l-8 16A8 8 0 0 0 24 64h8v64H16a8 8 0 0 0-8 8v16a8 8 0 0 0 8 8zm-3.91 160H80a8 8 0 0 0 8-8v-16a8 8 0 0 0-8-8H41.32c3.29-10.29 48.34-18.68 48.34-56.44 0-29.06-25-39.56-44.47-39.56-21.36 0-33.8 10-40.46 18.75-4.37 5.59-3 10.84 2.8 15.37l8.58 6.88c5.61 4.56 11 2.47 16.12-2.44a13.44 13.44 0 0 1 9.46-3.84c3.33 0 9.28 1.56 9.28 8.75C51 248.19 0 257.31 0 304.59v4C0 316 5.08 320 12.09 320z"/></svg></button>

      <button 
        class="
          wrap-code-button
          tw-select-none 
          tw-mx-2 
          tw-hidden 
          group-[.is-open]:tw-block 
          group-[.is-wrap]:tw-text-fgColor-link 
          print:!tw-hidden" 
        title="Toggle code wrap"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"/></svg></button>
      
      <button 
        class="
          copy-code-button
          tw-select-none
          tw-mx-2 
          tw-hidden
          group-[.is-open]:tw-block
          hover:tw-text-fgColor-link 
          print:!tw-hidden"
        title="Copy code">
          <span class="copy-icon tw-block"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"/></svg></span>
          <span class="check-icon tw-hidden"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"/></svg></span>
      </button>
        
      <button 
        class="
          tw-select-none 
          tw-mx-2 
          tw-block 
          group-[.is-open]:tw-hidden 
          print:!tw-hidden" 
        disabled
        aria-hidden="true"><svg class="icon"
    xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"/></svg></button>
    </div>
  </div>
  <pre style="counter-reset: codeblock;" class="tw-block tw-m-0 tw-p-0"><code 
    id="codeblock-id-3" 
    class="
      chroma 
      !tw-block 
      tw-p-0
      tw-m-0
      tw-transition-[max-height] 
      tw-duration-500 
      tw-ease-in-out 
      group-[.is-closed]:!tw-max-h-0 
      group-[.is-wrap]:tw-text-wrap
      tw-overflow-y-hidden
      tw-overflow-x-auto
      tw-scrollbar-thin
      "><span class="line"><span class="cl"><span class="k">interface</span> <span class="nc">IPlayer</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">fun</span> <span class="nf">play</span><span class="p">(</span><span class="n">content</span><span class="p">:</span> <span class="n">ITVContent</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Cinema</span> <span class="p">:</span> <span class="n">IPlayer</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">play</span><span class="p">(</span><span class="n">content</span><span class="p">:</span> <span class="n">ITVContent</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">content</span><span class="p">.</span><span class="n">show</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Television</span> <span class="p">:</span> <span class="n">IPlayer</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">override</span> <span class="k">fun</span> <span class="nf">play</span><span class="p">(</span><span class="n">content</span><span class="p">:</span> <span class="n">ITVContent</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">content</span><span class="p">.</span><span class="n">show</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">fun</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">val</span> <span class="py">television</span> <span class="p">=</span> <span class="n">Television</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="k">val</span> <span class="py">cinema</span> <span class="p">=</span> <span class="n">Cinema</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">val</span> <span class="py">cartoon</span> <span class="p">=</span> <span class="n">Cartoon</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="n">television</span><span class="p">.</span><span class="n">play</span><span class="p">(</span><span class="n">cartoon</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">val</span> <span class="py">movie</span> <span class="p">=</span> <span class="n">Movie</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="n">cinema</span><span class="p">.</span><span class="n">play</span><span class="p">(</span><span class="n">movie</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre>
</div>
<p>经过简单的修改，无论是 <code>Television</code> 还是 <code>Cinema</code> 都不在依赖具体的类，而是依赖抽象的接口，以后无论扩展什么播放方法和播放内容，都不需要对之前的类进行修改。同时也不存在<strong>抽象的依赖具体实现，而是具体实现全部依赖于抽象</strong>。完成了解耦问题，将变换进行了隔离。</p>
<h2 id="开闭原则-ocp" class="headerLink">
    <a href="#%e5%bc%80%e9%97%ad%e5%8e%9f%e5%88%99-ocp" class="header-mark"></a>开闭原则 (OCP)</h2><p>对扩展开发，对修改封闭，类模块应该是可以扩展的，但是不可以修改。</p>
<p>什么叫做修改，什么叫做扩展？修改是指对已有的源代码进行修改，而扩展是对当前没有的类或者方法进行添加。</p>
<p>对于上述示例，第一次代码还没有进行修改的时候，代码就进行了修改，每次修改必须对源码进行修改来实现新的功能。最终的代码版本，进行新功能的添加只需要扩展新的类即可，无需对已有的代码进行修改。这样便实现了开闭原则。</p>
<h2 id="单一职责原则srp" class="headerLink">
    <a href="#%e5%8d%95%e4%b8%80%e8%81%8c%e8%b4%a3%e5%8e%9f%e5%88%99srp" class="header-mark"></a>单一职责原则(SRP)</h2><p>不要存在多于一个导致类变更的原因，一个类只负责一项原则。每个类负责的职责不同，进行修改的时候不会对其他类造成影响或者改变。</p>
<h2 id="里氏-liskov-替换原则lsp" class="headerLink">
    <a href="#%e9%87%8c%e6%b0%8f-liskov-%e6%9b%bf%e6%8d%a2%e5%8e%9f%e5%88%99lsp" class="header-mark"></a>里氏 Liskov 替换原则(LSP)</h2><p>子类必须能够替换它们的基类，继承表达类型抽象。LSP 是继承复用的基石，只有子类可以替换父类，并且之前功能不受到影响时，父类才能真正的被复用。是对开闭原则的补充。</p>
<h2 id="接口隔离原则isp" class="headerLink">
    <a href="#%e6%8e%a5%e5%8f%a3%e9%9a%94%e7%a6%bb%e5%8e%9f%e5%88%99isp" class="header-mark"></a>接口隔离原则(ISP)</h2><p>类之间的依赖关系应该建立在最小的接口上。建立单一的接口，不要建立庞大臃肿的接口，接口中的方法尽量少，而不是去建立一个庞大的接口供依赖去使用。</p>
<h2 id="其他原则" class="headerLink">
    <a href="#%e5%85%b6%e4%bb%96%e5%8e%9f%e5%88%99" class="header-mark"></a>其他原则</h2><h3 id="优先使用对象组合而不是继承" class="headerLink">
    <a href="#%e4%bc%98%e5%85%88%e4%bd%bf%e7%94%a8%e5%af%b9%e8%b1%a1%e7%bb%84%e5%90%88%e8%80%8c%e4%b8%8d%e6%98%af%e7%bb%a7%e6%89%bf" class="header-mark"></a>优先使用对象组合，而不是继承</h3><p>继承表达的一种类属关系，例如 大熊猫🐼继承动物，动物继承于生物，这是表达了一种类属关系(is-a)。</p>
<p>继承在某种程度上破坏了封装性，子类父类耦合度较高。</p>
<p>例如子类无法继承多个父类，父类中的方法子类无条件拥有，从父类继承的方法不能在运行时进行改变。这些都时继承所带来的缺点或者不足。</p>
<p>而对象组合只要求被组合的对象具有良好的定义接口。</p>
<h3 id="针对接口编程而不是针对实现编程" class="headerLink">
    <a href="#%e9%92%88%e5%af%b9%e6%8e%a5%e5%8f%a3%e7%bc%96%e7%a8%8b%e8%80%8c%e4%b8%8d%e6%98%af%e9%92%88%e5%af%b9%e5%ae%9e%e7%8e%b0%e7%bc%96%e7%a8%8b" class="header-mark"></a>针对接口编程，而不是针对实现编程</h3><p>不要将变量类型声明为具体某个类型，而是声明为接口；客服端无需知道对象的具体类型，只需要知道对象的接口；减少系统中各部分的依赖关系，从而实现“高内聚，低耦合”的设计。</p>
<p>接口标准化是软件开发的重要举措，面向接口设计可以使工程分工，代码解耦。</p>
<hr>
<p>不同的设计模型对设计原则有着不同的依赖，设计原则指导的设计模式的进行。</p>
]]></description></item></channel></rss>