Design Patterns Basics in System Architecture
advance · System Architecture
Design Patterns: Blueprints for Scalable Code Design patterns are reusable solutions to common problems in software design. They are not code you can copy-paste, but rather a description of how to structure your classes and objects to make your code more maintainable, flexible, and scalable. 1. Singleton Pattern The Singleton ensures that a class has only one instance and provides a global point of access to it. The Problem: You have a shared resource, such as a database connection pool or a configuration manager, and you don't want to create hundreds of instances of it (which would be wasteful and lead to synchronization issues). Implementation: The class makes its constructor private and provides a getInstance() method that returns the existing instance if it exists, or creates it if it doesn't. Caution: Singletons can introduce hidden dependencies and make unit testing difficult because they create global state. 2. Factory Pattern The Factory pattern provides an interface for creating objects in a superclass but allows subclasses to alter the type of objects that will be created. The Problem: You have a complex object creation logic. You don't want your main code to depend on the concrete classes of the objects it creates. Implementation: You define a "Factory" class or method that handles the instantiation. Instead of using new Service() , you call factory.createService() . The Benefit: Decoupling. If you need to change the implementation of a service, you only change the factory; your application code remains untouched. 3. Observer Pattern The Observer pattern defines a one-to-many dependency between objects so that when one object (the "Subject") changes state, all its dependents ("Observers") are notified and updated automatically. The Problem: You have a system where multiple parts of the application need to react to a specific event (e.g., a "User Logged In" event). Implementation: The Subject maintains a list of Observers. When an event occurs, it iterates through the list and calls an update() method on each one. Use Case: This is the foundation of Event-Driven Architecture and UI frameworks (like React or Vue, where the UI "observes" the state). 4. Strategy Pattern The Strategy pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. It lets the algorithm vary independently from the clients that use it. The Problem: You have a class that performs an action in different ways (e.g., a PaymentProcessor that supports Credit Card, PayPal, or Crypto). Without the strategy pattern, you would end up with a massive if-else or switch statement that is hard to maintain. Implementation: You define an interface for the algorithm. You then create concrete classes for each strategy (e.g., CreditCardStrategy , PaypalStrategy ). The PaymentProcessor takes the strategy as an argument and executes it. The Benefit: Open/Closed Principle—you can add a new payment method without changing the existing PaymentProcessor code. Design Pattern Reference Matrix Pattern Category Primary Goal Best Used For Singleton Creational Controlled access to a single instance. Logger, Config, DB Pools. Factory Creational Encapsulate object creation. Complex object instantiation. Observer Behavioral Notify objects of state changes. Event systems, UI updates. Strategy Behavioral Interchangeable algorithms. Payment types, sorting algorithms.