{"componentChunkName":"component---src-templates-blog-post-jsx","path":"/blog/why-the-dependency-inversion-principle-is-worth-using/","result":{"data":{"site":{"siteMetadata":{"name":"Huzaifa Rasheed","title":"Huzaifa Rasheed","description":"Software Engineer","about":"\n      Hey, I'm Huzaifa.\n      <br/><br/>\n      Engineer by trade, builder by instinct - I believe in owning my stack, shipping fast, and occasionally running on chai (tea) and stubbornness. I work best in that sweet spot between deep focus and fast feedback - solo or in sync with a good team.\n      <br/><br/>\n      This site's my little corner of the internet - part portfolio, part lab - where I document what I build, break, or learn.\n      <br/><br/>\n      Outside work, I'm into long walks, pixel-perfect headshots in FPS games (eventually... maybe), plants I probably overwater, and the occasional \"classified\" hobby to stay curious.\n      <br/><br/>\n      Reach out anytime - my digital door's always open. 👋\n    ","twitter":"https://twitter.com/huzRasheed","github":"https://github.com/huzaifa-99","linkedin":"https://www.linkedin.com/in/huzaifa-rasheed/","devto":"https://dev.to/huzaifa99","stackoverflow":"https://stackoverflow.com/users/12579290/huzaifa","leetcode":"https://leetcode.com/rhuzaifa","discord":"https://discordapp.com/users/rhuzaifa","email":"dev@rhuzaifa.com","projects":[{"name":"FFMpeg Web","description":"An experimental browser-based terminal that runs FFmpeg using WebAssembly, enabling media processing directly in the browser.","link":"https://ffmpeg-web.rhuzaifa.com/","github":"https://github.com/huzaifa-99/ffmpeg-web"},{"name":"Feed base 2","description":"A mini browser game where players manipulate 4-bit binary blocks to match target BCD values - part puzzle, part binary logic trainer.","link":"https://feedbase2.rhuzaifa.com/","github":"https://github.com/huzaifa-99/feed-base-2"},{"name":"Fabric browser extension","description":"A Chrome extension that injects engineered Fabric prompts directly into the ChatGPT interface for enhanced workflow automation.","link":"https://github.com/huzaifa-99/fabric-browser-extension","github":"https://github.com/huzaifa-99/fabric-browser-extension"},{"name":"Pure Cinema","description":"An experimental, tongue-in-cheek text-to-video generator that stitches together footage, synthesized voiceovers, and background music with a Node.js + ffmpeg pipeline. Not quite Hollywood, but it renders.","link":"https://cinema.rhuzaifa.com","github":null},{"name":"Aria2c Packload","description":"A Bash script for bulk downloading magnet links or torrents using aria2c - optimized for series or list-based transfers.","link":"https://github.com/huzaifa-99/aria2c-packload","github":"https://github.com/huzaifa-99/aria2c-packload"},{"name":"RSS Watchdog","description":"A lightweight Bash script that watches RSS/Atom feeds and compiles a Markdown-based reading checklist for Unix systems.","link":"https://github.com/huzaifa-99/rss-watchdog","github":"https://github.com/huzaifa-99/rss-watchdog"},{"name":"QuoteGen","description":"A quote graphic generator that produces stylized quote images with random selection and a built-in editor for customization.","link":"https://quotegen.rhuzaifa.com/","github":null},{"name":"WebRTC Video Chat","description":"A basic WebRTC-powered app enabling peer-to-peer video and audio calls between two users.","link":"https://webrtc-video-chat.rhuzaifa.com/","github":null}],"experience":null,"skills":[{"name":"Languages & Frameworks","description":"JavaScript, TypeScript, Python, Bash - Frameworks include Node.js, React, Next.js, Vue, React Native, FastAPI."},{"name":"Databases & Storage","description":"PostgreSQL, MySQL, MongoDB - Experience with schema design, indexing, query optimization, and migrations."},{"name":"Cloud & Infrastructure","description":"AWS (EC2, RDS, S3, Lambda), Vercel, Netlify, Heroku - Comfortable with serverless, autoscaling, and cost optimization."},{"name":"DevOps & Tooling","description":"Docker, Git, CI/CD pipelines (GitHub Actions, GitLab CI) - Experience with observability, containerization, and release workflows."},{"name":"Testing & QA Automation","description":"Jest, Playwright, Puppeteer, Selenium - Focus on E2E testing, mocking APIs, and maintaining test coverage."}]}},"markdownRemark":{"id":"9986ffd3-42b0-563c-a13d-fffdb4f0e95c","excerpt":"Repost of https://dev.to/rhuzaifa/why-the-dependency-inversion-principle-is-worth-using-opj Dependency Inversion is the D of SOLID, and you may wonder, what is…","html":"<blockquote>\n<p>Repost of <a href=\"https://dev.to/rhuzaifa/why-the-dependency-inversion-principle-is-worth-using-opj\">https://dev.to/rhuzaifa/why-the-dependency-inversion-principle-is-worth-using-opj</a></p>\n</blockquote>\n<p>Dependency Inversion is the <strong>D</strong> of <strong>SOLID</strong>, and you may wonder, what is <strong>SOLID?</strong></p>\n<blockquote>\n<p>SOLID are 5 software development principles or guidelines based on Object-Oriented design making it easier for you to make your projects scalable and maintainable.</p>\n</blockquote>\n<p>Rules and Conventions have their place. In code, the SOLID design is considered a convention/best-practice.</p>\n<h3>Now what is Dependency Inversion?</h3>\n<p>Basically</p>\n<blockquote>\n<p>High-Level Modules Should Not Depend Upon Low-Level Modules. Both Should Depend Upon Abstractions.</p>\n</blockquote>\n<p>Not too difficult. Right? Here is more</p>\n<blockquote>\n<p>Abstractions Should Not Depend Upon Details. Details\nShould Depend Upon Abstractions.</p>\n</blockquote>\n<p>Too confusing? This might help</p>\n<p><img src=\"https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eznvnc2jslo1phhycz5a.png\" alt=\"Dependency Inversion Pictorial Example\"></p>\n<h4>What This Means</h4>\n<p>✔️ Both High-level and Low-level modules should depend on the same Abstraction.<br/>\n✔️ High-level modules should implement abstractions that implement Low-Level modules and vice-versa.<br/>\n✔️ Abstractions can implement different details of the operation.<br/>\n❌ High-level modules can implement details surpassing abstractions.<br/></p>\n<h3>Goal</h3>\n<ul>\n<li>Follow an abstract/facade/wrapper pattern.</li>\n<li>Hide Low-Level implementation from High-Level Implementation.</li>\n</ul>\n<h3>A Simple Use Case</h3>\n<p>We will continue with the payment example from <strong><a href=\"/blog/explained-open-close-principle-in-2-minutes\">Open/Close Principle</a></strong>. But for this example at the moment we only accept cash payment.</p>\n<div class=\"gatsby-highlight\" data-language=\"typescript\"><pre class=\"language-typescript\"><code class=\"language-typescript\"><span class=\"token keyword\">interface</span> <span class=\"token class-name\">Payment</span> <span class=\"token punctuation\">{</span>\n\t<span class=\"token function\">pay</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">:</span> <span class=\"token builtin\">boolean</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">class</span> <span class=\"token class-name\">CashPayment</span> <span class=\"token keyword\">implements</span> <span class=\"token class-name\">Payment</span> <span class=\"token punctuation\">{</span>\n\t<span class=\"token keyword\">public</span> <span class=\"token function\">pay</span><span class=\"token punctuation\">(</span>amount<span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n\t\t<span class=\"token comment\">// handle cash payment logic</span>\n\t<span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">function</span> <span class=\"token function\">makePayment</span><span class=\"token punctuation\">(</span>amount<span class=\"token operator\">:</span> <span class=\"token builtin\">number</span><span class=\"token punctuation\">,</span> paymentMethod<span class=\"token operator\">:</span> Payment<span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n\t<span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span>paymentMethod<span class=\"token punctuation\">.</span><span class=\"token function\">pay</span><span class=\"token punctuation\">(</span>amount<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n\t\t<span class=\"token keyword\">return</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">;</span>\n\t<span class=\"token punctuation\">}</span>\n\t<span class=\"token keyword\">return</span> <span class=\"token boolean\">false</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>In this particular example, <code class=\"language-text\">makePayment()</code> is a high-level module and <code class=\"language-text\">CashPayment</code> is a low-level module. It clearly has no wrapper/abstraction layer. </p>\n<p>Now, what if we want to add credit card payment? We might modify our code like this</p>\n<div class=\"gatsby-highlight\" data-language=\"typescript\"><pre class=\"language-typescript\"><code class=\"language-typescript\"><span class=\"token keyword\">interface</span> <span class=\"token class-name\">Payment</span> <span class=\"token punctuation\">{</span>\n\t<span class=\"token function\">pay</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">:</span> <span class=\"token builtin\">boolean</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token comment\">// (low-level module)</span>\n<span class=\"token keyword\">class</span> <span class=\"token class-name\">CashPayment</span> <span class=\"token keyword\">implements</span> <span class=\"token class-name\">Payment</span> <span class=\"token punctuation\">{</span>\n\t<span class=\"token function\">constructor</span><span class=\"token punctuation\">(</span>user<span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n\t\t<span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>user <span class=\"token operator\">=</span> user\n\t<span class=\"token punctuation\">}</span>\n\n\t<span class=\"token keyword\">public</span> <span class=\"token function\">pay</span><span class=\"token punctuation\">(</span>amount<span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n\t\t<span class=\"token comment\">// handle cash payment logic</span>\n\t<span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token comment\">// (low-level module)</span>\n<span class=\"token keyword\">class</span> <span class=\"token class-name\">CreditCardPayment</span> <span class=\"token keyword\">implements</span> <span class=\"token class-name\">Payment</span> <span class=\"token punctuation\">{</span>\n\t<span class=\"token function\">constructor</span><span class=\"token punctuation\">(</span>user<span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n\t\t<span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>user <span class=\"token operator\">=</span> user\n\t<span class=\"token punctuation\">}</span>\n\n\t<span class=\"token keyword\">public</span> <span class=\"token function\">pay</span><span class=\"token punctuation\">(</span>amount<span class=\"token punctuation\">,</span> creditCardId<span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n\t\t<span class=\"token comment\">// handle creditCard payment logic</span>\n\t<span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\n\n<span class=\"token comment\">// (High-level Module)</span>\n<span class=\"token keyword\">function</span> <span class=\"token function\">makePayment</span><span class=\"token punctuation\">(</span>amount<span class=\"token operator\">:</span> <span class=\"token builtin\">number</span><span class=\"token punctuation\">,</span> paymentMethod<span class=\"token operator\">:</span> Payment<span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n  \n\t<span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span>paymentMethod <span class=\"token keyword\">instanceof</span> <span class=\"token class-name\">CashPayment</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n\t\t<span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span>paymentMethod<span class=\"token punctuation\">.</span><span class=\"token function\">pay</span><span class=\"token punctuation\">(</span>amount<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n\t\t\t<span class=\"token keyword\">return</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">;</span>\n\t\t<span class=\"token punctuation\">}</span>\n\t<span class=\"token punctuation\">}</span>\n\n\t<span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span>paymentMethod <span class=\"token keyword\">instanceof</span> <span class=\"token class-name\">CreditCardPayment</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n\t\t<span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span>paymentMethod<span class=\"token punctuation\">.</span><span class=\"token function\">pay</span><span class=\"token punctuation\">(</span>amount<span class=\"token punctuation\">,</span>paymentMethod<span class=\"token punctuation\">.</span>user<span class=\"token punctuation\">.</span>creditCardId<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n\t\t\t<span class=\"token keyword\">return</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">;</span>\n\t\t<span class=\"token punctuation\">}</span>\n\t<span class=\"token punctuation\">}</span>\n  \n  \t<span class=\"token keyword\">return</span> <span class=\"token boolean\">false</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>This clearly violates the <strong>Dependency Inversion</strong> principle since the high-level module is implementing details for low-level modules. It also violates the <strong><a href=\"/blog/why-you-should-be-following-the-single-responsibility-principle\">Single Responsibility Principle</a></strong>.</p>\n<hr>\n<p>Using <strong>Dependency Inversion</strong>, we will make wrapper classes or abstractions around cash and credit payment implementations.</p>\n<div class=\"gatsby-highlight\" data-language=\"typescript\"><pre class=\"language-typescript\"><code class=\"language-typescript\"><span class=\"token keyword\">interface</span> <span class=\"token class-name\">Payment</span> <span class=\"token punctuation\">{</span>\n\t<span class=\"token function\">pay</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">:</span> <span class=\"token builtin\">boolean</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token comment\">// (Wrapper/Abstraction around cash payment)</span>\n<span class=\"token keyword\">class</span> <span class=\"token class-name\">CashHandler</span> <span class=\"token keyword\">implements</span> <span class=\"token class-name\">Payment</span> <span class=\"token punctuation\">{</span>\n\t<span class=\"token function\">constructor</span><span class=\"token punctuation\">(</span>user<span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n\t\t<span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>user <span class=\"token operator\">=</span> user\n\t\t<span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>CashPayment <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">CashPayment</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\t<span class=\"token punctuation\">}</span>\n\n\t<span class=\"token function\">pay</span><span class=\"token punctuation\">(</span>amount<span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n\t\t<span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>CashPayment<span class=\"token punctuation\">.</span><span class=\"token function\">pay</span><span class=\"token punctuation\">(</span>amount<span class=\"token punctuation\">)</span>\n\t<span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token comment\">// (low-level module)</span>\n<span class=\"token keyword\">class</span> <span class=\"token class-name\">CashPayment</span> <span class=\"token punctuation\">{</span>\n\t<span class=\"token keyword\">public</span> <span class=\"token function\">pay</span><span class=\"token punctuation\">(</span>amount<span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n\t\t<span class=\"token comment\">// handle cash payment logic</span>\n\t<span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\n\n<span class=\"token comment\">// (Wrapper/Abstraction around credit card payment)</span>\n<span class=\"token keyword\">class</span> <span class=\"token class-name\">CreditCardHandler</span> <span class=\"token keyword\">implements</span> <span class=\"token class-name\">Payment</span> <span class=\"token punctuation\">{</span>\n\t<span class=\"token function\">constructor</span><span class=\"token punctuation\">(</span>user<span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n\t\t<span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>user <span class=\"token operator\">=</span> user\n\t\t<span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>CreditCardPayment <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">CreditCardPayment</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\t<span class=\"token punctuation\">}</span>\n\n\t<span class=\"token function\">pay</span><span class=\"token punctuation\">(</span>amount<span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n\t\t<span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>CreditCardPayment<span class=\"token punctuation\">.</span><span class=\"token function\">pay</span><span class=\"token punctuation\">(</span>amount<span class=\"token punctuation\">,</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>user<span class=\"token punctuation\">.</span>creditCardId<span class=\"token punctuation\">)</span>\n\t<span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token comment\">// (low-level module)</span>\n<span class=\"token keyword\">class</span> <span class=\"token class-name\">CreditCardPayment</span> <span class=\"token punctuation\">{</span>\n\t<span class=\"token keyword\">public</span> <span class=\"token function\">pay</span><span class=\"token punctuation\">(</span>amount<span class=\"token punctuation\">,</span> creditCardId<span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n\t\t<span class=\"token comment\">// handle creditCard payment logic</span>\n\t<span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\n\n<span class=\"token comment\">// (High-level Module)</span>\n<span class=\"token keyword\">function</span> <span class=\"token function\">makePayment</span><span class=\"token punctuation\">(</span>amount<span class=\"token operator\">:</span> <span class=\"token builtin\">number</span><span class=\"token punctuation\">,</span> paymentMethod<span class=\"token operator\">:</span> Payment<span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n\t<span class=\"token keyword\">if</span><span class=\"token punctuation\">(</span>paymentMethod<span class=\"token punctuation\">.</span><span class=\"token function\">pay</span><span class=\"token punctuation\">(</span>amount<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">{</span>\n\t\t<span class=\"token keyword\">return</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">;</span>\n\t<span class=\"token punctuation\">}</span>\n\t<span class=\"token keyword\">return</span> <span class=\"token boolean\">false</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>As we can see now our high-level modules are separated by an abstract layer hiding the details of low-level implementation. We inverted the dependencies.</p>\n<h3>Why Dependency Inversion is Worth Using?</h3>\n<p>Consider This</p>\n<blockquote>\n<p>We want to add PayPal and WireTransfer Payment Options to our existing code (the example we just did). It can be done easily without touching our existing code. We only have to add low-level and wrapper implementations for PayPal and WireTransfer Payments. Thus, our High-level implementations never break since we are not touching it.</p>\n</blockquote>\n<p>Also<br/></p>\n<ul>\n<li>We create resilient and reusable code.</li>\n<li>Code that is easier to maintain.</li>\n<li>Easier to test individual code components.</li>\n<li>We prevent code breakages by not touching high-level implementation</li>\n</ul>\n<p>The pattern for other <strong>SOLID</strong> principles like <strong><a href=\"/blog/is-it-practical-to-use-interface-segregation-principle\">Interface Segregation</a></strong> and <strong><a href=\"/blog/is-the-liskov-substitution-principle-really-useful\">Liskov Substitution</a></strong> is much similar in terms of code breakages i.e <strong>:</strong> Avoid Them in the long run.</p>\n<hr>\n<p>Here it is guys. Do you use Dependency Inversion? Be sure to tell me your opinion in the comments and give this article a Heart 💖 if you liked it.</p>","frontmatter":{"title":"Why The Dependency Inversion Principle Is Worth Using","date":"April 02, 2021","description":"Discover the Dependency Inversion Principle of SOLID design, which ensures abstractions do not depend on details, but the vice versa."}}},"pageContext":{"slug":"/blog/why-the-dependency-inversion-principle-is-worth-using/","previous":{"fields":{"slug":"/blog/is-it-practical-to-use-interface-segregation-principle/"},"frontmatter":{"title":"Is It Practical To Use Interface Segregation Principle?"}},"next":{"fields":{"slug":"/blog/solid-is-it-still-useful-in-2021/"},"frontmatter":{"title":"Solid. Is It Still Useful In 2021?"}}}},"staticQueryHashes":["2276319502"]}