<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Design Patterns on AI VOID</title><link>https://ai-blog.noorshomelab.dev/categories/design-patterns/</link><description>Recent content in Design Patterns on AI VOID</description><generator>Hugo</generator><language>en</language><lastBuildDate>Thu, 04 Dec 2025 00:00:00 +0000</lastBuildDate><atom:link href="https://ai-blog.noorshomelab.dev/categories/design-patterns/index.xml" rel="self" type="application/rss+xml"/><item><title>Chapter 16: Design Patterns: Solutions to Common Problems - Part 1</title><link>https://ai-blog.noorshomelab.dev/java-mastery-2025/chapter-16-design-patterns-creational-structural/</link><pubDate>Thu, 04 Dec 2025 00:00:00 +0000</pubDate><guid>https://ai-blog.noorshomelab.dev/java-mastery-2025/chapter-16-design-patterns-creational-structural/</guid><description>&lt;h2 id="chapter-16-design-patterns-solutions-to-common-problems---part-1"&gt;Chapter 16: Design Patterns: Solutions to Common Problems - Part 1&lt;/h2&gt;
&lt;p&gt;Welcome back, aspiring Java architects! You&amp;rsquo;ve come a long way, mastering the fundamentals of Java, object-oriented programming, and even some advanced concepts. Now, it&amp;rsquo;s time to elevate your code to the next level. In this chapter, we&amp;rsquo;re diving into the fascinating world of &lt;strong&gt;Design Patterns&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Design patterns are like blueprints for solving common problems in software design. They aren&amp;rsquo;t concrete solutions you can just copy-paste, but rather generalized, reusable solutions to recurring problems in a particular context. Think of them as a shared vocabulary and a set of best practices that experienced developers have refined over decades. By learning them, you&amp;rsquo;ll not only write more robust, maintainable, and flexible code, but you&amp;rsquo;ll also be able to understand complex frameworks and discuss software design with other professionals more effectively.&lt;/p&gt;</description></item><item><title>Best Practices and Common Patterns with Injection-JS</title><link>https://ai-blog.noorshomelab.dev/injection-js-guide-chapters/best-practices-and-common-patterns/</link><pubDate>Sat, 25 Oct 2025 00:00:00 +0000</pubDate><guid>https://ai-blog.noorshomelab.dev/injection-js-guide-chapters/best-practices-and-common-patterns/</guid><description>&lt;h2 id="5-best-practices-and-common-patterns"&gt;5. Best Practices and Common Patterns&lt;/h2&gt;
&lt;p&gt;Mastering a library like Injection-JS isn&amp;rsquo;t just about knowing its features; it&amp;rsquo;s about applying them effectively to write clean, maintainable, and robust code. This chapter covers essential best practices, common patterns, and potential pitfalls to help you leverage Injection-JS to its fullest.&lt;/p&gt;
&lt;h3 id="adhering-to-solid-principles"&gt;Adhering to SOLID Principles&lt;/h3&gt;
&lt;p&gt;Dependency Injection itself is a powerful enabler of SOLID principles, which are fundamental to good software design.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Single Responsibility Principle (SRP)&lt;/strong&gt;: Each class should have only one reason to change. DI helps by allowing a class to focus on its primary responsibility, delegating concerns like logging, data access, or authentication to injected dependencies.
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Bad:&lt;/em&gt; A &lt;code&gt;UserService&lt;/code&gt; handles user logic, &lt;em&gt;and&lt;/em&gt; connects to the database, &lt;em&gt;and&lt;/em&gt; logs messages.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Good:&lt;/em&gt; &lt;code&gt;UserService&lt;/code&gt; handles user logic and &lt;em&gt;injects&lt;/em&gt; &lt;code&gt;UserRepository&lt;/code&gt; (for DB access) and &lt;code&gt;Logger&lt;/code&gt; (for logging).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Open/Closed Principle (OCP)&lt;/strong&gt;: Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification. With DI, you can introduce new implementations of an interface or abstract class without modifying the consumer of that dependency. This is especially clear with &lt;code&gt;useClass&lt;/code&gt;, &lt;code&gt;useFactory&lt;/code&gt;, and &lt;code&gt;useExisting&lt;/code&gt;.
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Example:&lt;/em&gt; If a &lt;code&gt;NotificationService&lt;/code&gt; is injected, you can switch from &lt;code&gt;EmailNotificationService&lt;/code&gt; to &lt;code&gt;SMSNotificationService&lt;/code&gt; by changing a provider, not the client code.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Liskov Substitution Principle (LSP)&lt;/strong&gt;: Objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program. When you inject an abstraction (like an interface represented by an &lt;code&gt;InjectionToken&lt;/code&gt; or a base class), you can substitute different concrete implementations, and the client code should still work correctly.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dependency Inversion Principle (DIP)&lt;/strong&gt;: High-level modules should not depend on low-level modules. Both should depend on abstractions. Abstractions should not depend on details. Details should depend on abstractions. DI enforces this by making high-level classes depend on abstract &lt;code&gt;InjectionToken&lt;/code&gt;s or interface-like class types, rather than concrete implementations. The injector then provides the concrete details.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="when-to-use-which-provider-type"&gt;When to Use Which Provider Type&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;useClass&lt;/code&gt;&lt;/strong&gt;:&lt;/p&gt;</description></item></channel></rss>