codesbyjit.dev
← cd ../blog
#System Design#Low Level Design#LLD#Software Architecture#OOP#Design Patterns#Clean Architecture

Low-Level Design Isn't About UML: It's About Designing Code That Survives Change

acodesbyjit·AUG 29, 2026·1 min read
Low-Level Design Isn't About UML: It's About Designing Code That Survives Change

The central argument should be:

LLD is the process of turning system responsibilities into concrete software components, interfaces, dependencies, data models, and interactions.

A good design is not necessarily the one with the most classes or patterns. It is the one where a change in one part of the system has the smallest necessary impact on the rest.

That is where your blog becomes interesting.

Microsoft's design guidance emphasizes that abstractions are useful for extensibility and testability, but also warns against creating abstractions prematurely or making them unnecessarily complex. ([Microsoft Learn][1])

Clean Architecture demonstrates the same idea through dependency direction: high-level application logic should depend on abstractions rather than directly on infrastructure implementations, allowing infrastructure to be swapped without rewriting the core logic. ([Microsoft Learn][2])

NASA's software engineering guidance also frames lower-level design around decomposition into design entities, interfaces, dependencies, resources, processing, and data—not just class diagrams. ([SWEHB][3])

Best structure

The Problem: Code Changes Faster Than Architecture

Start with a realistic example:

text
You build an application with a payment service.

Initially:
PaymentService -> Stripe

Six months later:
PaymentService -> Stripe
               -> Razorpay
               -> PayPal

If PaymentService directly depends on Stripe everywhere, adding another provider means changing business logic.

A better design:

text
PaymentService
       |
PaymentProvider interface
   /        |        \
Stripe   Razorpay   PayPal

The important point:

The interface is not useful because interfaces are “good practice.” It is useful because the application has a real boundary that may need multiple implementations.

This matches Microsoft's guidance that abstractions should represent useful contracts and should not be introduced arbitrarily. ([Microsoft Learn][1])

The Five Things I Actually Look For in LLD

I think this would be an excellent section:

  1. Responsibilities — what does each component own?
  2. Boundaries — where should implementation details stop leaking?
  3. Dependencies — what changes when something changes?
  4. Abstractions — what behavior needs a stable contract?
  5. Extensibility — what will probably change later?

Don't Use Patterns Just to Use Patterns

This is important and makes the blog sound human.

Bad:

“We used Factory, Strategy, Adapter, Observer and Singleton.”

Better:

“We introduced Strategy because the system had multiple payment implementations with the same behavior but different execution logic.”

A design pattern should be the result of a problem, not the starting point.

The Most Important Question

End the LLD article with:

If I change this requirement tomorrow, how many unrelated files will I need to touch?

If the answer is 30 files, the design has a problem.

share: