LLD INTERVIEW WORKFLOW / OBJECT DESIGN BRIEF

Discuss extensibility

Step 8: close the interview by showing how the design evolves.

IntermediatePhase 10 / Topic 8 of 8ResponsibilitiesCollaborationsExtensibility
01

Overview

Step 8: close the interview by showing how the design evolves. Interviewers commonly ask follow-ups: add a new seat type, support multiple cities, add dynamic pricing, persist data, scale to many servers, add waitlists. A strong answer names exactly which classes change and which stay untouched, proving the design follows OCP and has clear seams.

Prepare a short 'extension map': for each likely change, the extension point (interface, strategy, event) and the impact. Also discuss what you would do for production: persistence behind repositories, distributed locks or database constraints for concurrency, observability, and testing strategy.

A house built with extension plans

A well-designed house has plumbing and wiring routed so adding a bathroom or a floor is straightforward. A poorly designed one needs walls torn down for every change.

02

When to use it

  • The final minutes of an LLD interview.
  • When the interviewer adds a new requirement.
  • Design reviews assessing future-proofing.
03

Where it shows up in interviews

Follow-up requirements

Recognize it when: 'how would you add X?'

  • Add dynamic pricing to movie booking
  • Add EV charging to a parking lot
  • Add express elevators
04

Where it is used in real software

Plugin architectures

IDEs and browsers add features via extension points without core changes.

Feature flags

New behavior ships behind flags and new strategy implementations.

Repository pattern

Swapping in-memory storage for a database without touching domain logic.

05

Key terms

Extension point
Interface or event where new behavior plugs in.
Blast radius of a change
How many classes a new requirement touches.
Seam
Place where behavior can be substituted.
Evolution path
From in-memory to persistent to distributed.
06

How it works, step by step

  1. 1
    List likely changes

    From the prompt's domain and your out-of-scope list.

  2. 2
    Map each to an extension point

    New strategy, new subclass, new listener.

  3. 3
    Name impacted classes

    Ideally one or two new classes.

  4. 4
    Discuss production evolution

    Persistence, distributed concurrency, observability.

  5. 5
    Admit limitations

    Explain what would need refactoring and why.

07

Extension map for the movie ticket system

Follow-up requirements

Step 1 / 6
New requirementExtension pointChange
Recliner seat typeSeatType + PricingStrategyAdd enum value and price rule
Dynamic (demand) pricingPricingStrategyNew DemandPricing class
New payment providerPaymentGatewayNew adapter
SMS on bookingBookingEvents listenerNew listener
Multiple serversSeatLockManagerDB conditional update or Redis lock
PersistenceRepositoriesSQL implementations; domain unchanged

NOWNew requirement: Recliner seat type | Extension point: SeatType + PricingStrategy | Change: Add enum value and price rule

Most changes are additions, not modifications, which is the evidence of a good design.

08

Implementation

// New requirement: demand-based pricing. Added as a new strategy; nothing else changes.class DemandPricing implements PricingStrategy {  constructor(private base: PricingStrategy, private occupancy: (showId: string) => number) {}  price(seat: Seat, show: Show) {    const factor = this.occupancy(show.id) > 0.8 ? 1.25 : this.occupancy(show.id) < 0.3 ? 0.85 : 1;    return Math.round(this.base.price(seat, show) * factor);  }} // New requirement: persistence. The domain depends on this interface already.interface ShowRepository { get(id: string): Promise<Show>; save(show: Show): Promise<void> }class InMemoryShowRepository implements ShowRepository { /* used in the interview */ }class PostgresShowRepository implements ShowRepository { /* added later, same interface */ } // Composition root is the only place that changesconst service = new BookingService(new PostgresShowRepository(pool), new DemandPricing(standardPricing, occupancyOf), stripeAdapter);
09

Complexity and performance

Ideal change1-2 new classes

No edits to core logic.

TimeLast ~5 minutes

Leave room for it.

10

Trade-offs

Anticipating change vs YAGNI

Build seams where change is likely (pricing, providers); do not generalize everything.

In-memory vs production

In-memory designs are fine for interviews if you explain the path to persistence and distribution.

11

Variants and related techniques

Event-driven extensions

Publish domain events so new features subscribe without touching core code.

Configuration-driven rules

Rules and prices in config or a rule engine.

12

Common mistakes

  • Saying 'I would just add an if statement'.

    Fix: Point to the extension point and the new class.

  • Ignoring scale when asked.

    Fix: Explain distributed locking, persistence, and caching briefly.

13

Interview questions

How would you add a new vehicle type to your parking lot?

Add a Vehicle subclass or enum value with its size and a spot-fit rule; update the pricing strategy if pricing differs. Allocation and ticketing code stay unchanged because they depend on abstractions.

How would your in-memory design change for multiple servers?

Move state to a database behind the existing repositories, replace in-memory locks with database conditional updates or distributed locks behind the same interface, add idempotency keys, and keep domain logic unchanged.

14

Practice problems

ProblemDifficultyWhat it trains
Extension map for an elevator systemMediumSeams.
Evolve Splitwise to multi-currency and persistenceHardImpact analysis.