<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Prateek Prabhakar</title>
    <description>The latest articles on DEV Community by Prateek Prabhakar (@prateekprabhakar).</description>
    <link>https://dev.to/prateekprabhakar</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3322908%2Fa6d9417e-45e2-4716-a734-4029ccc62802.jpg</url>
      <title>DEV Community: Prateek Prabhakar</title>
      <link>https://dev.to/prateekprabhakar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/prateekprabhakar"/>
    <language>en</language>
    <item>
      <title>The Only Design Pattern Cheat Sheet You'll Need Before Interviews</title>
      <dc:creator>Prateek Prabhakar</dc:creator>
      <pubDate>Mon, 01 Sep 2025 05:14:13 +0000</pubDate>
      <link>https://dev.to/prateekprabhakar/the-only-design-pattern-cheat-sheet-youll-need-before-interviews-4npp</link>
      <guid>https://dev.to/prateekprabhakar/the-only-design-pattern-cheat-sheet-youll-need-before-interviews-4npp</guid>
      <description>&lt;p&gt;You've probably read a lot about design patterns, most of them have long explanations, heavy UML diagrams, and abstract examples that are hard to connect with real life.&lt;br&gt;
But let's be honest, when you're preparing for a tech interview, you don't need a textbook. You need a &lt;strong&gt;quick, crisp, memorable guide&lt;/strong&gt; that tells you,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What the pattern is &lt;/li&gt;
&lt;li&gt;Why it exists &lt;/li&gt;
&lt;li&gt;A real world hook to remember it &lt;/li&gt;
&lt;li&gt;A tiny pseudo code snippet for recall &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is exactly what this &lt;strong&gt;Design Pattern Cheat Sheet&lt;/strong&gt; is.&lt;br&gt;
Think of it as your one stop destination to revise all design patterns in minutes, with hooks and analogies that will stick in your head when interview pressure hits.&lt;br&gt;
And if you want to go deeper, don't worry, I have already written detailed articles for each pattern. You'll find the links next to each one for a full deep dive.&lt;/p&gt;


&lt;h3&gt;
  
  
  Creational Patterns
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Creational design patterns&lt;/strong&gt; are like a set of blueprints or recipes for creating objects. They separate the process of &lt;strong&gt;HOW&lt;/strong&gt; objects are created from the code that actually &lt;strong&gt;USES&lt;/strong&gt; them. This makes our code more flexible and easier to change later on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.&lt;/strong&gt;&lt;a href="https://dev.to/prateekprabhakar/design-patterns-simplified-part-1-factory-pattern-and-its-clones-simple-method-abstract-5dmi"&gt;&lt;strong&gt;Factory Method&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F70yv9vzy0ipp0zkpnnte.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F70yv9vzy0ipp0zkpnnte.png" alt="Factory Method Pattern: Analogy - The Hiring Manager" width="800" height="797"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Interface
Interface Sender
    Method Send(msg)

// Concrete products
Class EmailSender implements Sender
    Send(msg) → print "Email: " + msg

Class SmsSender implements Sender
    Send(msg) → print "SMS: " + msg

// Creator
Abstract Class NotificationCreator
    Abstract Method CreateSender()

Class EmailCreator extends NotificationCreator
    CreateSender() → new EmailSender()

Class SmsCreator extends NotificationCreator
    CreateSender() → new SmsSender()

// Caller
creator = new EmailCreator()
sender  = creator.CreateSender()
sender.Send("Hey! How are you doing?")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2.&lt;/strong&gt;&lt;a href="https://dev.to/prateekprabhakar/design-patterns-simplified-part-1-factory-pattern-and-its-clones-simple-method-abstract-5dmi"&gt;&lt;strong&gt;Abstract Factory&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdjq9ey40b9ccknccsk8p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdjq9ey40b9ccknccsk8p.png" alt="Abstract Factory Pattern: Analogy - The Outfit Stylist" width="800" height="802"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Abstract Factory
Interface UIFactory
    Method CreateButton()
    Method CreateInput()

// Concrete factories
Class DarkFactory implements UIFactory
    CreateButton() → new DarkButton()
    CreateInput()  → new DarkInput()

Class LightFactory implements UIFactory
    CreateButton() → new LightButton()
    CreateInput()  → new LightInput()

// Caller
factory = new DarkFactory()
btn = factory.CreateButton()
inp = factory.CreateInput()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3.&lt;/strong&gt;&lt;a href="https://dev.to/prateekprabhakar/design-patterns-simplified-part-8-prototype-pattern-aka-copy-that-2ho3"&gt;&lt;strong&gt;Prototype&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe1m39l4zpj8h74w2qfr7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe1m39l4zpj8h74w2qfr7.png" alt="Prototype Pattern: Analogy - The Object Template" width="800" height="801"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Prototype interface
Interface Document
    Method Clone()

// Concrete prototype
Class Invoice implements Document
    Property header, footer
    Clone() → return shallowCopy(this)

// Caller
invoice1 = new Invoice("Logo A", "Thanks")
invoice2 = invoice1.Clone()
invoice2.footer = "Updated Footer"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4.&lt;/strong&gt;&lt;a href="https://dev.to/prateekprabhakar/design-patterns-simplified-part-6-singleton-pattern-aka-one-and-only-one-2dca"&gt;&lt;strong&gt;Singleton&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fysjy76dgiacgw06mqp8g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fysjy76dgiacgw06mqp8g.png" alt="Singleton Pattern: Analogy - The Uno Captain" width="800" height="804"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Singleton
Class Config
    Private static instance
    Private Constructor()

    Static Method GetInstance()
        If instance == null
            instance = new Config()
        return instance

// Caller
c1 = Config.GetInstance()
c2 = Config.GetInstance()
// c1 == c2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;5.&lt;/strong&gt;&lt;a href="https://dev.to/prateekprabhakar/design-patterns-simplified-part-7-builder-pattern-aka-build-it-step-by-step-1p82"&gt;&lt;strong&gt;Builder&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvai7hxr5qffmij5zt588.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvai7hxr5qffmij5zt588.png" alt="Builder Pattern: Analogy - The Object Chef" width="800" height="792"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Class Notification
    Props: Title, Message, IsEmail, IsSMS, IsPush, Priority

Class NotificationBuilder
    Constructor() -&amp;gt; this.n = new Notification()
    Method SetTitle(t)         -&amp;gt; n.Title = t; return this
    Method SetMessage(m)       -&amp;gt; n.Message = m; return this
    Method EnableEmail()       -&amp;gt; n.IsEmail = true; return this
    Method EnableSMS()         -&amp;gt; n.IsSMS   = true; return this
    Method EnablePush()        -&amp;gt; n.IsPush  = true; return this
    Method WithPriority(p)     -&amp;gt; n.Priority = p; return this
    Method Build()             -&amp;gt; return n

// Caller
notification = new NotificationBuilder()
                 .SetTitle("Big Sale!")
                 .SetMessage("50% off today")
                 .EnableEmail()
                 .EnablePush()
                 .WithPriority("High")
                 .Build()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Structural Patterns
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Structural design patterns&lt;/strong&gt; are a set of rules for putting together classes and objects to create bigger, more useful systems. They are all about &lt;strong&gt;composition&lt;/strong&gt;, which means combining objects instead of relying solely on inheritance. Think of it like building with LEGOs, you are fitting different pieces together to make a larger, more complex model.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6.&lt;/strong&gt;&lt;a href="https://dev.to/prateekprabhakar/design-patterns-simplified-part-5-adapter-pattern-aka-lets-make-it-compatible-4jf0"&gt;&lt;strong&gt;Adapter&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnpevbvz1cg72wlog7fmz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnpevbvz1cg72wlog7fmz.png" alt="Adapter Pattern: Analogy - The Universal Adapter" width="800" height="788"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Old interface
Class LegacyPayment
    Method MakePayment(amount)

// Adapter
Class PaymentAdapter implements NewPayment
    legacy = new LegacyPayment()
    Pay(amount) → legacy.MakePayment(amount)

// Caller
p = new PaymentAdapter()
p.Pay(100)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;7.&lt;/strong&gt;&lt;a href="https://dev.to/prateekprabhakar/design-patterns-simplified-part-4-decorator-pattern-aka-wrap-it-before-you-log-it-3lfo"&gt;&lt;strong&gt;Decorator&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faioozb0gl7gotlp8mrw4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faioozb0gl7gotlp8mrw4.png" alt="Decorator Pattern: Analogy - The Coffee Customizer" width="800" height="798"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Base
Interface Coffee
    Method Cost()

Class SimpleCoffee implements Coffee
    Cost() → 50

// Decorator
Class MilkDecorator implements Coffee
    coffee
    Constructor(c) → coffee = c
    Cost() → coffee.Cost() + 20

// Caller
coffee = new MilkDecorator(new SimpleCoffee())
print coffee.Cost()   // 70
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;8.&lt;/strong&gt;&lt;a href="https://dev.to/prateekprabhakar/design-patterns-simplified-part-19-composite-pattern-aka-the-file-tree-organizer-1j1l"&gt;&lt;strong&gt;Composite&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxxdpio2bm1lpao3diu2e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxxdpio2bm1lpao3diu2e.png" alt="Composite Pattern: Analogy - The File Tree Organizer" width="800" height="801"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Component
Interface FileSystemItem
    Display(indent)

// Leaf
Class File implements FileSystemItem
    Display(i) → print i + "File"

// Composite
Class Folder implements FileSystemItem
    items = []
    Add(item) → items.Add(item)
    Display(i)
        print i + "Folder"
        For item in items → item.Display(i+1)

// Caller
root = new Folder()
root.Add(new File())
root.Display(0)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;9.&lt;/strong&gt;&lt;a href="https://dev.to/prateekprabhakar/design-patterns-simplified-part-21-facade-pattern-aka-the-one-stop-counter-49e5"&gt;&lt;strong&gt;Facade&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fogxb63burqtdalocfwq4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fogxb63burqtdalocfwq4.png" alt="Facade Pattern: Analogy - The One Stop Counter" width="800" height="801"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Subsystems
Class Lights
    Method Dim()

Class TV
    Method TurnOn()

// Facade
Class HomeTheaterFacade
    Method StartMovieNight()
        Lights.Dim()
        TV.TurnOn()

// Caller
theater = new HomeTheaterFacade()
theater.StartMovieNight()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;10.&lt;/strong&gt;&lt;a href="https://dev.to/prateekprabhakar/design-patterns-simplified-part-16-proxy-pattern-aka-the-gatekeeper-1f4j"&gt;&lt;strong&gt;Proxy&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvt0h53ag7iq9ogo400br.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvt0h53ag7iq9ogo400br.png" alt="Proxy Pattern: Analogy - The Bodyguard" width="800" height="797"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Subject
Interface Service
    Request()

// Real subject
Class RealService implements Service
    Request() → print "Real work done"

// Proxy
Class ServiceProxy implements Service
    real = new RealService()
    Request()
        print "Proxy check..."
        real.Request()

// Caller
s = new ServiceProxy()
s.Request()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;11.&lt;/strong&gt;&lt;a href="https://dev.to/prateekprabhakar/design-patterns-simplified-part-17-flyweight-pattern-aka-the-shared-furniture-4c3l"&gt;&lt;strong&gt;Flyweight&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7loj9i3vodtub3t1rlgk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7loj9i3vodtub3t1rlgk.png" alt="Flyweight Pattern: Analogy - The Character Cache" width="800" height="798"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Flyweight
Class Character
    symbol
    Constructor(s) → symbol = s

// Factory
Class CharFactory
    cache = {}
    GetChar(s)
        If not in cache → cache[s] = new Character(s)
        return cache[s]

// Caller
c1 = factory.GetChar("A")
c2 = factory.GetChar("A")
// same instance
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;12.&lt;/strong&gt;&lt;a href="https://dev.to/prateekprabhakar/design-patterns-simplified-part-18-bridge-pattern-aka-the-music-connector-1feb"&gt;&lt;strong&gt;Bridge&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcuog850p7t9xnvo0ipcw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcuog850p7t9xnvo0ipcw.png" alt="Bridge Pattern: Analogy - The Music Connector" width="800" height="800"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Implementor
Interface Device
    TurnOn()

Class TV implements Device
    TurnOn() → print "TV On"

// Abstraction
Class Remote
    device
    Constructor(d) → device = d
    Press() → device.TurnOn()

// Caller
r = new Remote(new TV())
r.Press()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Behavioral Patterns
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Behavioral design patterns&lt;/strong&gt; are about defining how objects interact and communicate with each other. They focus on &lt;strong&gt;delegating responsibilities&lt;/strong&gt; and ensuring objects can work together effectively without being tightly coupled. Think of them as the traffic rules for our code. They manage the flow of requests and the assignment of tasks between different objects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;13.&lt;/strong&gt;&lt;a href="https://dev.to/prateekprabhakar/design-patterns-simplified-part-2-strategy-pattern-aka-pick-your-coupon-wisely-2ane"&gt;&lt;strong&gt;Strategy&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn1g5jgfz7kgkvnnlfr6s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn1g5jgfz7kgkvnnlfr6s.png" alt="Strategy Pattern: Analogy - The Coupon Brain" width="800" height="801"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Strategy
Interface Coupon
    Apply(amount)

// Concrete strategies
Class Flat50 implements Coupon
    Apply(amount) → amount - 50

Class TenPercent implements Coupon
    Apply(amount) → amount * 0.9

// Caller
coupon = new Flat50()
print coupon.Apply(500)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;14.&lt;/strong&gt;&lt;a href="https://dev.to/prateekprabhakar/design-patterns-simplified-part-3-observer-pattern-aka-dont-call-me-ill-call-you--38m3"&gt;&lt;strong&gt;Observer&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0e78vwjn6o5j10wiz3yb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0e78vwjn6o5j10wiz3yb.png" alt="Observer Pattern: Analogy - The Youtube Subscriber" width="800" height="801"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Subject
Class Channel
    subs = []
    AddSub(s) → subs.Add(s)
    Upload(video)
        For s in subs → s.Notify(video)

// Observer
Class User
    Notify(v) → print "New video: " + v

// Caller
ch = new Channel()
usr = new User()
ch.AddSub(usr)
ch.Upload("Design Patterns")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;15.&lt;/strong&gt;&lt;a href="https://dev.to/prateekprabhakar/design-patterns-simplified-part-9-command-pattern-aka-your-codes-remote-control-23gb"&gt;&lt;strong&gt;Command&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffv23p7dgaeuk5gan5jdp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffv23p7dgaeuk5gan5jdp.png" alt="Command Pattern: Analogy - The Remote Control" width="800" height="801"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Command
Interface Command
    Execute()

Class LightOn implements Command
    Execute() → print "Light ON"

// Invoker
Class Remote
    Set(cmd) → this.cmd = cmd
    Press() → cmd.Execute()

// Caller
remote = new Remote()
remote.Set(new LightOn())
remote.Press()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;16.&lt;/strong&gt;&lt;a href="https://dev.to/prateekprabhakar/design-patterns-simplified-part-10-chain-of-responsibility-pattern-aka-pass-it-along-until-5o8"&gt;&lt;strong&gt;Chain of Responsibility&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F712e0r64qdvpsnci1eeb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F712e0r64qdvpsnci1eeb.png" alt="Chain of Responsibility Pattern: Analogy - The Customer Support Escalation" width="800" height="725"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Handler
Abstract Class Handler
    next
    SetNext(h) → next = h
    Handle(req)
        If next != null → next.Handle(req)

// Concrete
Class Manager extends Handler
    Handle(req)
        If req &amp;lt; 1000 → print "Manager handled"
        Else super.Handle(req)

// Caller
mgr = new Manager()
dir = new Director()
mgr.SetNext(dir)
mgr.Handle(2000)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;17.&lt;/strong&gt;&lt;a href="https://dev.to/prateekprabhakar/design-patterns-simplified-part-14-state-pattern-aka-the-mood-manager-390l"&gt;&lt;strong&gt;State&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq1lx44218nnzefyk48d2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq1lx44218nnzefyk48d2.png" alt="State Pattern: Analogy - The Mood Manager" width="800" height="795"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// State
Interface State
    Play()

Class HappyState implements State
    Play() → print "Party music"

Class SadState implements State
    Play() → print "Sad songs"

// Context
Class MusicPlayer
    state
    SetState(s) → state = s
    Play() → state.Play()

// Caller
mp = new MusicPlayer()
mp.SetState(new HappyState())
mp.Play()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;18.&lt;/strong&gt;&lt;a href="https://dev.to/prateekprabhakar/design-patterns-simplified-part-11-mediator-pattern-aka-talk-to-the-middleman-455p"&gt;&lt;strong&gt;Mediator&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnh7h3csgslpx5ztooc5r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnh7h3csgslpx5ztooc5r.png" alt="Mediator Pattern: Analogy - The Air Traffic Controller" width="800" height="801"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Mediator
Class ChatRoom
    Send(msg, user) → print user + ": " + msg

// Colleague
Class User
    name, room
    Send(msg) → room.Send(msg, name)

// Caller
room = new ChatRoom()
u1 = new User("Alice", room)
u1.Send("Hello!")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;19.&lt;/strong&gt;&lt;a href="https://dev.to/prateekprabhakar/design-patterns-simplified-part-12-memento-pattern-aka-your-objects-time-machine-3d6g"&gt;&lt;strong&gt;Momento&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo9jyei3r86u3pm37lfu7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo9jyei3r86u3pm37lfu7.png" alt="Momento Pattern: Analogy - The Game Save" width="800" height="794"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Memento
Class Snapshot
    state
    Constructor(s) → state = s

// Originator
Class Editor
    text
    Save() → new Snapshot(text)
    Restore(snap) → text = snap.state

// Caller
e = new Editor()
e.text = "v1"
snap = e.Save()
e.text = "v2"
e.Restore(snap)  // back to v1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;20.&lt;/strong&gt;&lt;a href="https://dev.to/prateekprabhakar/design-patterns-simplified-part-13-template-method-pattern-aka-the-recipe-pattern-55bj"&gt;&lt;strong&gt;Template Method&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F494ddxm9vf1maf60vluw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F494ddxm9vf1maf60vluw.png" alt="Template Method Pattern: Analogy - The Cooking Recipe" width="800" height="798"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Abstract
Class Game
    Play()
        Init()
        Start()
        End()

// Concrete
Class Football extends Game
    Init() → print "Setup field"
    Start() → print "Kickoff"
    End()   → print "Game over"

// Caller
g = new Football()
g.Play()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;21.&lt;/strong&gt;&lt;a href="https://dev.to/prateekprabhakar/design-patterns-simplified-part-15-visitor-pattern-aka-the-vip-guest-2g8m"&gt;&lt;strong&gt;Visitor&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9eh286o0gw5rywfxn0lf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9eh286o0gw5rywfxn0lf.png" alt="Visitor Pattern: Analogy - The Tax Auditor" width="800" height="783"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Visitor
Interface Visitor
    Visit(Book)

// Element
Class Book
    Accept(v) → v.Visit(this)

// Concrete visitor
Class TaxVisitor implements Visitor
    Visit(b) → print "Taxing book"

// Caller
book = new Book()
visitor = new TaxVisitor()
book.Accept(visitor)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;22.&lt;/strong&gt;&lt;a href="https://dev.to/prateekprabhakar/design-patterns-simplified-part-20-iterator-pattern-aka-the-product-browser-38bd"&gt;&lt;strong&gt;Iterator&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff4xrlffqnfdtwhggtg83.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff4xrlffqnfdtwhggtg83.png" alt="Iterator Pattern: Analogy - The Product Browser" width="800" height="797"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Iterator
Interface Iterator
    HasNext()
    Next()

Class ProductIterator implements Iterator
    list, index=0
    HasNext() → index &amp;lt; list.Length
    Next() → list[index++]

// Caller
it = new ProductIterator(products)
while it.HasNext()
    print it.Next()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;23.&lt;/strong&gt;&lt;a href="https://dev.to/prateekprabhakar/design-patterns-simplified-part-22-interpreter-pattern-aka-the-rule-engine-45bc"&gt;&lt;strong&gt;Interpreter&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvmvzzfwv13bv2m7wowo5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvmvzzfwv13bv2m7wowo5.png" alt="Interpreter Pattern: Analogy - The Rule Engine" width="800" height="801"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Interface Expression
    Method Interpret(product): bool

Class CategoryExpression implements Expression
    Constructor(category)
    Method Interpret(product) -&amp;gt; product.Category == category

Class PriceExpression implements Expression
    Constructor(limit)
    Method Interpret(product) -&amp;gt; product.Price &amp;lt; limit

Class AndExpression implements Expression
    Constructor(left, right)
    Method Interpret(product) -&amp;gt; left.Interpret(product) 
                                      AND right.Interpret(product)

// Usage
rule = new AndExpression(
          new CategoryExpression("Electronics"),
          new PriceExpression(1000))

For each product in products
    If rule.Interpret(product)
        Print "Selected: " + product.Name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Design patterns aren't about throwing jargon in interviews. They are about writing &lt;strong&gt;clean, extensible, and maintainable code&lt;/strong&gt;.&lt;br&gt;
This cheat sheet is meant to be your &lt;strong&gt;last minute revision buddy&lt;/strong&gt;, something you can glance at before an interview and instantly recall the essence of each pattern.&lt;br&gt;
Remember,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There is no need to memorize patterns, instead it is important to &lt;strong&gt;understand the problem each one solves&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Use the &lt;strong&gt;hooks and analogies&lt;/strong&gt; here to explain patterns in a simple, story like way during interviews.&lt;/li&gt;
&lt;li&gt;When coding, reach for patterns not because they are "fancy," but because they make your design &lt;strong&gt;clearer and future proof&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With this in your toolkit, I am sure you will walk into interviews not just knowing the names of the patterns, but with the confidence to explain and apply them in real world scenarios.&lt;/p&gt;

&lt;p&gt;Happy coding, and may your designs always stay simple and scalable!&lt;/p&gt;

</description>
      <category>designpatterns</category>
      <category>techinterview</category>
      <category>softwareengineering</category>
      <category>cleancode</category>
    </item>
    <item>
      <title>Design Patterns Simplified: Part 22 — Interpreter Pattern (a.k.a. “The Rule Engine”)</title>
      <dc:creator>Prateek Prabhakar</dc:creator>
      <pubDate>Wed, 27 Aug 2025 10:43:25 +0000</pubDate>
      <link>https://dev.to/prateekprabhakar/design-patterns-simplified-part-22-interpreter-pattern-aka-the-rule-engine-45bc</link>
      <guid>https://dev.to/prateekprabhakar/design-patterns-simplified-part-22-interpreter-pattern-aka-the-rule-engine-45bc</guid>
      <description>&lt;p&gt;The &lt;strong&gt;Interpreter Pattern&lt;/strong&gt; belongs to the &lt;strong&gt;Behavioral&lt;/strong&gt; category of design patterns.&lt;br&gt;
Why? Because it is all about &lt;em&gt;defining a simple grammar and then interpreting statements written in that grammar&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Bigger question is why do we even need it? &lt;br&gt;
The Interpreter Pattern is used when your system needs to read, understand, and act on sentences written in a mini language (domain-specific language). Instead of hardcoding all possible variations, you define a grammar (rules) and let the system evaluate them dynamically.&lt;/p&gt;

&lt;p&gt;Think about traffic signs. A red circle with a line means No Entry, a green light means Go. You do not memorize every road individually, instead, just interpret symbols using predefined rules.&lt;/p&gt;

&lt;p&gt;It applies effectively to below scenarios too.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Search filters → "category = 'Electronics' AND price &amp;lt; 1000"&lt;/li&gt;
&lt;li&gt;Validation rules → "Age &amp;gt; 18 AND Country = 'India'"&lt;/li&gt;
&lt;li&gt;Math expressions → "5 + 10 - 2"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each of these is a sentence in some domain specific language. &lt;br&gt;
The Interpreter Pattern lets you define the grammar (rules + symbols) and then evaluate/interpret sentences accordingly.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Language Teacher
&lt;/h3&gt;

&lt;p&gt;Suppose you are learning Spanish. Instead of memorizing every possible sentence, your teacher gives you rules,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“hola” → “hello”&lt;br&gt;
“gracias” → “thank you”&lt;br&gt;
Grammar: Sentence = Word1 + Word2 + ...&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, when you see &lt;em&gt;“hola amigo”&lt;/em&gt;, you don’t need a separate hardcoded translation. You apply rules recursively to interpret the whole sentence.&lt;/p&gt;

&lt;p&gt;That is the Interpreter Pattern in action - Rules + Recursive interpretation.&lt;/p&gt;




&lt;h3&gt;
  
  
  Search Filters in E-commerce
&lt;/h3&gt;

&lt;p&gt;Let's say you are building a product search system for an e-commerce application. Users can define filters like,&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Category&lt;/strong&gt; = "Electronics" &lt;br&gt;
&lt;strong&gt;&lt;em&gt;AND&lt;/em&gt;&lt;/strong&gt; &lt;br&gt;
&lt;strong&gt;Price&lt;/strong&gt; &amp;lt; 1000&lt;/p&gt;

&lt;p&gt;You want your system to interpret this rule and filter products accordingly.&lt;/p&gt;

&lt;h4&gt;
  
  
  What Does the Code Look Like?
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Step 1: Common Expression interface
Interface Expression
    Method Interpret(product) : bool

// Step 2: Terminal Expressions (basic rules)
Class CategoryExpression implements Expression
    Property category

    Constructor(category)
        this.category = category

    Method Interpret(product)
        return product.Category == category

Class PriceExpression implements Expression
    Property priceLimit

    Constructor(priceLimit)
        this.priceLimit = priceLimit

    Method Interpret(product)
        return product.Price &amp;lt; priceLimit

// Step 3: Non-Terminal Expressions (combinators)
Class AndExpression implements Expression
    Property left : Expression
    Property right : Expression

    Constructor(left, right)
        this.left = left
        this.right = right

    Method Interpret(product)
        return left.Interpret(product) AND right.Interpret(product)

Class OrExpression implements Expression
    Property left : Expression
    Property right : Expression

    Constructor(left, right)
        this.left = left
        this.right = right

    Method Interpret(product)
        return left.Interpret(product) OR right.Interpret(product)

// caller logic
products = [
    {Name:"iPhone", Category:"Electronics", Price:900},
    {Name:"Shoes", Category:"Fashion", Price:120},
    {Name:"Laptop", Category:"Electronics", Price:1500}
]

// Rule: Category = "Electronics" AND Price &amp;lt; 1000
rule = new AndExpression(
            new CategoryExpression("Electronics"),
            new PriceExpression(1000))

// Evaluate rule against all products
For each product in products
    If rule.Interpret(product)
        Print "Selected: " + product.Name

// output:
Selected: iPhone

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we defined a common &lt;code&gt;Expression&lt;/code&gt; interface.&lt;br&gt;
&lt;code&gt;CategoryExpression&lt;/code&gt; and &lt;code&gt;PriceExpression&lt;/code&gt; are &lt;em&gt;terminal&lt;/em&gt; expressions → basic rules.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;AndExpression&lt;/code&gt; and &lt;code&gt;OrExpression&lt;/code&gt; are &lt;em&gt;non-terminal&lt;/em&gt; expressions → combine rules.&lt;/p&gt;

&lt;p&gt;The client builds a rule tree (Electronics AND Price &amp;lt; 1000), and the system evaluates each product using &lt;code&gt;Interpret()&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  What Did We Achieve?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Abstraction of rules : Client does not hardcode logic for category/price.&lt;/li&gt;
&lt;li&gt;Extensibility : You can add new filters (BrandExpression, RatingExpression) easily.&lt;/li&gt;
&lt;li&gt;Reusability : Complex rules can be built from smaller ones.&lt;/li&gt;
&lt;li&gt;Flexibility : Rules are simply objects, which can be stored, combined, reused.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  When Should You Use the Interpreter Pattern?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;When you have to process and evaluate expressions (math, rules, filters).&lt;/li&gt;
&lt;li&gt;When the grammar is simple and stable.&lt;/li&gt;
&lt;li&gt;When you want to allow dynamic rules instead of hardcoding logic.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Use Cases?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;E-commerce search filters&lt;/li&gt;
&lt;li&gt;Rule-based engines (validation, business policies)&lt;/li&gt;
&lt;li&gt;Query interpreters (SQL-like structures in domain specific language)&lt;/li&gt;
&lt;li&gt;Formula calculation engines&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Interpreter pattern is not about machine translation like English → French. It is about defining a grammar and providing a way to interpret statements written in that grammar.&lt;/li&gt;
&lt;li&gt;If the grammar is very complex, Interpreter can lead to large class hierarchies. In such cases, parser generators or compilers are a better fit.&lt;/li&gt;
&lt;li&gt;People confuse it with these patterns,
&lt;strong&gt;&lt;a href="https://dev.to/prateekprabhakar/design-patterns-simplified-part-2-strategy-pattern-aka-pick-your-coupon-wisely-2ane"&gt;Strategy Pattern&lt;/a&gt;&lt;/strong&gt; (choosing one algorithm at runtime) - but Interpreter is about grammar + evaluating sentences, not choosing algorithms.
&lt;strong&gt;&lt;a href="https://dev.to/prateekprabhakar/design-patterns-simplified-part-21-facade-pattern-aka-the-one-stop-counter-49e5"&gt;Facade Pattern&lt;/a&gt;&lt;/strong&gt; (simplifying subsystems) - Interpreter is not about simplification, it is about parsing + evaluating rules.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;




&lt;p&gt;To summarize, it would be apt to say,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Interpreter Pattern is like having a language teacher for your code. Instead of hardcoding every possible sentence, you define rules (grammar), and the system interprets them recursively.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It shines when you want flexible, extensible, rule-based evaluation.&lt;/p&gt;

&lt;p&gt;Hope now you have a good understanding of the Interpreter pattern and its applications.&lt;/p&gt;

&lt;p&gt;This marks the end of our series - Design Patterns Simplified.&lt;/p&gt;

&lt;p&gt;Next up: &lt;strong&gt;Design Patterns Simplified - Cheat Sheet&lt;/strong&gt;. The only design pattern sheet you need to look at before your next tech interview.&lt;/p&gt;

</description>
      <category>designpatterns</category>
      <category>softwareengineering</category>
      <category>techinterview</category>
      <category>cleancode</category>
    </item>
    <item>
      <title>Design Patterns Simplified: Part 21 — Facade Pattern (a.k.a. “The One-Stop Counter”)</title>
      <dc:creator>Prateek Prabhakar</dc:creator>
      <pubDate>Mon, 25 Aug 2025 04:44:12 +0000</pubDate>
      <link>https://dev.to/prateekprabhakar/design-patterns-simplified-part-21-facade-pattern-aka-the-one-stop-counter-49e5</link>
      <guid>https://dev.to/prateekprabhakar/design-patterns-simplified-part-21-facade-pattern-aka-the-one-stop-counter-49e5</guid>
      <description>&lt;p&gt;The &lt;strong&gt;Facade Pattern&lt;/strong&gt; belongs to the &lt;strong&gt;Structural&lt;/strong&gt; category of design patterns.&lt;br&gt;
Why? Because it &lt;em&gt;hides complex subsystems behind a simple interface&lt;/em&gt;, making the client’s life easier.&lt;/p&gt;

&lt;p&gt;Say you are travelling to your favorite holiday destination. You enter the airport an walk to the check-in counter. You would not directly deal with baggage handling, seat assignment, boarding pass generation etc. Instead, you walk up to one counter, hand over your passport, and the staff takes care of all the background steps by coordinating with multiple systems.&lt;/p&gt;

&lt;p&gt;That is the Facade Pattern in action. You can think of it as a single, simplified entry point to a complex set of operations.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Smart Home
&lt;/h3&gt;

&lt;p&gt;Imagine you have a smart home with many subsystems like Lights, Air Conditioner, Security Camera, Music System.&lt;/p&gt;

&lt;p&gt;Say its Friday and you decide to have a movie night. You would want to have the stage set for it to have a wonderful experience.&lt;/p&gt;

&lt;p&gt;Without Facade you would have to, talk to each subsystem directly - lights, AC, TV, speakers. The client code becomes a to-do list of commands and is tightly coupled to the subsystem details. Any small change (say, new speakers) forces changes everywhere.&lt;/p&gt;

&lt;p&gt;With Facade, you just call one method - "StartMovieNight", and its all set.&lt;/p&gt;

&lt;h4&gt;
  
  
  What Does the Code Look Like?
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Step 1: Subsystems
Class Lights
    Method TurnOn()
    Method Dim()

Class AirConditioner
    Method TurnOn()
    Method SetTemperature(temp)

Class TV
    Method TurnOn()
    Method SetInput(input)

Class Speakers
    Method TurnOn()
    Method SetMode(mode)

// Step 2: Facade
Class HomeTheaterFacade
    Property lights
    Property ac
    Property tv
    Property speakers

    Constructor(lights, ac, tv, speakers)
        this.lights = lights
        this.ac = ac
        this.tv = tv
        this.speakers = speakers

    Method StartMovieNight()
        lights.Dim()
        ac.TurnOn()
        ac.SetTemperature(22)
        tv.TurnOn()
        tv.SetInput("HDMI")
        speakers.TurnOn()
        speakers.SetMode("Theater")

// caller logic
lights = new Lights()
ac = new AirConditioner()
tv = new TV()
speakers = new Speakers()

homeTheater = new HomeTheaterFacade(lights, ac, tv, speakers)
homeTheater.StartMovieNight()

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We define individual subsystem classes (Lights, AC, TV, Speakers), with each having its own detailed operations.&lt;br&gt;
Instead of the client calling these classes directly, we introduce HomeTheaterFacade.&lt;/p&gt;

&lt;p&gt;The facade exposes a single method &lt;code&gt;StartMovieNight()&lt;/code&gt;, which internally coordinates all the subsystem calls in the right sequence.&lt;/p&gt;

&lt;p&gt;This makes the client’s job super easy. Its just one call that does it all for you.&lt;/p&gt;

&lt;h4&gt;
  
  
  What Did We Achieve?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Simplicity: Clients deal with one simple interface instead of multiple complex subsystems.&lt;/li&gt;
&lt;li&gt;Loose Coupling: Clients aren not tied to subsystem details. If internals change, the facade shields them.&lt;/li&gt;
&lt;li&gt;Reusability: Common workflows that have complex subsystems synchronized can be packaged into facade methods.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  When Should You Use the Facade Pattern?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;When your system has multiple subsystems that are complex or frequently change.&lt;/li&gt;
&lt;li&gt;When you want to provide a simplified entry point for common tasks.&lt;/li&gt;
&lt;li&gt;When you want to reduce dependencies between client code and low level operations.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Use Cases?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Holiday booking websites : one interface coordinates flights, hotels, cars, activities&lt;/li&gt;
&lt;li&gt;Payment gateways : single call hides multiple banking/payment subsystems&lt;/li&gt;
&lt;li&gt;Libraries/Frameworks : where a facade API wraps complex underlying logic&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;To summarize, it would be apt to say,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Facade Pattern is like your airport check-in counter, one simple stop that takes care of a whole set of complex behind the scenes processes. Hiding the complexities and getting the work done with just a single entry point.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hope this gave a good idea on the Facade Pattern. &lt;/p&gt;

&lt;p&gt;Next up: &lt;strong&gt;Interpreter Pattern&lt;/strong&gt;. Stay tuned!&lt;/p&gt;




&lt;h3&gt;
  
  
  BONUS: Relation to Adapter &amp;amp; Mediator
&lt;/h3&gt;

&lt;p&gt;Facade is often confused with two patterns - &lt;a href="https://dev.to/prateekprabhakar/design-patterns-simplified-part-5-adapter-pattern-aka-lets-make-it-compatible-4jf0"&gt;Adapter&lt;/a&gt; &amp;amp; &lt;a href="https://dev.to/prateekprabhakar/design-patterns-simplified-part-11-mediator-pattern-aka-talk-to-the-middleman-455p"&gt;Mediator&lt;/a&gt;. Here is a quick comparison between the three.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Adapter&lt;/em&gt;&lt;/strong&gt; : It focuses on compatibility. Makes two incompatible interfaces work together. Example, plugging a US charger into an EU socket.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Facade&lt;/em&gt;&lt;/strong&gt; : It focuses on simplicity. Hides a complex subsystem behind a clean, unified interface.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Mediator&lt;/em&gt;&lt;/strong&gt; : It focuses on communication. Defines how objects interact with each other without them referring to each other directly.&lt;/p&gt;

</description>
      <category>designpatterns</category>
      <category>softwareengineering</category>
      <category>cleancode</category>
      <category>techinterview</category>
    </item>
    <item>
      <title>Design Patterns Simplified: Part 20 — Iterator Pattern (a.k.a. “The Product Browser”)</title>
      <dc:creator>Prateek Prabhakar</dc:creator>
      <pubDate>Fri, 22 Aug 2025 11:50:19 +0000</pubDate>
      <link>https://dev.to/prateekprabhakar/design-patterns-simplified-part-20-iterator-pattern-aka-the-product-browser-38bd</link>
      <guid>https://dev.to/prateekprabhakar/design-patterns-simplified-part-20-iterator-pattern-aka-the-product-browser-38bd</guid>
      <description>&lt;p&gt;The &lt;strong&gt;Iterator Pattern&lt;/strong&gt; belongs to the &lt;strong&gt;Behavioral&lt;/strong&gt; category of design patterns.&lt;br&gt;
Why? Because it is all about how you &lt;em&gt;access elements in a collection without exposing its internal structure&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Imagine you are at a buffet. Cravings!!!&lt;br&gt;
You don’t really care how dishes are stored in the kitchen or in which order the chef cooked them. You simply move along the buffet line and take one dish after another.&lt;/p&gt;

&lt;p&gt;That’s what the Iterator Pattern does for collections in code. It lets you move through items sequentially without knowing how they are actually stored (array, tree, linked list, etc.).&lt;/p&gt;




&lt;h3&gt;
  
  
  The E-commerce Product Catalog
&lt;/h3&gt;

&lt;p&gt;Suppose you are building a product catalog for an online store. The catalog might store products in different ways, maybe an array, maybe a list fetched from a database, or even a cache.&lt;/p&gt;

&lt;p&gt;The challenge? You want to give customers a consistent browsing experience without caring about the underlying storage.&lt;br&gt;
In comes the iterator pattern to help you out.&lt;/p&gt;

&lt;h4&gt;
  
  
  What Is the Iterator Pattern?
&lt;/h4&gt;

&lt;p&gt;This pattern provides a way to sequentially access elements of a collection without exposing how the collection is implemented.&lt;br&gt;
So, instead of writing different loops for arrays, lists, or DB queries, you just ask the iterator,&lt;/p&gt;

&lt;p&gt;&lt;code&gt;HasNext()&lt;/code&gt; → Is there another product?&lt;br&gt;
&lt;code&gt;Next()&lt;/code&gt; → Show me the next product.&lt;/p&gt;

&lt;h4&gt;
  
  
  What Does the Code Look Like?
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Step 1: Define a Product class
Class Product
    Property name
    Property price

    Constructor(name, price)
        this.name = name
        this.price = price

// Step 2: Define the Iterator interface
Interface Iterator
    Method HasNext() : Boolean
    Method Next() : Product

// Step 3: Concrete Iterator for a List of Products
Class ProductIterator implements Iterator
    Property products
    Property position = 0

    Constructor(products)
        this.products = products

    Method HasNext()
        Return position &amp;lt; products.Count

    Method Next()
        product = products[position]
        position = position + 1
        Return product

// Step 4: Define Collection Interface
Interface ProductCollection
    Method CreateIterator() : Iterator

// Step 5: Concrete Product Catalog
Class OnlineStoreCatalog implements ProductCollection
    Property products = []

    Method AddProduct(product)
        products.Add(product)

    Method CreateIterator()
        Return new ProductIterator(products)

// caller logic
catalog = new OnlineStoreCatalog()
catalog.AddProduct(new Product("Laptop", 800))
catalog.AddProduct(new Product("Headphones", 100))
catalog.AddProduct(new Product("Keyboard", 50))

iterator = catalog.CreateIterator()

While iterator.HasNext()
    product = iterator.Next()
    Print "Browsing product: " + product.name 
       + " ($" + product.price + ")"

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let me explain on what's happening in the code above. We have the below components that work in tandem to help achieve the iterator pattern. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;Product&lt;/code&gt; → It is a simple class holding product details like name and price.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Iterator&lt;/code&gt; interface → A contract that says, “Any iterator must at least know how to check if there is another item (&lt;code&gt;HasNext()&lt;/code&gt;) and how to return the next one (&lt;code&gt;Next()&lt;/code&gt;).”&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ProductIterator&lt;/code&gt; → The actual implementation of an iterator for a product list. It keeps track of your current position and knows how to move forward.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ProductCollection&lt;/code&gt; interface → Another contract that says, “Any product collection should be able to give an iterator.”&lt;/p&gt;

&lt;p&gt;&lt;code&gt;OnlineStoreCatalog&lt;/code&gt; → It is the concrete product collection. It stores products internally, but instead of exposing them directly, it gives you an iterator when asked (&lt;code&gt;CreateIterator()&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;The end user only interacts with the iterator and not the collection itself. They just keep asking, &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Do you have another product?” → “Okay, give it to me.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The key here is that the client does not need to know how products are stored (list, array, DB fetch). They only interact with the iterator, which provides a consistent way to browse.&lt;/p&gt;

&lt;h4&gt;
  
  
  What Did We Achieve?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Abstraction: The client does not need to know how products are stored, they can simply iterate over them.&lt;/li&gt;
&lt;li&gt;Consistency: A uniform way to browse products, regardless of underlying data structure.&lt;/li&gt;
&lt;li&gt;Flexibility: You can change the collection’s implementation (array, DB, API) without touching client code.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  When Should You Use Iterator Pattern?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;When you want a uniform way to traverse different types of collections.&lt;/li&gt;
&lt;li&gt;When you do not want to expose the internal structure of a collection.&lt;/li&gt;
&lt;li&gt;When collections might change, but client code should remain stable.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Use Cases?
&lt;/h4&gt;

&lt;p&gt;As you might have already guessed, the Iterator Pattern shows up all around us.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;E-commerce product catalogs : browse through thousands of products page by page without knowing the storage backend.&lt;/li&gt;
&lt;li&gt;Social media feeds : scroll through posts, reels, or stories in sequence.&lt;/li&gt;
&lt;li&gt;Photo gallery apps : swipe through images one by one, regardless of how they’re stored on disk.&lt;/li&gt;
&lt;li&gt;Music or video playlists : play next, previous, or shuffle without exposing the internal list.&lt;/li&gt;
&lt;li&gt;File browsing : move through folders and files seamlessly.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;To summarize, it would be apt to say,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Iterator Pattern is like giving your customers a “Next Product” button in your store. They don’t care how the products are stored, instead, they just keep browsing smoothly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is one of those patterns that keeps your application user friendly and your code future proof. &lt;/p&gt;

&lt;p&gt;Hope this article helped you understand the Iterator Pattern and where to apply effectively.&lt;/p&gt;

&lt;p&gt;Next up: &lt;strong&gt;Facade Pattern&lt;/strong&gt;. Stay tuned!&lt;/p&gt;




&lt;h3&gt;
  
  
  Bonus: Iterator + Composite Pattern - A Perfect Duo
&lt;/h3&gt;

&lt;p&gt;Remember the &lt;a href="https://dev.to/prateekprabhakar/design-patterns-simplified-part-19-composite-pattern-aka-the-file-tree-organizer-1j1l"&gt;Composite Pattern&lt;/a&gt; we covered earlier (like file/folder structures or org charts)? It helps you organize objects into a hierarchy, where individual items and groups are treated the same.&lt;/p&gt;

&lt;p&gt;Now, here’s where Iterator steps in as the perfect partner: it gives you a clean way to walk through that hierarchy.&lt;/p&gt;

&lt;p&gt;Take a file–folder system as an example,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Composite&lt;/strong&gt; lets you represent folders that can contain files or even other folders.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Iterator&lt;/strong&gt; then allows you to seamlessly move through these items, whether you are looping through files in one folder or traversing the entire tree.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short, &lt;strong&gt;&lt;em&gt;Composite organizes, Iterator navigates&lt;/em&gt;&lt;/strong&gt;. &lt;br&gt;
Together, they make working with hierarchical data both neat and effortless.&lt;/p&gt;

</description>
      <category>designpatterns</category>
      <category>softwareengineering</category>
      <category>techinterview</category>
      <category>cleancode</category>
    </item>
    <item>
      <title>Design Patterns Simplified: Part 19 — Composite Pattern (a.k.a. “The File Tree Organizer”)</title>
      <dc:creator>Prateek Prabhakar</dc:creator>
      <pubDate>Wed, 20 Aug 2025 16:57:20 +0000</pubDate>
      <link>https://dev.to/prateekprabhakar/design-patterns-simplified-part-19-composite-pattern-aka-the-file-tree-organizer-1j1l</link>
      <guid>https://dev.to/prateekprabhakar/design-patterns-simplified-part-19-composite-pattern-aka-the-file-tree-organizer-1j1l</guid>
      <description>&lt;p&gt;The &lt;strong&gt;Composite Pattern&lt;/strong&gt; belongs to the &lt;strong&gt;Structural&lt;/strong&gt; category of design patterns.&lt;br&gt;
Why? Because it allows you to &lt;em&gt;treat individual objects and groups of objects uniformly, by organizing them into a tree like hierarchy&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Think about a Company Org Chart.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An Employee can be a individual contributor.&lt;/li&gt;
&lt;li&gt;A Manager is also an employee, but they can have multiple employees reporting to them.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, when their details are needed in order to distribute festive coupons, you don’t want different logic for developers and managers. You would just want to call the same method, and the right thing should happen.&lt;/p&gt;

&lt;p&gt;This is exactly what the Composite Pattern does in code. It lets you work with single objects (referred as leaves) and collections of objects (referred as composites) through a common interface.&lt;/p&gt;




&lt;h3&gt;
  
  
  The File System
&lt;/h3&gt;

&lt;p&gt;Suppose you are building a file explorer application. You want it to be able to display both Files and Folders.&lt;br&gt;
But a Folder can contain Files as well as other Folders, and you don’t want to write separate logic for each.&lt;/p&gt;

&lt;p&gt;So, the challenge here is - &lt;em&gt;How do you treat individual items and groups of items in the same way?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Enter the Composite Pattern. It lets you represent part-whole hierarchies (like trees) where individual objects and groups are treated uniformly.&lt;/p&gt;

&lt;h4&gt;
  
  
  What does the code look like?
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Step 1: Define a common interface
Interface FileSystemItem
    Method Display(indentLevel)

// Step 2: Leaf class (File)
Class File implements FileSystemItem
    Property name

    Constructor(name)
        this.name = name

    Method Display(indentLevel)
        Print indentLevel * "-" + " File: " + name

// Step 3: Composite class (Folder)
Class Folder implements FileSystemItem
    Property name
    Property items = List of FileSystemItem

    Constructor(name)
        this.name = name

    Method Add(item)
        items.Add(item)

    Method Display(indentLevel)
        Print indentLevel * "-" + " Folder: " + name
        For each item in items
            item.Display(indentLevel + 1)

// caller logic
root = new Folder("Root")
root.Add(new File("Resume.docx"))
root.Add(new File("Budget.xlsx"))

projects = new Folder("Projects")
projects.Add(new File("AppDesign.pdf"))
projects.Add(new File("Prototype.png"))

root.Add(projects)

root.Display(0)

//output
Folder: Root
- File: Resume.docx
- File: Budget.xlsx
- Folder: Projects
-- File: AppDesign.pdf
-- File: Prototype.png

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above code, we define a common interface &lt;code&gt;FileSystemItem&lt;/code&gt; and both &lt;code&gt;File&lt;/code&gt; and &lt;code&gt;Folder&lt;/code&gt; implement the same interface. This ensures we can call &lt;code&gt;Display()&lt;/code&gt; on either of them without worrying about whether it is a file or a folder.&lt;/p&gt;

&lt;p&gt;We have a &lt;code&gt;Leaf (File)&lt;/code&gt; which represents a single object (like Resume.docx). The &lt;code&gt;Display()&lt;/code&gt; method just prints its own name with indentation.&lt;/p&gt;

&lt;p&gt;There is another class &lt;code&gt;Composite (Folder)&lt;/code&gt; that holds a collection of &lt;code&gt;FileSystemItem&lt;/code&gt;(both files and folders). Its &lt;code&gt;Display()&lt;/code&gt; method first prints the folder name, then recursively calls &lt;code&gt;Display()&lt;/code&gt; on each child item.&lt;/p&gt;

&lt;p&gt;This recursive call builds the tree-like structure.&lt;/p&gt;

&lt;p&gt;In short, the Composite Pattern hides the complexity of &lt;em&gt;“is this a single item or a group?”&lt;/em&gt;. You just treat everything as a &lt;code&gt;FileSystemItem&lt;/code&gt;. The recursion inside Folder handles the hierarchy behind the scenes.&lt;/p&gt;

&lt;h4&gt;
  
  
  What Did We Achieve?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Unified treatment: Files and Folders can be handled with the same operations.&lt;/li&gt;
&lt;li&gt;Scalability: You can add new types (like shortcuts, archives) easily without breaking existing code.&lt;/li&gt;
&lt;li&gt;Tree structures: Perfect for hierarchical data like file systems, menus, or org charts.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  When Should You Use the Composite Pattern?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;When your objects naturally form a tree structure (like files, menus, or employees).&lt;/li&gt;
&lt;li&gt;When you want to treat individual and composite objects uniformly.&lt;/li&gt;
&lt;li&gt;When you want to simplify client code by avoiding if-else checks for single vs group.&lt;/li&gt;
&lt;li&gt;When new leaf or composite types should be easy to add without changing client logic.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Use Cases?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;File Systems (Files and Folders)&lt;/li&gt;
&lt;li&gt;UI Components (Buttons, Panels, Windows)&lt;/li&gt;
&lt;li&gt;Organization Structures (Employee vs Manager hierarchy)&lt;/li&gt;
&lt;li&gt;Menu Systems (Single menu item vs Submenu)&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;To summarize, it would be apt to say,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Composite Pattern is like your File Tree. You don’t care whether you are dealing with a single File or a whole Folder. Both are items, and you can work with them in the same way.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This keeps your code simple, extensible, and a lot cleaner whenever hierarchical structures come into play.&lt;/p&gt;

&lt;p&gt;Composite works hand in hand with the &lt;strong&gt;&lt;a href="https://dev.to/prateekprabhakar/design-patterns-simplified-part-20-iterator-pattern-aka-the-product-browser-38bd"&gt;Iterator Pattern&lt;/a&gt;&lt;/strong&gt;. We will be diving into it next!&lt;/p&gt;

</description>
      <category>designpatterns</category>
      <category>softwareengineering</category>
      <category>cleancode</category>
      <category>techinterview</category>
    </item>
    <item>
      <title>Design Patterns Simplified: Part 18 — Bridge Pattern (a.k.a. “The Music Connector”)</title>
      <dc:creator>Prateek Prabhakar</dc:creator>
      <pubDate>Mon, 18 Aug 2025 14:15:35 +0000</pubDate>
      <link>https://dev.to/prateekprabhakar/design-patterns-simplified-part-18-bridge-pattern-aka-the-music-connector-1feb</link>
      <guid>https://dev.to/prateekprabhakar/design-patterns-simplified-part-18-bridge-pattern-aka-the-music-connector-1feb</guid>
      <description>&lt;p&gt;The &lt;strong&gt;Bridge Pattern&lt;/strong&gt; belongs to the &lt;strong&gt;Structural&lt;/strong&gt; category of design patterns. &lt;br&gt;
Why? Because it helps us &lt;em&gt;split two related objects so they can grow independently&lt;/em&gt;, without stepping on each other’s toes.&lt;/p&gt;

&lt;p&gt;Think of it like using a Universal Remote. With this you can control different brands of TVs, sound systems, or streaming boxes, without buying a separate remote for each.&lt;br&gt;
That is because the remote and the device work &lt;strong&gt;independently but together&lt;/strong&gt; through a common connection.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Music Connector
&lt;/h3&gt;

&lt;p&gt;Say you have just bought a brand new smart speaker. Party time indeed !!&lt;br&gt;
It looks sleek, sounds amazing, and you can’t wait to blast your favorite playlist.&lt;/p&gt;

&lt;p&gt;But here’s the catch,&lt;br&gt;
You are a Spotify person, your partner loves Apple Music, and your friend is always on YouTube Music.&lt;/p&gt;

&lt;p&gt;Now imagine if the manufacturer had to build a different speaker for every streaming service, like,&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Smart Speaker + Spotify&lt;/li&gt;
&lt;li&gt;Smart Speaker + Apple Music&lt;/li&gt;
&lt;li&gt;Smart Speaker + YouTube Music&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;… and the same for phones, car stereos, and every other music device.&lt;/p&gt;

&lt;p&gt;That would be absolute madness. We would end up having a storage room full of almost identical devices, each tied to just one service.&lt;/p&gt;

&lt;p&gt;Thankfully, that is not how it works in real life.&lt;br&gt;
Instead, your device (phone, speaker, car stereo) and your music service (Spotify, Apple Music, YouTube Music) are independent, yet they work together seamlessly. You can mix and match however you like.&lt;/p&gt;

&lt;p&gt;That is the Bridge Pattern in action.&lt;br&gt;
It is the “connector” that lets two separate worlds (in our example - devices and services) interact without being locked into each other.&lt;/p&gt;

&lt;h4&gt;
  
  
  What is the Bridge Pattern?
&lt;/h4&gt;

&lt;p&gt;The Bridge Pattern helps you separate an abstraction from its implementation so that both can evolve independently.&lt;br&gt;
In our music example,&lt;br&gt;
&lt;em&gt;&lt;strong&gt;Abstraction&lt;/strong&gt;&lt;/em&gt; → The device (Phone, Smart Speaker, Car Stereo)&lt;br&gt;
&lt;em&gt;&lt;strong&gt;Implementation&lt;/strong&gt;&lt;/em&gt; → The streaming service (Spotify, Apple Music, YouTube Music)&lt;/p&gt;

&lt;p&gt;Instead of creating every possible combination as a separate class, we “bridge” the two so they can connect dynamically.&lt;/p&gt;

&lt;h4&gt;
  
  
  What does the code look like?
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Step 1: Define the "Implementor" interface (MusicSource)
Interface MusicSource
    Method PlayMusic()

// Step 2: Concrete Implementations of MusicSource
Class Spotify implements MusicSource
    Method PlayMusic()
        Print "Playing music from Spotify..."

Class YouTubeMusic implements MusicSource
    Method PlayMusic()
        Print "Playing music from YouTube Music..."

Class AppleMusic implements MusicSource
    Method PlayMusic()
        Print "Playing music from Apple Music..."


// Step 3: Define the "Abstraction" (Device)
Class MusicDevice
    Property musicSource  // reference to a MusicSource

    Constructor(musicSource)
        this.musicSource = musicSource

    Method Play()
        musicSource.PlayMusic()


// Step 4: Refined Abstractions (Specific Devices)
Class Phone extends MusicDevice
    Constructor(musicSource)
        super(musicSource)

Class CarStereo extends MusicDevice
    Constructor(musicSource)
        super(musicSource)

Class SmartSpeaker extends MusicDevice
    Constructor(musicSource)
        super(musicSource)


//caller logic
spotify = new Spotify()
youtube = new YouTubeMusic()

phone = new Phone(spotify)
phone.Play()      // Output: Playing music from Spotify...

carStereo = new CarStereo(youtube)
carStereo.Play()  // Output: Playing music from YouTube Music...

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi3ep1wpmdhm1dtewmtbz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi3ep1wpmdhm1dtewmtbz.png" alt="Bridge pattern sample code structure" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is how the above code works,&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;You (the caller) decide which Device (e.g., SmartSpeaker, CarStereo) you want and which Music Source (e.g., SpotifyService, YouTubeMusicService) it should play from.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When creating the device, you pass the chosen music source into the device’s constructor. This is the “bridge” that connects the two worlds.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Device (Abstraction): The device defines high level actions like &lt;code&gt;PlayMusic()&lt;/code&gt; or &lt;code&gt;StopMusic()&lt;/code&gt;. It does not know how the music service works, instead, it just calls the music service’s methods.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Music Service (Implementor): Each music service (Spotify, YouTube Music, etc.) implements its own logic for playing/streaming music.&lt;br&gt;
The device simply delegates to this service without caring about its details.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In short,&lt;br&gt;
You call &lt;code&gt;myDevice.Play()&lt;/code&gt; → The device calls &lt;code&gt;musicSource.PlayMusic()&lt;/code&gt; internally → The music service does its work and returns control back to the device.&lt;/p&gt;

&lt;h4&gt;
  
  
  What Did We Achieve?
&lt;/h4&gt;

&lt;p&gt;With this approach, the devices and music services are separate. You can add a new device without touching any music service code, or add a new music service without touching any device code. The constructor injection is the handshake that makes them work together without being tightly coupled.&lt;/p&gt;

&lt;h4&gt;
  
  
  When Should You Use the Bridge Pattern?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;When you have two dimensions of change, for example, different devices and different music sources, and you want them to evolve independently.&lt;/li&gt;
&lt;li&gt;When subclass explosion is a risk. Without Bridge, you would need a class for every combination (e.g. CarStereoWithSpotify, CarStereoWithYouTubeMusic, etc.).&lt;/li&gt;
&lt;li&gt;When you want loose coupling between high level logic (device) and low level details (music service), so changes on one side don’t break the other.&lt;/li&gt;
&lt;li&gt;When future scalability matters. You can add new variations of either side without touching the other side’s code.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Use Cases?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Payment systems (different payment methods + different platforms)&lt;/li&gt;
&lt;li&gt;UI Themes (different themes + different components)&lt;/li&gt;
&lt;li&gt;Messaging apps (different message senders + different protocols)&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;To summarize, it would be apt to say,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Bridge Pattern is like using a universal remote that works with different brands of TVs, separating the remote (abstraction) from the TV (implementation) so both can evolve independently without messing each other up.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hope this made the Bridge Pattern easy to grasp!&lt;/p&gt;

&lt;p&gt;Next up: &lt;strong&gt;&lt;a href="https://dev.to/prateekprabhakar/design-patterns-simplified-part-19-composite-pattern-aka-the-file-tree-organizer-1j1l"&gt;Composite Pattern&lt;/a&gt;&lt;/strong&gt;. See you there!&lt;/p&gt;

</description>
      <category>designpatterns</category>
      <category>softwareengineering</category>
      <category>cleancode</category>
      <category>techinterview</category>
    </item>
    <item>
      <title>Design Patterns Simplified: Part 17 — Flyweight Pattern (a.k.a. “The Shared Furniture”)</title>
      <dc:creator>Prateek Prabhakar</dc:creator>
      <pubDate>Fri, 15 Aug 2025 10:16:42 +0000</pubDate>
      <link>https://dev.to/prateekprabhakar/design-patterns-simplified-part-17-flyweight-pattern-aka-the-shared-furniture-4c3l</link>
      <guid>https://dev.to/prateekprabhakar/design-patterns-simplified-part-17-flyweight-pattern-aka-the-shared-furniture-4c3l</guid>
      <description>&lt;p&gt;The &lt;strong&gt;Flyweight Pattern&lt;/strong&gt; belongs to the &lt;strong&gt;Structural&lt;/strong&gt; category.&lt;br&gt;
Why? Because it &lt;em&gt;helps you save memory by sharing common parts of objects instead of creating duplicates&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Think about a hotel with many rooms. All these rooms need chairs, tables, and lamps. Instead of buying unique furniture for every room, which is costly and takes up variable space in each room, the hotel buys a limited number of identical furniture pieces and reuses them across many rooms.&lt;br&gt;
This sharing saves money and space, while each room still keeps its own layout and style (like where the furniture is placed or extra decorations).&lt;/p&gt;




&lt;h3&gt;
  
  
  The Text Editor
&lt;/h3&gt;

&lt;p&gt;Suppose you are building a Text Editor app that handles large documents.&lt;br&gt;
Each character in the document is an object with properties like font, size, and color.&lt;/p&gt;

&lt;p&gt;If you create a separate object for every character including its style properties, your app will quickly consume a lot of memory.&lt;/p&gt;

&lt;p&gt;So, the challenge here is, How do you reduce memory usage when you have many similar objects (characters with same style) repeated throughout the document?&lt;/p&gt;

&lt;h4&gt;
  
  
  Enter the Flyweight Pattern
&lt;/h4&gt;

&lt;p&gt;The Flyweight Pattern lets you share common parts of objects &lt;em&gt;(called intrinsic state)&lt;/em&gt; and store only unique parts &lt;em&gt;(called extrinsic state)&lt;/em&gt; separately.&lt;br&gt;
This reduces memory usage by reusing shared data instead of duplicating it.&lt;/p&gt;

&lt;h4&gt;
  
  
  What does the code look like?
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Step 1: Define the Character interface
Interface Character
    Method Display(positionX, positionY)

// Step 2: Concrete Character Class (Flyweight)
Class ConcreteCharacter implements Character
    Property symbol        // intrinsic state, shared
    Property font
    Property size
    Property color

    Constructor(symbol, font, size, color)
        Set properties

    Method Display(positionX, positionY)
        Print "Displaying '" + symbol + "' at ("
             + positionX + "," + positionY + ") with font="
             + font + ", size=" + size + ", color=" + color

// Step 3: Flyweight Factory to manage shared objects
Class CharacterFactory
    Property characters = Dictionary of (symbol+font+size+color)
                             -&amp;gt; ConcreteCharacter

    Method GetCharacter(symbol, font, size, color)
        key = symbol + font + size + color
        If characters contains key Then
            Return characters[key]
        Else
            character = new ConcreteCharacter(symbol, font, size, color)
            characters[key] = character
            Return character

//caller logic (text editor)
factory = new CharacterFactory()

// For each character in document
charA1 = factory.GetCharacter('A', 'Arial', 12, 'Black')
// Reuses same object as charA1
charA2 = factory.GetCharacter('A', 'Arial', 12, 'Black')  

charB = factory.GetCharacter('B', 'Arial', 12, 'Black')

charA1.Display(10, 20)
charA2.Display(15, 20)
charB.Display(20, 20)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;CharacterFactory&lt;/code&gt; ensures that characters with the same intrinsic properties (symbol, font, size, color) are shared i.e. only one object is created and reused.&lt;br&gt;
The unique part, like position, is passed as extrinsic state during method calls.&lt;/p&gt;

&lt;h4&gt;
  
  
  What Did We Achieve?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Saved memory by sharing common parts of objects.&lt;/li&gt;
&lt;li&gt;Avoided creating many duplicate objects with the same properties.&lt;/li&gt;
&lt;li&gt;Kept unique parts separate by passing them externally when needed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  When Should You Use the Flyweight Pattern?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;When you have many similar objects that differ only in a few properties.&lt;/li&gt;
&lt;li&gt;When you want to optimize memory usage in your app.&lt;/li&gt;
&lt;li&gt;When object creation is costly or you want to reduce resource consumption.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Use Cases?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Text editors handling lots of characters.&lt;/li&gt;
&lt;li&gt;Graphical apps rendering many shapes with shared properties.&lt;/li&gt;
&lt;li&gt;Game development where many objects share textures or models.&lt;/li&gt;
&lt;li&gt;Caching and object pooling.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Does the Flyweight Pattern look similar to the Prototype pattern?
&lt;/h3&gt;

&lt;p&gt;Yes. It is often confused with the &lt;a href="https://dev.to/prateekprabhakar/design-patterns-simplified-part-8-prototype-pattern-aka-copy-that-2ho3"&gt;Prototype pattern&lt;/a&gt;, but let's understand the difference,&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Flyweight Pattern (Structural):&lt;/strong&gt; It focuses on sharing common parts of objects (called intrinsic state) to save memory when many similar objects exist. Instead of creating many full objects every time needed, it reuses shared data and passes unique information separately. This is great for optimizing resource use when you have lots of similar objects with small differences.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prototype Pattern (Creational):&lt;/strong&gt; It is about creating new objects by cloning an existing object (a prototype). It allows you to quickly generate copies with the same state as the original, which can then be modified independently. This is useful when object creation is costly or complex, and you want to create new objects efficiently by copying.&lt;/p&gt;




&lt;p&gt;To summarize, it would be apt to say,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Flyweight Pattern is like furnishing hotel rooms by sharing furniture i.e. saving memory and resources while still allowing each room to have unique arrangements.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hope this made the Flyweight Pattern easy to understand!&lt;/p&gt;

&lt;p&gt;Next up: &lt;strong&gt;&lt;a href="https://dev.to/prateekprabhakar/design-patterns-simplified-part-18-bridge-pattern-aka-the-music-connector-1feb"&gt;Bridge Pattern&lt;/a&gt;&lt;/strong&gt;. Please come over!&lt;/p&gt;

</description>
      <category>designpatterns</category>
      <category>softwareengineering</category>
      <category>techinterview</category>
      <category>cleancode</category>
    </item>
    <item>
      <title>Design Patterns Simplified: Part 16 — Proxy Pattern (a.k.a. “The Gatekeeper”)</title>
      <dc:creator>Prateek Prabhakar</dc:creator>
      <pubDate>Wed, 13 Aug 2025 14:26:58 +0000</pubDate>
      <link>https://dev.to/prateekprabhakar/design-patterns-simplified-part-16-proxy-pattern-aka-the-gatekeeper-1f4j</link>
      <guid>https://dev.to/prateekprabhakar/design-patterns-simplified-part-16-proxy-pattern-aka-the-gatekeeper-1f4j</guid>
      <description>&lt;p&gt;The &lt;strong&gt;Proxy Pattern&lt;/strong&gt; belongs to the &lt;strong&gt;Structural&lt;/strong&gt; category.&lt;br&gt;
Why? Because it &lt;em&gt;controls access to an object&lt;/em&gt; by providing a placeholder or “proxy” that &lt;em&gt;manages how and when the real object is accessed&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Think of it like, you want to enter a VIP party, but first, you meet the gatekeeper.&lt;br&gt;
The gatekeeper checks your invitation and only lets you in if everything is good. You don’t talk to the party organizer directly. It is the gatekeeper who controls your access.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Image Viewer
&lt;/h3&gt;

&lt;p&gt;Suppose you are building an Image Viewer app that loads high resolution images. Loading these images is slow and uses a lot of memory.&lt;/p&gt;

&lt;p&gt;You don’t want to load every image at once when the gallery opens. Instead, you want to load an image only when the user actually wants to see it.&lt;/p&gt;

&lt;p&gt;So, the challenge here is - How do you delay loading the heavy image without changing how the rest of the app accesses it?&lt;/p&gt;

&lt;h4&gt;
  
  
  Enter the Proxy Pattern
&lt;/h4&gt;

&lt;p&gt;The Proxy Pattern provides a placeholder object (proxy) that looks like the real object and controls access to it. The proxy implements the same interface as the real object, so the app can use it seamlessly.&lt;br&gt;
But the proxy handles the loading or access logic, for example, loading the image only when requested.&lt;/p&gt;

&lt;h4&gt;
  
  
  What does the code look like?
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Step 1: Define the Image interface
Interface Image
    Method Display()

//Step 2: Real Image Class
Class RealImage implements Image
    Property filename

    Constructor(filename)
        this.filename = filename
        LoadFromDisk()

    Method LoadFromDisk()
        Print "Loading " + filename + " from disk..."

    Method Display()
        Print "Displaying " + filename

//Step 3: Proxy Image Class
Class ProxyImage implements Image
    Property realImage
    Property filename

    Constructor(filename)
        this.filename = filename
        this.realImage = null

    Method Display()
        If realImage == null Then
            // Load image only when needed
            realImage = new RealImage(filename)  
        End If
        realImage.Display()

// Caller Logic
images = [new ProxyImage("photo1.jpg"), new ProxyImage("photo2.jpg")]
// Images are NOT loaded yet

images[0].Display()  // Loads and displays photo1.jpg
images[1].Display()  // Loads and displays photo2.jpg
images[0].Display()  // Displays photo1.jpg without loading again

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;ProxyImage&lt;/code&gt; looks just like &lt;code&gt;RealImage&lt;/code&gt; because both implement the same Image interface.&lt;br&gt;
But the proxy controls when the real image is loaded. It loads the image only when &lt;code&gt;Display()&lt;/code&gt; is called for the first time.&lt;br&gt;
This saves memory and improves performance without changing how the rest of the app uses the images.&lt;/p&gt;

&lt;h4&gt;
  
  
  What Did We Achieve?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Controlled access to a heavy object.&lt;/li&gt;
&lt;li&gt;Delayed expensive object creation until needed (lazy loading). Lazy loading is implemented by delaying the creation (and loading) of the RealImage object until the Display() method is actually called.&lt;/li&gt;
&lt;li&gt;Kept client code unchanged by using the same interface for proxy and real object.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  When Should You Use the Proxy Pattern?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;When you want to control access to an object (security, logging).&lt;/li&gt;
&lt;li&gt;When creating the real object is expensive, and you want to delay it until necessary.&lt;/li&gt;
&lt;li&gt;When you want to add extra functionality (like caching or access control) without changing the real object.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Use Cases?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Virtual Proxy: Lazy loading large images, files, or data.&lt;/li&gt;
&lt;li&gt;Remote Proxy: Representing an object in a different address space (e.g. across a network).&lt;/li&gt;
&lt;li&gt;Protection Proxy: Controlling access based on permissions.&lt;/li&gt;
&lt;li&gt;Logging Proxy: Logging access to the real object’s methods.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Is the Proxy Pattern Confused with Any Other Pattern?
&lt;/h3&gt;

&lt;p&gt;Yes. It is often confused with the &lt;strong&gt;&lt;a href="https://dev.to/prateekprabhakar/design-patterns-simplified-part-4-decorator-pattern-aka-wrap-it-before-you-log-it-3lfo"&gt;Decorator Pattern&lt;/a&gt;&lt;/strong&gt;.&lt;br&gt;
Both deal with object structure, but here is the difference,&lt;br&gt;
&lt;strong&gt;Proxy:&lt;/strong&gt; Controls access and can delay or restrict it.&lt;br&gt;
&lt;strong&gt;Decorator:&lt;/strong&gt; Adds new behaviors dynamically without controlling access.&lt;/p&gt;




&lt;p&gt;To summarize, it would be apt to say,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Proxy Pattern is like having a gatekeeper who controls when and how you get access to something valuable, making your system efficient and secure.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hope this helped you understand the Proxy Pattern clearly!&lt;/p&gt;

&lt;p&gt;Next up: &lt;strong&gt;&lt;a href="https://dev.to/prateekprabhakar/design-patterns-simplified-part-17-flyweight-pattern-aka-the-shared-furniture-4c3l"&gt;Flyweight Pattern&lt;/a&gt;&lt;/strong&gt;. Let’s learn about it…&lt;/p&gt;

</description>
      <category>designpatterns</category>
      <category>softwareengineering</category>
      <category>techinterview</category>
      <category>cleancode</category>
    </item>
    <item>
      <title>Design Patterns Simplified: Part 15 — Visitor Pattern (a.k.a. “The VIP Guest”)</title>
      <dc:creator>Prateek Prabhakar</dc:creator>
      <pubDate>Mon, 11 Aug 2025 13:05:45 +0000</pubDate>
      <link>https://dev.to/prateekprabhakar/design-patterns-simplified-part-15-visitor-pattern-aka-the-vip-guest-2g8m</link>
      <guid>https://dev.to/prateekprabhakar/design-patterns-simplified-part-15-visitor-pattern-aka-the-vip-guest-2g8m</guid>
      <description>&lt;p&gt;The &lt;strong&gt;Visitor Pattern&lt;/strong&gt; falls under the &lt;strong&gt;Behavioral&lt;/strong&gt; category.&lt;br&gt;
Why? Because it is all about &lt;em&gt;defining new operations on objects without changing their classes&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Say you have a VIP guest who can visit different rooms in a building. The guest behaves differently in each room, but instead of rewriting each room’s code, you just &lt;em&gt;allow the guest to visit and decide what to do there&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Let's understand this with another example, diving deep this time.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Document Processor
&lt;/h3&gt;

&lt;p&gt;Imagine you are building an application that works with different types of documents - Word, PDF, and Spreadsheet.&lt;br&gt;
You want to run operations like Spell check, Export to HTML, or Count words.&lt;/p&gt;

&lt;h4&gt;
  
  
  The Problem
&lt;/h4&gt;

&lt;p&gt;If you add each new operation directly into the document classes, you will keep changing those classes every time. Overtime your classes would become messy, repetitive, and more importantly it breaks the Open/Closed Principle (classes should be open for extension, but closed for modification).&lt;/p&gt;

&lt;h4&gt;
  
  
  Enter the Visitor Pattern
&lt;/h4&gt;

&lt;p&gt;The Visitor Pattern lets you add new operations without changing your document classes.&lt;/p&gt;

&lt;p&gt;Each document has an &lt;code&gt;Accept(visitor)&lt;/code&gt; method. Its a way of saying &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Come in and do your work"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Each visitor knows exactly how to handle each document type.&lt;/p&gt;

&lt;h4&gt;
  
  
  What does the code look like?
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Step 1: Define the Visitor Interface
Interface DocumentVisitor
    Method VisitWordDocument(wordDoc)
    Method VisitPdfDocument(pdfDoc)
    Method VisitSpreadsheet(sheet)

//Step 2: Define the Document Interface
Interface Document
    Method Accept(visitor)

//Step 3: Concrete Document Classes
Class WordDocument implements Document
    Method Accept(visitor)
        visitor.VisitWordDocument(this)

Class PdfDocument implements Document
    Method Accept(visitor)
        visitor.VisitPdfDocument(this)

Class Spreadsheet implements Document
    Method Accept(visitor)
        visitor.VisitSpreadsheet(this)

//Step 4: Create Concrete Visitors (Operations)
Class SpellCheckVisitor implements DocumentVisitor
    Method VisitWordDocument(wordDoc)
        Print "Spell checking Word document..."

    Method VisitPdfDocument(pdfDoc)
        Print "Spell checking PDF document..."

    Method VisitSpreadsheet(sheet)
        Print "Spell checking Spreadsheet..."

Class ExportToHTMLVisitor implements DocumentVisitor
    Method VisitWordDocument(wordDoc)
        Print "Exporting Word document to HTML..."

    Method VisitPdfDocument(pdfDoc)
        Print "Exporting PDF document to HTML..."

    Method VisitSpreadsheet(sheet)
        Print "Exporting Spreadsheet to HTML..."

//caller logic
documents = [new WordDocument(), new PdfDocument(), new Spreadsheet()]

spellChecker = new SpellCheckVisitor()
exporter = new ExportToHTMLVisitor()

For each doc in documents
    doc.Accept(spellChecker)

For each doc in documents
    doc.Accept(exporter)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In our Document Processor example above, think of each visitor as a specialist.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;SpellCheckVisitor&lt;/code&gt; - knows how to spell check any document.&lt;br&gt;
&lt;code&gt;ExportToHTMLVisitor&lt;/code&gt; - knows how to export any document to HTML.&lt;/p&gt;

&lt;p&gt;When a document receives a visitor, it simply hands itself over, and says, &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Here is my PDF data. You know what to do.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This way, you keep document classes simple. You can add new operations anytime without touching existing document classes. With this, your code stays clean, flexible, and easy to grow.&lt;/p&gt;

&lt;h4&gt;
  
  
  What Did We Achieve?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;No need to modify existing document classes when adding new operations.&lt;/li&gt;
&lt;li&gt;Operations (Visitors) are separated from the document structure.&lt;/li&gt;
&lt;li&gt;Adding a new visitor means adding new features without changing existing code.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  When Should You Use Visitor Pattern?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;When you have a stable set of classes (like document types) but frequently add new operations.&lt;/li&gt;
&lt;li&gt;When you want to separate business logic from the object structure.&lt;/li&gt;
&lt;li&gt;When you need to perform many unrelated operations on objects without mixing those operations into the objects themselves.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Use Cases?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Compilers: Different passes over syntax trees (type checking, optimization, code generation)&lt;/li&gt;
&lt;li&gt;File explorers: Performing operations on different file types&lt;/li&gt;
&lt;li&gt;Graphics editors: Applying different filters or transformations to shapes&lt;/li&gt;
&lt;li&gt;E-commerce: Running promotions or discounts on different product categories&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Is Visitor Confused with Any Other Pattern?
&lt;/h3&gt;

&lt;p&gt;Yes. It is sometimes mistaken for the &lt;strong&gt;&lt;a href="https://dev.to/prateekprabhakar/design-patterns-simplified-part-2-strategy-pattern-aka-pick-your-coupon-wisely-2ane"&gt;Strategy Pattern&lt;/a&gt;&lt;/strong&gt;. Both separate behavior from objects, but here is the difference,&lt;br&gt;
&lt;strong&gt;Strategy&lt;/strong&gt;: Object decides which behavior to use.&lt;br&gt;
&lt;strong&gt;Visitor&lt;/strong&gt;: External entity visits and applies behavior to the object.&lt;/p&gt;




&lt;p&gt;To summarize, it would be apt to say,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Visitor Pattern is like inviting a VIP guest who knows exactly what to do in each room, without asking you to renovate the building every time they visit.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It offers great flexibility for adding new operations while keeping your object structure intact.&lt;/p&gt;

&lt;p&gt;Hope you got a clear understanding of the Visitor Pattern!&lt;/p&gt;

&lt;p&gt;Next up: &lt;strong&gt;&lt;a href="https://dev.to/prateekprabhakar/design-patterns-simplified-part-16-proxy-pattern-aka-the-gatekeeper-1f4j"&gt;Proxy Pattern&lt;/a&gt;&lt;/strong&gt;. Let's meet there!&lt;/p&gt;

</description>
      <category>designpatterns</category>
      <category>softwareengineering</category>
      <category>techinterview</category>
      <category>cleancode</category>
    </item>
    <item>
      <title>Design Patterns Simplified: Part 14 — State Pattern (a.k.a. “The Mood Manager”)</title>
      <dc:creator>Prateek Prabhakar</dc:creator>
      <pubDate>Fri, 08 Aug 2025 17:05:25 +0000</pubDate>
      <link>https://dev.to/prateekprabhakar/design-patterns-simplified-part-14-state-pattern-aka-the-mood-manager-390l</link>
      <guid>https://dev.to/prateekprabhakar/design-patterns-simplified-part-14-state-pattern-aka-the-mood-manager-390l</guid>
      <description>&lt;p&gt;The &lt;strong&gt;State Pattern&lt;/strong&gt; falls under the &lt;strong&gt;Behavioral&lt;/strong&gt; category. Why? Because it deals with how an &lt;em&gt;object behaves depending on its internal state and more importantly, how it can change that behavior dynamically at runtime&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Think of it like, when your object is in a “mood", its reactions depend on what mood it is currently in.&lt;/p&gt;

&lt;p&gt;Let’s understand this with a story.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Media Player
&lt;/h3&gt;

&lt;p&gt;Imagine you are building a media player app with two main controls: a &lt;strong&gt;Play/Pause toggle button&lt;/strong&gt; and a &lt;strong&gt;Stop button&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Sounds simple, right? But here’s the thing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If the player is &lt;strong&gt;Stopped&lt;/strong&gt;, pressing Play starts playback.
&lt;/li&gt;
&lt;li&gt;If it’s &lt;strong&gt;Playing&lt;/strong&gt;, pressing Play pauses the music.
&lt;/li&gt;
&lt;li&gt;If it’s &lt;strong&gt;Paused&lt;/strong&gt;, pressing Play resumes playback.
&lt;/li&gt;
&lt;li&gt;Pressing Stop at any point stops the music and resets the state.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The key insight is this,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The same Play button behaves differently depending on the current state of the player.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Without the State Pattern, you would be writing messy if-else chains to handle all scenarios.&lt;/p&gt;

&lt;p&gt;With the State Pattern, each state (Playing, Paused, Stopped) handles user input its own way.&lt;/p&gt;

&lt;h4&gt;
  
  
  What Is the State Pattern?
&lt;/h4&gt;

&lt;p&gt;The State Pattern allows an object to change its behavior when its internal state changes as if it changed its class.&lt;/p&gt;

&lt;p&gt;Instead of managing the behavior using complex conditionals, the object delegates behavior to state specific classes.&lt;/p&gt;

&lt;h4&gt;
  
  
  What does the code look like?
&lt;/h4&gt;

&lt;p&gt;To implement such behavior in the application, typically we would have the below components,&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;State Interface&lt;/em&gt;&lt;/strong&gt;: declares the actions (Play, Pause, Stop).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Concrete State Classes&lt;/em&gt;&lt;/strong&gt;: implement behavior specific to each state.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Context Class (MediaPlayer)&lt;/em&gt;&lt;/strong&gt;: maintains the current state reference and delegates action calls.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Step 1: Define the State Interface
Interface PlayerState
    Method TogglePlayPause(player)
    Method Stop(player)

//Step 2: Define Concrete States
Class PlayingState implements PlayerState
    Method TogglePlayPause(player)
        Print "Pausing playback..."
        player.SetState(new PausedState())

    Method Stop(player)
        Print "Stopping playback..."
        player.SetState(new StoppedState())

Class PausedState implements PlayerState
    Method TogglePlayPause(player)
        Print "Resuming playback..."
        player.SetState(new PlayingState())

    Method Stop(player)
        Print "Stopping playback from pause..."
        player.SetState(new StoppedState())

Class StoppedState implements PlayerState
    Method TogglePlayPause(player)
        Print "Starting playback..."
        player.SetState(new PlayingState())

    Method Stop(player)
        Print "Already stopped."

//Step 3: Define the MediaPlayer Context
Class MediaPlayer
    Property currentState

    Constructor()
        currentState = new StoppedState()

    Method TogglePlayPause()
        currentState.TogglePlayPause(this)

    Method Stop()
        currentState.Stop(this)

//caller logic
player = new MediaPlayer()

player.TogglePlayPause()  // Starting playback...
player.TogglePlayPause()  // Pausing playback...
player.TogglePlayPause()  // Resuming playback...
player.Stop()             // Stopping playback...
player.Stop()             // Already stopped.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each state class (PlayingState, PausedState, StoppedState) encapsulates the behavior for TogglePlayPause() and Stop() actions relevant to that state. The MediaPlayer object delegates these calls to its current state, allowing dynamic behavior changes without complex conditional logic.&lt;br&gt;
This approach keeps the player’s behavior organized which is easy to extend and intuitive to manage.&lt;/p&gt;

&lt;h4&gt;
  
  
  What Did We Achieve?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;No messy if-else chains: All state-specific behavior is encapsulated cleanly.&lt;/li&gt;
&lt;li&gt;Easily extensible: Adding new states (like Buffering) means adding new classes and no modifications to existing code.&lt;/li&gt;
&lt;li&gt;Cleaner MediaPlayer class: Just delegates actions. It has no complex logic.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  When Should You Use State Pattern?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;When an object’s behavior varies significantly depending on its state.&lt;/li&gt;
&lt;li&gt;When complex conditional logic is hard to maintain and understand.&lt;/li&gt;
&lt;li&gt;When you want to encapsulate each state’s logic for easier testing and modification.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Use Cases?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Media players (play/pause/stop)&lt;/li&gt;
&lt;li&gt;Game characters (idle, running, jumping)&lt;/li&gt;
&lt;li&gt;Vending machines (waiting for coin, dispensing, out of stock)&lt;/li&gt;
&lt;li&gt;Traffic lights (green, yellow, red)&lt;/li&gt;
&lt;li&gt;Network connections (connecting, connected, disconnected)&lt;/li&gt;
&lt;li&gt;Workflow engines (draft, submitted, approved)&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;To summarize, it would be apt to say,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“State Pattern is like giving your object a brain that knows when and how to switch gears.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It gives your objects a “mood” enabling them to behave differently based on their internal condition, without tangled conditional logic. This leads to cleaner, more maintainable code and makes extending behavior easier.&lt;/p&gt;

&lt;p&gt;Next up in the series: &lt;strong&gt;&lt;a href="https://dev.to/prateekprabhakar/design-patterns-simplified-part-15-visitor-pattern-aka-the-vip-guest-2g8m"&gt;Visitor Pattern&lt;/a&gt;&lt;/strong&gt;. Let's understand that now!&lt;/p&gt;




&lt;h3&gt;
  
  
  BONUS: State vs Strategy — A Story to Remember
&lt;/h3&gt;

&lt;p&gt;Imagine you are running a café that serves coffee.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Scenario 1: The Customer’s Mood (State Pattern)&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One customer walks in. Depending on their mood - happy, tired, or grumpy, they order and react differently.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If they are happy, they smile and say, “I’ll have a cappuccino, please.”
&lt;/li&gt;
&lt;li&gt;If they are tired, they say, “Just a strong black coffee, thanks.”
&lt;/li&gt;
&lt;li&gt;If they are grumpy, they might say, “Make it quick, I’m in a hurry.”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The customer’s mood changes over time. After a sip, they might become happier or more relaxed, changing their behavior accordingly.&lt;/p&gt;

&lt;p&gt;This is the &lt;strong&gt;State Pattern&lt;/strong&gt;: the object (customer) changes behavior based on its internal state (mood).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Scenario 2: The Barista’s Tools (Strategy Pattern)&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
Now, the barista needs to prepare coffee. They can use different brewing methods - espresso machine, French press, or drip coffee maker.&lt;br&gt;
The barista chooses the brewing method based on the customer’s preference or cafe’s style.&lt;/p&gt;

&lt;p&gt;Each brewing method is an independent strategy i.e. a different algorithm to make coffee.&lt;br&gt;
Here, the choice of brewing method comes from outside, the barista selects which strategy to use for the task.&lt;/p&gt;

&lt;p&gt;This is the &lt;strong&gt;&lt;a href="https://dev.to/prateekprabhakar/design-patterns-simplified-part-2-strategy-pattern-aka-pick-your-coupon-wisely-2ane"&gt;Strategy Pattern&lt;/a&gt;&lt;/strong&gt;: The context (barista) uses a chosen strategy (brewing method) to accomplish a task.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;The Key Difference&lt;/em&gt;&lt;/strong&gt;:&lt;br&gt;
State Pattern - The object itself controls which behavior to perform by switching between states internally.&lt;/p&gt;

&lt;p&gt;Strategy Pattern - The client or context decides which algorithm or strategy to use externally and sticks with it.&lt;/p&gt;

&lt;p&gt;Think of it like,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In State, the behavior changes because your mood changed.&lt;br&gt;
In Strategy, the behavior changes because you picked a different tool.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>designpatterns</category>
      <category>softwareengineering</category>
      <category>techinterview</category>
      <category>cleancode</category>
    </item>
    <item>
      <title>Design Patterns Simplified: Part 13 — Template Method Pattern (a.k.a. “The Recipe Pattern”)</title>
      <dc:creator>Prateek Prabhakar</dc:creator>
      <pubDate>Wed, 06 Aug 2025 12:51:43 +0000</pubDate>
      <link>https://dev.to/prateekprabhakar/design-patterns-simplified-part-13-template-method-pattern-aka-the-recipe-pattern-55bj</link>
      <guid>https://dev.to/prateekprabhakar/design-patterns-simplified-part-13-template-method-pattern-aka-the-recipe-pattern-55bj</guid>
      <description>&lt;p&gt;The &lt;strong&gt;Template Method Pattern&lt;/strong&gt; belongs to the &lt;strong&gt;Behavioral&lt;/strong&gt; category of design patterns.&lt;/p&gt;

&lt;p&gt;Why? Because it defines &lt;em&gt;how an algorithm runs, step by step, while letting child classes tweak only the steps that vary&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Think of it like a cooking recipe. The steps are fixed,&lt;br&gt;
&lt;em&gt;Gather ingredients&lt;br&gt;
Cook&lt;br&gt;
Serve&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;But how you cook depends on the dish. You might make pasta or toss noodles, both follow the same structure(boil them first, put in the pan, etc.) but different steps.&lt;/p&gt;

&lt;p&gt;The Template Method Pattern in a nutshell, is like the “recipe” your base class writes and subclasses just fill in the flavor.&lt;/p&gt;




&lt;h3&gt;
  
  
  What Is the Template Method Pattern?
&lt;/h3&gt;

&lt;p&gt;The Template Method Pattern defines the skeleton of an algorithm in a base class, and lets subclasses override specific steps without changing the overall structure.&lt;/p&gt;

&lt;p&gt;It helps,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reuse shared logic&lt;/li&gt;
&lt;li&gt;Keep algorithms consistent&lt;/li&gt;
&lt;li&gt;Allow extensions via subclassing&lt;/li&gt;
&lt;li&gt;Avoid code duplication&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Report Generation System
&lt;/h3&gt;

&lt;p&gt;Let’s say you are building an enterprise application that generates various types of reports like, Sales Report, Inventory Report, User Activity Report.&lt;/p&gt;

&lt;p&gt;Every report follows the same high level process,&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Connect to the database&lt;/li&gt;
&lt;li&gt;Fetch relevant data&lt;/li&gt;
&lt;li&gt;Format the data&lt;/li&gt;
&lt;li&gt;Add a header and footer&lt;/li&gt;
&lt;li&gt;Export to PDF&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But the data and formatting vary based on report type.&lt;br&gt;
Instead of repeating the full process in every report class, we define it once in a base class, and only override what is different.&lt;br&gt;
That is the power of the Template Method Pattern.&lt;/p&gt;

&lt;h4&gt;
  
  
  What does the code look like?
&lt;/h4&gt;

&lt;p&gt;The basic setup would involve the below 3 components.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Abstract class&lt;/em&gt;&lt;/strong&gt;: defines the template (i.e. the fixed process)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Concrete subclasses&lt;/em&gt;&lt;/strong&gt;: override the specific steps&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Hook methods&lt;/em&gt;&lt;/strong&gt;: optional steps that can be overridden if needed
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Step 1: Define the Template (Base Class)
Class ReportGenerator
    Method GenerateReport()
        ConnectToDatabase()    // Step 1: Common step
        FetchData()            // Step 2: Customized by subclass
        FormatData()           // Step 3: Customized by subclass
        AddHeader()            // Step 4: Common step
        AddFooter()            // Step 5: Common step
        Export()               // Step 6: Common step

    Method ConnectToDatabase()
        Print "Connecting to database..."

    // Variable steps
    Abstract Method FetchData()  // To be implemented by subclasses
    Abstract Method FormatData() // To be implemented by subclasses

    // Optional hooks
    Method AddHeader()
        Print "Adding standard header..."

    Method AddFooter()
        Print "Adding standard footer..."

    Method Export()
        Print "Exporting report to PDF..."

//Step 2: Define Concrete Reports
Class SalesReport extends ReportGenerator
    Method FetchData()
        Print "Fetching sales data for current month..."

    Method FormatData()
        Print "Creating bar chart for sales..."

Class InventoryReport extends ReportGenerator
    Method FetchData()
        Print "Fetching stock levels from warehouse DB..."

    Method FormatData()
        Print "Formatting inventory into table layout..."

//caller logic
report = new SalesReport()
report.GenerateReport()

// Output:
// Connecting to database...
// Fetching sales data for current month...
// Creating bar chart for sales...
// Adding standard header...
// Adding standard footer...
// Exporting report to PDF...

report = new InventoryReport()
report.GenerateReport()

// Output:
// Connecting to database...
// Fetching stock levels from warehouse DB...
// Formatting inventory into table layout...
// Adding standard header...
// Adding standard footer...
// Exporting report to PDF...

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;ReportGenerator&lt;/code&gt; is an abstract class that defines how a report should be generated, but not the specific details for every report.&lt;/p&gt;

&lt;p&gt;The method &lt;code&gt;GenerateReport()&lt;/code&gt; is the template method. This method is not meant to be overridden. It controls the flow. It outlines the exact sequence of steps to generate a report.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Connect to the database&lt;br&gt;
Fetch data&lt;br&gt;
Format the data&lt;br&gt;
Add headers and footers&lt;br&gt;
Export the final report&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Steps like &lt;code&gt;ConnectToDatabase()&lt;/code&gt;, &lt;code&gt;AddHeader()&lt;/code&gt;, &lt;code&gt;AddFooter()&lt;/code&gt;, and &lt;code&gt;Export()&lt;/code&gt; are shared across all reports, so they are implemented once in the base class. &lt;code&gt;AddHeader()&lt;/code&gt; and &lt;code&gt;AddFooter()&lt;/code&gt; are basically hook methods that are optional steps the subclasses can override if they want to customize these parts, otherwise, the base implementation runs.&lt;/p&gt;

&lt;p&gt;But steps like &lt;code&gt;FetchData()&lt;/code&gt; and &lt;code&gt;FormatData()&lt;/code&gt; may vary for each report type (Sales report vs. Inventory report), so they are declared as abstract methods. Subclasses must provide their own implementation.&lt;br&gt;
This way, the base class ensures consistent structure, while subclasses customize the variable parts.&lt;/p&gt;

&lt;h4&gt;
  
  
  What Did We Achieve?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Consistent structure: All reports follow the same, tested process.&lt;/li&gt;
&lt;li&gt;Flexible overrides: Customize only what’s necessary without changing the flow.&lt;/li&gt;
&lt;li&gt;No code duplication: Common logic lives at one place in the base class.&lt;/li&gt;
&lt;li&gt;Clear control: The base class owns the workflow and subclasses plug in their specifics.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  When Should You Use It?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;You have an algorithm with a fixed sequence of steps but some steps vary&lt;/li&gt;
&lt;li&gt;You are building a framework or base class where extensions should follow a strict flow&lt;/li&gt;
&lt;li&gt;You want to enforce consistency across subclasses while allowing custom behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Use Cases?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Report/document generation workflows&lt;/li&gt;
&lt;li&gt;Unit test lifecycle (setup → test → teardown)&lt;/li&gt;
&lt;li&gt;Order processing pipelines&lt;/li&gt;
&lt;li&gt;File import/export processing&lt;/li&gt;
&lt;li&gt;Game engine loops (initialize → update → render)&lt;/li&gt;
&lt;li&gt;Image processing workflows (load → process → save)&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;To summarize, it would be apt to say,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Template Method Pattern lets you define a fixed recipe, and delegate specific steps to child classes.&lt;br&gt;
“It is the design pattern equivalent of a chef preparing a meal. The steps are fixed, but the ingredients vary.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It gives your code Reusability, Structure and Controlled flexibility.&lt;/p&gt;

&lt;p&gt;Next up in the series: &lt;strong&gt;&lt;a href="https://dev.to/prateekprabhakar/design-patterns-simplified-part-14-state-pattern-aka-the-mood-manager-390l"&gt;State Pattern&lt;/a&gt;&lt;/strong&gt;. Let's dive in!&lt;/p&gt;




&lt;h3&gt;
  
  
  BONUS: Isn't This Similar to &lt;strong&gt;&lt;a href="https://dev.to/prateekprabhakar/design-patterns-simplified-part-2-strategy-pattern-aka-pick-your-coupon-wisely-2ane"&gt;Strategy Pattern&lt;/a&gt;&lt;/strong&gt;?
&lt;/h3&gt;

&lt;p&gt;At first glance, Template Method and Strategy Patterns may seem alike. Both let you vary parts of an algorithm. But the difference lies in who controls the flow.&lt;/p&gt;

&lt;p&gt;Let us understand it through a quick story.&lt;/p&gt;

&lt;p&gt;You work at a company that generates different types of reports -Sales, Inventory, Feedback (as we took the example in the article above). Your application requirements are as below,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;All reports getting generated via this application must follow the same process.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Connect to DB&lt;/li&gt;
&lt;li&gt;Fetch Data&lt;/li&gt;
&lt;li&gt;Format Data&lt;/li&gt;
&lt;li&gt;Add Header &amp;amp; Footer&lt;/li&gt;
&lt;li&gt;Export to PDF&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, here the overall flow is fixed, but steps like data fetching and formatting differ per report type.&lt;br&gt;
To implement this functionality, you create a base class &lt;code&gt;ReportGenerator&lt;/code&gt; with a method &lt;code&gt;GenerateReport()&lt;/code&gt; that defines this flow. Subclasses override the steps that vary.&lt;br&gt;
&lt;strong&gt;That is Template Method Pattern.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What you are effectively saying is,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“This is how we have a fixed structure setup. You can tweak parts, but not the process.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A week passes by and the product comes up with a new requirement,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“We want to export reports in different formats - PDF, Excel, or HTML depending on user preference.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now again, the flow stays the same, only the export format changes dynamically.&lt;/p&gt;

&lt;p&gt;So you define a &lt;code&gt;IReportExportStrategy&lt;/code&gt; interface and implement different export classes. You inject the appropriate strategy at runtime based on the configuration and send the report.&lt;br&gt;
&lt;strong&gt;That is Strategy Pattern.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This time what you are saying is,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“The task stays the same. You choose the tool to do the final step.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Differences:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyr1i5fzgecu0c3u0m1x5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyr1i5fzgecu0c3u0m1x5.png" alt="Template Method vs Strategy Pattern" width="800" height="175"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To summarize the difference between the two, you should, &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Use Template Method when the flow is fixed and only steps vary.&lt;br&gt;
Use Strategy Pattern when the task is fixed but the way to perform it varies, and should be chosen at runtime.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>designpatterns</category>
      <category>cleancode</category>
      <category>techinterview</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Design Patterns Simplified: Part 12 — Memento Pattern (a.k.a. “Your Object's Time Machine”)</title>
      <dc:creator>Prateek Prabhakar</dc:creator>
      <pubDate>Mon, 04 Aug 2025 12:19:00 +0000</pubDate>
      <link>https://dev.to/prateekprabhakar/design-patterns-simplified-part-12-memento-pattern-aka-your-objects-time-machine-3d6g</link>
      <guid>https://dev.to/prateekprabhakar/design-patterns-simplified-part-12-memento-pattern-aka-your-objects-time-machine-3d6g</guid>
      <description>&lt;p&gt;The &lt;strong&gt;Memento Pattern&lt;/strong&gt; belongs to the &lt;strong&gt;Behavioral&lt;/strong&gt; category of design patterns.&lt;/p&gt;

&lt;p&gt;Why? Because it focuses on &lt;em&gt;how objects capture and restore their past states (like an Undo)&lt;/em&gt;, all while keeping their internal details private.&lt;br&gt;
It gives your application the power to,&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Save a snapshot of an object’s state&lt;/li&gt;
&lt;li&gt;Restore it to that state later&lt;/li&gt;
&lt;li&gt;Do this all without exposing the object’s internal structure&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It is like giving your object a Time Machine, so it can rewind to a known good state when things go wrong.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let's take an example of the Shopping Cart Undo&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Imagine you are shopping online,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You add a Phone to your cart.&lt;/li&gt;
&lt;li&gt;Then a pair of Headphones.&lt;/li&gt;
&lt;li&gt;Then a Charger.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then suddenly, you accidentally delete the headphones from your cart. Oops! But no worries. You click ‘Undo’, and they are magically back.&lt;/p&gt;

&lt;p&gt;That is the Memento Pattern in action.&lt;br&gt;
Each time you make a change, your system quietly saves a snapshot of the cart.&lt;br&gt;
When you click Undo, it just restores the last saved version.&lt;/p&gt;




&lt;h3&gt;
  
  
  What is the Momento Pattern?
&lt;/h3&gt;

&lt;p&gt;It allows an object to capture and store its internal state so it can be restored later, all without exposing its internal details.&lt;/p&gt;

&lt;p&gt;It involves 3 main parts,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Originator&lt;/em&gt;&lt;/strong&gt;: The object whose state we want to save/restore (e.g. Shopping Cart)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Memento&lt;/em&gt;&lt;/strong&gt;: A value object storing the Originator's state&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Caretaker&lt;/em&gt;&lt;/strong&gt;: Manages the history of Mementos, e.g. to allow undo/redo&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Wiki Document with Version History
&lt;/h3&gt;

&lt;p&gt;Let’s say you are editing a wiki document. You write, you revise, you delete, and eventually hit Publish.&lt;/p&gt;

&lt;p&gt;Oops! You just realized you deleted an important paragraph. What would you do?&lt;br&gt;
Mostly, you would like to revert it to a previous published version.&lt;/p&gt;

&lt;p&gt;Each time you publish, the system silently saves the document’s current state. Later, you can roll back to any of those versions.&lt;/p&gt;

&lt;p&gt;That is exactly what the Memento Pattern helps you do in code.&lt;/p&gt;

&lt;h4&gt;
  
  
  What does the code look like?
&lt;/h4&gt;

&lt;p&gt;Say we want to mimic the code for how the wiki might be built with following features,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can publish new versions&lt;/li&gt;
&lt;li&gt;View current content&lt;/li&gt;
&lt;li&gt;Undo to a previous version
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Step 1: Define the Memento (saved version of the document)
Class WikiMemento
    Constructor(content)
        this.content = content

    Method GetContent()
        return content

//Step 2: Define the Originator (Wiki Document)
Class WikiDocument
    Property content

    Method Write(text)
        content = text

    Method Show()
        Print("Current Content: " + content)

    Method Save()
        return new WikiMemento(content)

    Method Restore(memento)
        content = memento.GetContent()

//Step 3: Define the Caretaker (History Manager)
Class VersionHistory
    Property history = []

    Method SaveVersion(memento)
        history.Push(memento)

    Method Undo()
        If history is not empty:
            return history.Pop()
        Else:
            return null

//caller logic
// Initialize components
doc = new WikiDocument()
history = new VersionHistory()

// First version
doc.Write("Initial Draft of Wiki Page")
history.SaveVersion(doc.Save())

// Update version
doc.Write("Added introduction and summary")
history.SaveVersion(doc.Save())

// Another update
doc.Write("Removed summary by mistake...")
doc.Show()

// Undo last change
prev = history.Undo()
doc.Restore(prev)
doc.Show()

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just like hitting Undo in your document editor, your application brings back the last published version.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;NOTE: In real world apps, you might want to undo to any specific version, not just the last one. This is also supported by the Memento Pattern but can add complexity. To keep things simple, here the example focuses on undoing the most recent change.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  What Did We Achieve?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Internal state saved without exposing implementation&lt;/li&gt;
&lt;li&gt;Clean separation between state management and history tracking&lt;/li&gt;
&lt;li&gt;Reversible actions (Undo/Redo behavior)&lt;/li&gt;
&lt;li&gt;It is scalable. You can add version limits, redo stacks, timestamps and more.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  When Should You Use It?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;When you want to implement undo/redo&lt;/li&gt;
&lt;li&gt;When you need state checkpoints (e.g., autosave, game saves)&lt;/li&gt;
&lt;li&gt;When you need to log or rollback user actions&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Use Cases?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Document editors (Google Docs, Notion, MS Word)&lt;/li&gt;
&lt;li&gt;Game save systems&lt;/li&gt;
&lt;li&gt;State restoration in visual editors (like Figma, Canva)&lt;/li&gt;
&lt;li&gt;Transaction rollback systems&lt;/li&gt;
&lt;li&gt;Form editing with preview/reset options&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;To summarize, it would be apt to say,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Memento Pattern lets your objects “remember” and "rewind" their states, just like a time machine, enabling undo functionality without exposing their inner workings.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is the design pattern equivalent of Ctrl+Z. It gives you the power to undo mistakes or revisit past states without complicating your logic or breaking encapsulation.&lt;/p&gt;

&lt;p&gt;Hope, the next time you hit the UNDO/REDO on your keyboard, you will definitely recall this pattern.&lt;/p&gt;

&lt;p&gt;Next up in the series: &lt;strong&gt;&lt;a href="https://dev.to/prateekprabhakar/design-patterns-simplified-part-13-template-method-pattern-aka-the-recipe-pattern-55bj"&gt;Template Pattern&lt;/a&gt;&lt;/strong&gt;. Join me there!&lt;/p&gt;

</description>
      <category>designpatterns</category>
      <category>softwareengineering</category>
      <category>cleancode</category>
      <category>techinterview</category>
    </item>
  </channel>
</rss>
