Sobes.tech
Middle+

What tasks have you solved using design patterns?

sobes.tech AI

Answer from AI

Applied various patterns to improve the structure and maintainability of the code:

Creational:

  • Singleton: For creating a single instance of objects, such as a configuration manager or a database connection pool.
    public final class ConfigManager {
        private static ConfigManager instance;
        private ConfigManager() {} // Private constructor
        public static synchronized ConfigManager getInstance() {
            if (instance == null) {
                instance = new ConfigManager();
            }
            return instance;
        }
    }
    
  • Factory Method: For creating objects with specific properties without explicitly specifying their classes. Used when working with different types of file parsers.
  • Abstract Factory: For creating families of related or dependent objects without specifying their concrete classes. Used for working with different data source types (e.g., file system, database) and their corresponding objects.

Structural:

  • Adapter: To adapt the interface of one class to another expected by the client. Used for integrating third-party libraries with incompatible interfaces.
    public interface Target {
        void request();
    }
    
    public class Adaptee {
        public void specificRequest() {
            System.out.println("Adaptee's specific request");
        }
    }
    
    public class Adapter implements Target {
        private Adaptee adaptee;
    
        public Adapter(Adaptee adaptee) {
            this.adaptee = adaptee;
        }
    
        @Override
        public void request() {
            adaptee.specificRequest();
        }
    }
    
  • Decorator: For dynamically adding new responsibilities to objects without changing their structure. Used for adding logging or caching functionality to existing objects.
  • Composite: For composing objects into tree structures to represent hierarchies "part-whole". Used when working with UI elements or file structures.

Behavioral:

  • Observer: To define a one-to-many dependency between objects so that when one object changes its state, all its dependents are notified and updated automatically. Used for implementing event notification systems.
    import java.util.ArrayList;
    import java.util.List;
    
    public class Subject {
        private List<Observer> observers = new ArrayList<>();
        private int state;
    
        public void attach(Observer observer) {
            observers.add(observer);
        }
    
        public void setState(int state) {
            this.state = state;
            notifyObservers();
        }
    
        private void notifyObservers() {
            for (Observer observer : observers) {
                observer.update();
            }
        }
    }
    
    public interface Observer {
        void update();
    }
    
  • Strategy: For defining a family of algorithms, encapsulating each one, and making them interchangeable. Used for selecting different data processing strategies depending on the context.
  • Template Method: For defining the skeleton of an algorithm in an operation, deferring some steps to subclasses. Used for standardizing request processing.