Chaturmind
LearnDSASystem DesignDevOpsEngineering GrowthBlog
Start learning
Chaturmind

Structured learning paths for engineers who want to go deep. Written by practitioners.

Learn

  • Java
  • DSA
  • System Design
  • Spring Boot
  • AI / ML
  • DevOps
  • Engineering Growth

Company

  • Blog
  • Contact

Legal

  • Privacy Policy
  • Terms of Service

© 2026 Chaturmind. All rights reserved.

Built for engineers who want to go deep.


← Low-Level Design & Design Patterns

OOP Fundamentals & SOLID Principles

  • Object-Oriented Design Refresher
  • Single Responsibility & Open/Closed
  • Liskov Substitution & Interface Segregation
  • Dependency Inversion

Creational Design Patterns

  • Singleton Pattern
  • Factory & Abstract Factory
  • Builder Pattern
  • Prototype Pattern

Structural Design Patterns

  • Adapter & Facade
  • Decorator Pattern
  • Composite & Proxy
  • Bridge & Flyweight

Behavioral Design Patterns

  • Strategy Pattern
  • Observer Pattern
  • Command Pattern
  • Template Method
  • State Pattern
  • Chain of Responsibility
  • Iterator & Mediator
  • Visitor Pattern

Machine Coding Exercises

  • Parking Lot — Requirements & Class Design
  • Parking Lot — Implementation
  • Elevator System — Requirements & Class Design
  • Elevator System — Implementation & Scheduling
  • Library Management System
  • Tic-Tac-Toe / Board Game Design
  • Chess Engine Design
  • Vending Machine Design
  • ATM System Design
  • In-Memory Rate Limiter
  • Thread-Safe LRU Cache
  • Connection Pool Design
  • Producer-Consumer Class Design
  • Movie Ticket Booking System
  • Hotel Reservation System
  • Airline Booking / Seat Selection System
  • Splitwise / Expense Sharing System
  • Design a Logging Framework
  • Design a Notification/Observer-Based Pub-Sub
  • Design a Cache with Pluggable Eviction Policy
  • Design Snake and Ladder
  • Design a Card Game Framework
  • Design an Inventory Management System
  • Restaurant Management System
  • Food Delivery Order Matching
  • Design a Shopping Cart & Checkout Flow
  • Design a Recommendation Engine
  • Design a Job Scheduler
  • Design a Circuit Breaker
  • Design a Distributed ID Generator
  • Design a Pub-Sub Message Broker
  • Design Twitter/X
  • Multi-Pattern Problem: Design a Ride Booking Class Model
  • Multi-Pattern Problem: Design a Food Ordering Class Model
  • Design an Authentication/Authorization Module
  • Design a Form/Survey Builder
  • Design a Meeting Room / Calendar Booking System
  • Design a Search/Filter Engine for an E-Commerce Catalog
  • Design a Voting/Polling System
  • Design a Retry Mechanism with Backoff
  • Design a Health Check Aggregator
  • Design a Feature Flag System
  • Design a Config Management Client
  • Design a Leader Election Algorithm
  • Design a Distributed Counter
  • Design a Bloom Filter
  • Design a Consistent Hashing Ring
  • Design a Distributed Tracing Library
  • Design a Metrics Collection Library
  • Design an Audit Logging Framework
  • Design a Plugin/Extension System
  • Design a Workflow Engine
  • Multi-Pattern Capstone: Design a Food Delivery App
Chaturmind
← Low-Level Design & Design Patterns

OOP Fundamentals & SOLID Principles

  • Object-Oriented Design Refresher
  • Single Responsibility & Open/Closed
  • Liskov Substitution & Interface Segregation
  • Dependency Inversion

Creational Design Patterns

  • Singleton Pattern
  • Factory & Abstract Factory
  • Builder Pattern
  • Prototype Pattern

Structural Design Patterns

  • Adapter & Facade
  • Decorator Pattern
  • Composite & Proxy
  • Bridge & Flyweight

Behavioral Design Patterns

  • Strategy Pattern
  • Observer Pattern
  • Command Pattern
  • Template Method
  • State Pattern
  • Chain of Responsibility
  • Iterator & Mediator
  • Visitor Pattern

Machine Coding Exercises

  • Parking Lot — Requirements & Class Design
  • Parking Lot — Implementation
  • Elevator System — Requirements & Class Design
  • Elevator System — Implementation & Scheduling
  • Library Management System
  • Tic-Tac-Toe / Board Game Design
  • Chess Engine Design
  • Vending Machine Design
  • ATM System Design
  • In-Memory Rate Limiter
  • Thread-Safe LRU Cache
  • Connection Pool Design
  • Producer-Consumer Class Design
  • Movie Ticket Booking System
  • Hotel Reservation System
  • Airline Booking / Seat Selection System
  • Splitwise / Expense Sharing System
  • Design a Logging Framework
  • Design a Notification/Observer-Based Pub-Sub
  • Design a Cache with Pluggable Eviction Policy
  • Design Snake and Ladder
  • Design a Card Game Framework
  • Design an Inventory Management System
  • Restaurant Management System
  • Food Delivery Order Matching
  • Design a Shopping Cart & Checkout Flow
  • Design a Recommendation Engine
  • Design a Job Scheduler
  • Design a Circuit Breaker
  • Design a Distributed ID Generator
  • Design a Pub-Sub Message Broker
  • Design Twitter/X
  • Multi-Pattern Problem: Design a Ride Booking Class Model
  • Multi-Pattern Problem: Design a Food Ordering Class Model
  • Design an Authentication/Authorization Module
  • Design a Form/Survey Builder
  • Design a Meeting Room / Calendar Booking System
  • Design a Search/Filter Engine for an E-Commerce Catalog
  • Design a Voting/Polling System
  • Design a Retry Mechanism with Backoff
  • Design a Health Check Aggregator
  • Design a Feature Flag System
  • Design a Config Management Client
  • Design a Leader Election Algorithm
  • Design a Distributed Counter
  • Design a Bloom Filter
  • Design a Consistent Hashing Ring
  • Design a Distributed Tracing Library
  • Design a Metrics Collection Library
  • Design an Audit Logging Framework
  • Design a Plugin/Extension System
  • Design a Workflow Engine
  • Multi-Pattern Capstone: Design a Food Delivery App
HomeLearnSystem DesignLow-Level Design & Design PatternsMachine Coding Exercises
✓ FreeIntermediate· 6 min read

Design a Config Management Client

ConfigSource, ConfigClient, and ConfigChangeListener using the Observer pattern so components react to config changes without polling, plus fallback-to-default behavior when the config source is unreachable.

Published September 23, 2026


Design a Config Management Client

Core classes

interface ConfigSource { Map<String, String> fetchAll(); }
interface ConfigChangeListener { void onChange(String key, String oldValue, String newValue); }

class ConfigClient {
    ConfigSource source;
    Map<String, String> cache = new ConcurrentHashMap<>();
    List<ConfigChangeListener> listeners = new CopyOnWriteArrayList<>();
}

ConfigSource as an interface (rather than a hardcoded connection to one specific backend) is what lets the SAME ConfigClient work against different backing stores — a local file for tests, a remote config service in production — without any calling code changing, a direct application of Dependency Inversion.

Observer pattern: reacting to changes without polling

class ConfigClient {
    void registerListener(ConfigChangeListener listener) { listeners.add(listener); }

    void refresh() {
        Map<String, String> latest = source.fetchAll();
        for (var entry : latest.entrySet()) {
            String oldValue = cache.get(entry.getKey());
            if (!Objects.equals(oldValue, entry.getValue())) {
                cache.put(entry.getKey(), entry.getValue());
                listeners.forEach(l -> l.onChange(entry.getKey(), oldValue, entry.getValue())); // notify subscribers
            }
        }
    }
}

Components that care about a specific config value REGISTER as listeners once, then get notified automatically whenever that value actually changes — rather than each component independently polling ConfigClient.get("someKey") on every operation to check for a change. This is the same Observer-pattern benefit as Design a Feature Flag System's push-based invalidation: components stay decoupled from HOW/WHEN refresh happens, they just react when notified.

Fallback-to-default when the source is unreachable

String get(String key, String defaultValue) {
    return cache.getOrDefault(key, defaultValue); // last-known-good value, or an explicit default
}

If refresh() fails (the remote config source is temporarily unreachable), the client should keep serving the LAST SUCCESSFULLY FETCHED values from its cache rather than failing every config lookup — this is a direct application of Health Checks' essential-vs-non-essential reasoning: config staleness (serving slightly outdated values during an outage) is almost always preferable to config UNAVAILABILITY (every part of the application that reads config suddenly breaking). A genuinely never-yet-successfully-fetched key falls back to an explicit, caller-provided default rather than throwing.

Follow-up questions this topic invites — and their answers

Q: How does the client know WHEN to call refresh() — polling, or something else? A: Either a periodic poll (simplest, same freshness/latency trade-off as Design a Feature Flag System) or a push-based mechanism (the config source notifying the client of a change via a webhook or a long-lived connection) — the Observer pattern here is about how CHANGES PROPAGATE TO INTERNAL LISTENERS once detected, independent of whether detection itself is poll-based or push-based.

Q: Is there a risk in notifying listeners synchronously, inline within refresh()? A: Yes — a slow or misbehaving listener could block the entire refresh cycle (and delay other listeners from being notified); a more robust implementation dispatches notifications asynchronously (each listener notified on its own thread/task) so one slow listener doesn't degrade the whole notification pipeline.

Q: How would you avoid every application instance hammering the config source with its own independent polling? A: At real scale, a common pattern layers a caching/pub-sub tier BETWEEN the config source and many client instances — instances subscribe to that intermediate tier rather than each polling the ultimate source directly, similar in spirit to how a CDN sits between many viewers and one origin server.

Q: What's a concrete failure mode if listeners aren't properly unregistered when a component shuts down? A: A classic memory leak — the listener list holds a reference to the component indefinitely, preventing garbage collection even after the component is logically done, the same lifecycle-management discipline as MDC/ThreadLocal cleanup covered in Centralized Logging, applied to a different kind of resource.

Previous

Design a Feature Flag System

Next

Design a Leader Election Algorithm

AI Tutor

Lesson: Design a Config Management Client

Quick actions

AI responses can be inaccurate. Verify critical information.