{"componentChunkName":"component---src-templates-post-template-js","path":"/posts/solid-dependency-inversion","result":{"data":{"markdownRemark":{"id":"23dd6830-e851-5202-925e-d8ee41d55fe4","html":"<p>第一次聽到 Dependency Inversion(依賴反轉) 這個詞，是在面試的時候。AmazingTalker 的 take home 專案裡面提到，期待面試者寫出來的程式碼，符合 <strong>SOLID 原則</strong>。而其中 SOLID 的 <strong>D</strong>，指的就是 <strong>D</strong>ependency Inversion。</p>\n<p>使用依賴反轉，可以讓程式碼之間減少依賴，寫出維護成本更低的程式碼。</p>\n<p>而這一篇文章希望可以用最直白的方法，讓我們更好理解什麼是依賴反轉。</p>\n<p>以下的例子來自於 <a href=\"https://bit.ly/clean-architecture-kingstone\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">無瑕的程式碼 ： 整潔的軟體設計與架構篇(Clean Architecture: A Craftsman’s Guide to Software Structure and Design)</a> 這本書。</p>\n<h2 id=\"情境\" style=\"position:relative;\"><a href=\"#%E6%83%85%E5%A2%83\" aria-label=\"情境 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>情境</h2>\n<p>“請寫一支程式，可以輸出 Hello World 字串到終端機上”</p>\n<p>如果我們用 C 語言寫會是這樣：</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span><span class=\"token string\">&lt;stdio.h></span></span>\n\n<span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token function\">printf</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Hello World\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>很簡單對吧！</p>\n<h2 id=\"更多情境\" style=\"position:relative;\"><a href=\"#%E6%9B%B4%E5%A4%9A%E6%83%85%E5%A2%83\" aria-label=\"更多情境 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>更多情境</h2>\n<ul>\n<li>如果我今天想要把 Hello World 字串寫到檔案裡面呢？</li>\n<li>如果儲存檔案的裝置換成磁帶呢？</li>\n</ul>\n<p>我們要每一種裝置都重寫一份 code 嗎？ 如果是，那其實我們這支程式<strong>依賴</strong>於裝置。\n當我們有新的裝置要輸出，就要重新修改原本的程式碼。</p>\n<p>圖像化表示的話，會是這樣：</p>\n<figure style=\"max-width: 450px\">\n\t<span class=\"gatsby-resp-image-wrapper\" style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 642px; \">\n      <a class=\"gatsby-resp-image-link\" href=\"/static/1f36c776542a9ab74f09fffa4125bafe/1bba8/di-1.png\" style=\"display: block\" target=\"_blank\" rel=\"noopener\">\n    <span class=\"gatsby-resp-image-background-image\" style=\"padding-bottom: 43.75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAAAsSAAALEgHS3X78AAABdElEQVQoz21RWWoCQRSc6EfIZ3ICv7yEQ66Sy3gID+EFZpB8ua+4grsg7iuCH9rSlVfNzGQkaSj69aOqqNfPGg6HIAaDAUajEbrdrtrtdpjNZo4lB0CkXC5HWFerVXu5XEKgx+OxbrVa6PV6fGOxWKBYLMLK5XIolUrgLUK4rqsmkwnENDBsNpvGsN1u26fTCZfLRUut0+k0HMfhG8fjEY1GA9Z2u8V6vcZms/Fvdb1eMZ1OA8NMJhNlXalU7NVqZRLKramljumY0iTc7/dME0BI6na7keQbvhCsO51OgnyBFq4x9HXs12o1WIzKx+FwMJD6oZTiH36Lx2s8Hv+IxWLvUr8lk8kv8oWnPSCMer3+axiCoqEkdJlKRo+mUikzsvzxpyfWTBnWsW8SeqmeDO/3+9PI8/ncX0rC4/8xDEY+n8/g5kJQWmsu6N8te3ztIdCxb7Ysf8WNhqGYot/vB4b5fN4YFgoFm3yBFp4O69jPZrP4AUanMSS4f/hXAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;\"></span>\n  <picture>\n        <source srcset=\"/static/1f36c776542a9ab74f09fffa4125bafe/8ac56/di-1.webp 240w,\n/static/1f36c776542a9ab74f09fffa4125bafe/d3be9/di-1.webp 480w,\n/static/1f36c776542a9ab74f09fffa4125bafe/7eb86/di-1.webp 642w\" sizes=\"(max-width: 642px) 100vw, 642px\" type=\"image/webp\">\n        <source srcset=\"/static/1f36c776542a9ab74f09fffa4125bafe/8ff5a/di-1.png 240w,\n/static/1f36c776542a9ab74f09fffa4125bafe/e85cb/di-1.png 480w,\n/static/1f36c776542a9ab74f09fffa4125bafe/1bba8/di-1.png 642w\" sizes=\"(max-width: 642px) 100vw, 642px\" type=\"image/png\">\n        <img class=\"gatsby-resp-image-image\" src=\"/static/1f36c776542a9ab74f09fffa4125bafe/1bba8/di-1.png\" alt=\"&#x4F9D;&#x8CF4;&#x53CD;&#x8F49;&#x7BC4;&#x4F8B;&#x4E00;\" title=\"&#x4F9D;&#x8CF4;&#x53CD;&#x8F49;&#x7BC4;&#x4F8B;&#x4E00;\" loading=\"lazy\" style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\">\n      </picture>\n  </a>\n    </span>\n</figure>\n<h2 id=\"那麼，我們有可能改變這樣的依賴關係嗎？\" style=\"position:relative;\"><a href=\"#%E9%82%A3%E9%BA%BC%EF%BC%8C%E6%88%91%E5%80%91%E6%9C%89%E5%8F%AF%E8%83%BD%E6%94%B9%E8%AE%8A%E9%80%99%E6%A8%A3%E7%9A%84%E4%BE%9D%E8%B3%B4%E9%97%9C%E4%BF%82%E5%97%8E%EF%BC%9F\" aria-label=\"那麼，我們有可能改變這樣的依賴關係嗎？ permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>那麼，我們有可能改變這樣的依賴關係嗎？</h2>\n<p>有的，藉由<strong>定義一個彼此溝通合作的介面</strong>，我們可以某種形式地反轉它。</p>\n<p>在 C 語言裡面，其實定義了 FILE type 的指標，必須要實作五個函數 open, close, read, write, seek。只要有實作五個函數，我們使用 fprintf，就可以使用這個指標作為輸出裝置。</p>\n<p>終端機實作了這五個函數，作業系統在串接硬碟時也實作了這五個函數，讓我們可以不論是要輸出到終端機，還是檔案，都可以不用修改原本的程式碼。</p>\n<p>舉個實例是這樣：</p>\n<div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token macro property\"><span class=\"token directive-hash\">#</span><span class=\"token directive keyword\">include</span><span class=\"token string\">&lt;stdio.h></span></span>\n\n<span class=\"token comment\">// 這邊都不用改</span>\n<span class=\"token keyword\">void</span> <span class=\"token function\">printHelloWorld</span><span class=\"token punctuation\">(</span>FILE <span class=\"token operator\">*</span>out<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token function\">fprintf</span><span class=\"token punctuation\">(</span>out<span class=\"token punctuation\">,</span> <span class=\"token string\">\"Hello World\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">int</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">// 想輸出到終端機</span>\n  <span class=\"token function\">printHelloWorld</span><span class=\"token punctuation\">(</span><span class=\"token constant\">stdout</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token comment\">// 想輸出到檔案</span>\n  FILE <span class=\"token operator\">*</span>filePointer <span class=\"token operator\">=</span> <span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">;</span>\n  <span class=\"token function\">printHellowWorld</span><span class=\"token punctuation\">(</span>filePointer<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token comment\">// 想輸出到其他裝置</span>\n  FILE <span class=\"token operator\">*</span>deviceFilePointer <span class=\"token operator\">=</span> <span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">;</span>\n  <span class=\"token function\">printHellowWorld</span><span class=\"token punctuation\">(</span>deviceFilePointer<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token keyword\">return</span> <span class=\"token number\">0</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>如此一來，我們已經改變了依賴關係，這隻程式實際上不再依賴裝置本身，而是依賴<strong>介面</strong>，而<strong>裝置也依賴介面</strong>。也就是說，兩隻程式的關係變成這樣：</p>\n<figure style=\"max-width: 600px\">\n\t<span class=\"gatsby-resp-image-wrapper\" style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; \">\n      <a class=\"gatsby-resp-image-link\" href=\"/static/6952e6f5cf3318a0861fe2be58038e8d/5819f/di-2.png\" style=\"display: block\" target=\"_blank\" rel=\"noopener\">\n    <span class=\"gatsby-resp-image-background-image\" style=\"padding-bottom: 27.083333333333332%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAAAsSAAALEgHS3X78AAAA+ElEQVQY01WQW4qEMBBF7VW2C+iFjczsxC8/FEHxASo+8S2KimgSqqtkOswIgVDee3ISJQxDsG0bLMticRxDnudfyu+Xpulz33cwTVMYhsFpT7PP/7IsteM4QNd15vs+DMMACgIIAlmWsXmeoSgKCUySRF2WBfBQEUUR37YN8FD1L/A8T8Acwz10XQdK0zQwTROM48g45wT+xuyDCmj2chwHcIl1XTnB0eb1AWL2hzFGfYZ96PselLZt/wHrupaGGFCDIADXdQXCbkO8sjTErCaEuLsEpEXD++5YZtd1QVVVEojzp+d5tyE+x22IVvINMauRIXXJjtYbbascxyhWljcAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;\"></span>\n  <picture>\n        <source srcset=\"/static/6952e6f5cf3318a0861fe2be58038e8d/8ac56/di-2.webp 240w,\n/static/6952e6f5cf3318a0861fe2be58038e8d/d3be9/di-2.webp 480w,\n/static/6952e6f5cf3318a0861fe2be58038e8d/e46b2/di-2.webp 960w,\n/static/6952e6f5cf3318a0861fe2be58038e8d/20e4c/di-2.webp 1042w\" sizes=\"(max-width: 960px) 100vw, 960px\" type=\"image/webp\">\n        <source srcset=\"/static/6952e6f5cf3318a0861fe2be58038e8d/8ff5a/di-2.png 240w,\n/static/6952e6f5cf3318a0861fe2be58038e8d/e85cb/di-2.png 480w,\n/static/6952e6f5cf3318a0861fe2be58038e8d/d9199/di-2.png 960w,\n/static/6952e6f5cf3318a0861fe2be58038e8d/5819f/di-2.png 1042w\" sizes=\"(max-width: 960px) 100vw, 960px\" type=\"image/png\">\n        <img class=\"gatsby-resp-image-image\" src=\"/static/6952e6f5cf3318a0861fe2be58038e8d/d9199/di-2.png\" alt=\"&#x4F9D;&#x8CF4;&#x53CD;&#x8F49;&#x7BC4;&#x4F8B;&#x4E8C;\" title=\"&#x4F9D;&#x8CF4;&#x53CD;&#x8F49;&#x7BC4;&#x4F8B;&#x4E8C;\" loading=\"lazy\" style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\">\n      </picture>\n  </a>\n    </span>\n</figure>\n<p>事實上，依賴關係並不是直接反轉過來，而是兩端依賴一個共用的介面。有了介面之後，我們可以讓兩端可以在不修改內部邏輯的前提下，完成不同的任務。</p>\n<p>這樣會方便很多，左邊我們可以改成輸出病例、銀行交易紀錄，右邊可以改成終端機、硬碟、磁帶…。</p>\n<figure style=\"max-width: 600px\">\n\t<span class=\"gatsby-resp-image-wrapper\" style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 960px; \">\n      <a class=\"gatsby-resp-image-link\" href=\"/static/d9398a889ba8d3b64a173e04044dae1d/5819f/di-3.png\" style=\"display: block\" target=\"_blank\" rel=\"noopener\">\n    <span class=\"gatsby-resp-image-background-image\" style=\"padding-bottom: 71.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAYAAAAvxDzwAAAACXBIWXMAAAsSAAALEgHS3X78AAACn0lEQVQ4y3VUy04iURBtECay0Z/wG/yOWSlOMsaFGxdOZq9f4EY2JK7UGfkBNi5M1AQjj+AjBIWAyrublwrKQ+mGrjmnh56YId7khtv3Vp06VacKpVAoSDQalbOzM6NcLouqqvsKlog4r6+vlf9XJBKx3niuVCr77+/vEo/HjWKxKI1GQ3hpAtTM5XL66+urlEqlXzYgAk0AHh8f/wOE7e/BYCDw16vVqglAU6nVatJqteT5+dkYDoeCSAewdfr9/ik4Ktls1pFMJpWrqyslnU47eLezs+MaAwboQ9/Hx0fhVoAszWaTdA1d16Ver+/SeGNjw618sjY3N6032O4RkL7EsADz+bwXD9yL2MtIfR62bifW/f29O5VKzaK2Mw8PDzOZTGYW9i6PxzMFGxfu5mG/DIaLmqZ58e1VYKQiHfXi4qJ0eXnZQU23mTIZgP1XGOu4b8disfbT05PBuzFRB87bKFn39PS0dHt7q+JdtVJmHQEk/X6fv6yhY6zoarfblbu7O0F0eXt7k/Pz81U7dXREADWlKJbC7XZbKIoJFiajfxSFKR0eHv5MJBICUYadTmdIh2Aw+IMlISBsA4ZhWKLA30QdTTK0DoigswXwvWunjPqt3NzcEHDw8vIyICBSX7EZgsweAelLDIhiUnovDtwLePiOqBRlmg4A+Ya0rJTIngsgS2O8aQpIUeC3AL+/omAatHA4rIVCoTJq1oPBts0ABnPY6wBcA/Aagq9D+Tn7Hdn40Bl9sC4DUANLjYUVSM7aSa/X42+AxltbW5/2oc/n+zIevYBpmsKRZQ9yQBSOCw7c+mg04uPBmJ0To+iAwi72HoK6wJC95/gwevak6BTFqiEZgjZrY7AtOPD2LB8dHU2wOzk5mfhzoC8xuP8AVFvEI3yFOOgAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;\"></span>\n  <picture>\n        <source srcset=\"/static/d9398a889ba8d3b64a173e04044dae1d/8ac56/di-3.webp 240w,\n/static/d9398a889ba8d3b64a173e04044dae1d/d3be9/di-3.webp 480w,\n/static/d9398a889ba8d3b64a173e04044dae1d/e46b2/di-3.webp 960w,\n/static/d9398a889ba8d3b64a173e04044dae1d/20e4c/di-3.webp 1042w\" sizes=\"(max-width: 960px) 100vw, 960px\" type=\"image/webp\">\n        <source srcset=\"/static/d9398a889ba8d3b64a173e04044dae1d/8ff5a/di-3.png 240w,\n/static/d9398a889ba8d3b64a173e04044dae1d/e85cb/di-3.png 480w,\n/static/d9398a889ba8d3b64a173e04044dae1d/d9199/di-3.png 960w,\n/static/d9398a889ba8d3b64a173e04044dae1d/5819f/di-3.png 1042w\" sizes=\"(max-width: 960px) 100vw, 960px\" type=\"image/png\">\n        <img class=\"gatsby-resp-image-image\" src=\"/static/d9398a889ba8d3b64a173e04044dae1d/d9199/di-3.png\" alt=\"&#x4F9D;&#x8CF4;&#x53CD;&#x8F49;&#x7BC4;&#x4F8B;&#x4E09;\" title=\"&#x4F9D;&#x8CF4;&#x53CD;&#x8F49;&#x7BC4;&#x4F8B;&#x4E09;\" loading=\"lazy\" style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\">\n      </picture>\n  </a>\n    </span>\n</figure>\n<h2 id=\"小小總結\" style=\"position:relative;\"><a href=\"#%E5%B0%8F%E5%B0%8F%E7%B8%BD%E7%B5%90\" aria-label=\"小小總結 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>小小總結</h2>\n<figure>\n\t<blockquote>\n\t\t<p>所謂的依賴反轉，就是藉由定義一個溝通的介面，讓兩端的程式碼可以互相合作，以達成不同程式目的，並讓兩端的程式碼不必為了另外一端而做內部修改。</p>\n    兩端都可以像插件一樣，可以抽換整個模組以達成新的目的，進而達到降低維護成本的目的。\n\t</blockquote>\n</figure>\n<hr>\n<h3 id=\"運用-dependency-inversion-有什麼缺點嗎？\" style=\"position:relative;\"><a href=\"#%E9%81%8B%E7%94%A8-dependency-inversion-%E6%9C%89%E4%BB%80%E9%BA%BC%E7%BC%BA%E9%BB%9E%E5%97%8E%EF%BC%9F\" aria-label=\"運用 dependency inversion 有什麼缺點嗎？ permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>運用 Dependency Inversion 有什麼缺點嗎？</h3>\n<p>假設我們今天定義出一個很棒的介面，左右兩端各有 10 支程式依賴這個介面，完成 100 個不同的任務。我們用 10+10 的時間完成了原本 100 時間才能完成的任務，聽起來非常棒。</p>\n<p><strong>但，如果介面改了呢？</strong></p>\n<p>沒錯，就左右兩邊加起來 20 支程式都要改。</p>\n<p>商業世界變動快速，我們一定都遇過，業主需求改變、PM 需求改變，老闆今天心情好想加個功能…。\n各種因素都有可能造成我們原本定義好的介面必須被改變，而這牽一髮動全身。如果原本每一種 case 都分開寫，還有可能不需要改動到 20 支程式。</p>\n<p>所以，如何定義好的介面，讓商業邏輯不會動到它，最有效減少程式碼維護的成本，永遠都是身為一名工程師的修煉。</p>\n<hr>\n<p>最後是我個人大推 <a href=\"https://bit.ly/clean-architecture-kingstone\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Clean Architecture</a> 這本書，讓我們用更抽象化的層級思考所寫的程式，那些結構的差異，如何影響我們的開發經驗。以及如何降低維護程式碼的成本，擁有更好的生活。</p>","fields":{"slug":"/posts/solid-dependency-inversion","tagSlugs":["/tag/dependency-inversion/","/tag/software-achitecture/","/tag/solid/"]},"frontmatter":{"date":"2020-12-04T16:12:04.772Z","description":"Dependency Inversion 是一種程式設計技巧，有助於改變程式之間相互依賴的關係，寫出更容易被重複使用、更能擴充的程式，降低維護成本。是邁向資深工程師必學的概念。如果你聽過 SOLID 原則，Dependency Inversion 就是裡面的 \"D\"。","tags":["Dependency Inversion","Software Achitecture","SOLID"],"title":"直白理解什麼是 Dependency Inversion （依賴反轉）","socialImage":{"publicURL":"/static/eeba515438f6b88c4b710090f9405159/di-media.jpg"}}}},"pageContext":{"slug":"/posts/solid-dependency-inversion"}},"staticQueryHashes":["251939775","401334301","825871152"]}