ReviseAlgo Logo

LLD Introduction

Design Thinking

Approach to problem solving

Last Updated: June 25, 2026 18 min read

Design Thinking is a systematic, human-centered approach to solving complex software engineering challenges. Before drawing class models or writing execution logic, you must understand the problem constraints, define entities, and build low-fidelity prototypes.

1. Learning Objectives

  • Apply the five phases of Design Thinking (Empathize, Define, Ideate, Prototype, Test) to code architecture.
  • Translate descriptive product specifications into class structures and system requirements.
  • Validate designs using scenario-based walkthroughs before implementation.

2. Problem Statement

Most software project failures do not stem from bad coding skills, but rather from building the wrong solution.

  • Without Design Thinking: Engineers jump straight to implementation. They build models without clarifying assumptions, resulting in missing functionalities and large-scale structural rework.
  • With Design Thinking: Requirements are gathered, entities are mapped, and edge-cases are accounted for prior to coding.

3. Real-world Analogy

Imagine building a customized mountain bicycle. If you jump straight into welding metal tubes, you might build a bicycle that is too heavy, has the wrong gear ratio for steep climbs, or lacks suspension points.

Instead, you talk to riders (Empathize), list the constraints (Define), brainstorm shock absorber options (Ideate), draw layouts (Prototype), and test it on dirt trails (Test) before manufacturing the frame.

4. Theory

Applying Design Thinking to LLD translates into five concrete stages:

  • Empathize: Gather requirements. What are the users doing? Clarify constraints (e.g. "Can a user have multiple wishlists?").
  • Define: Outline the domain model. Identify entities (Nouns in specifications) and operations (Verbs in specifications).
  • Ideate: Draft design alternatives. Should we use inheritance or composition? Which design patterns fit?
  • Prototype: Draw UML class structures and sketch interfaces.
  • Test: Write unit tests and run dry-run walkthroughs against specific scenarios.

5. Visual Diagram

This flowchart visualizes the design thinking loop applied to software design:

1. Empathize (Ask users and clarify constraints)
2. Define (Identify Domain Entities & Nouns)
3. Ideate (Assess patterns & loose coupling options)
4. Prototype (Write skeleton interfaces & classes)
5. Test (Execute unit tests & refactor logic)

6. Syntax Explanation

When defining domain structures, we use Composition to represent "Has-A" relationships (e.g. a Wishlist has a collection of Product objects).

  • In Java, collections are declared via List or Set.
  • In Python, we use type hinting like List[Product] to declare relationships.
  • In C++, we use smart pointers std::vector>.

7. Step-by-Step Implementation

Let's design a simple Product Catalog Wishlist based on the following requirement: *"A customer can add products to a custom wishlist and display them."*

  • Step 1: Identify Nouns: Product, Wishlist. Identify Verbs: addProduct, getProducts.
  • Step 2: Declare the Product entity.
  • Step 3: Declare the Wishlist class, containing a collection of Products.
  • Step 4: Write the client code to simulate and verify this flow.

8. Complete Code

9. Code Walkthrough

In the Wishlist class, we shield the internal products list. Returning Collections.unmodifiableList(products) in Java or a copy of the list in Python/C++ blocks clients from editing the wishlist contents without going through the class's addProduct() method.

10. Execution Flow

  • Create Product instance on the heap.
  • Create Wishlist instance on the heap.
  • Invoke wishlist.addProduct(product), passing the reference pointer.
  • Verify addition by requesting the unmodifiable collection and asserting size.

11. Internal Working

Returning an unmodifiable wrapper in Java allocates a lightweight read-only view in the Heap that points to the original list. If a client attempts to execute .add() on this wrapper, a runtime UnsupportedOperationException is thrown, protecting internal state.

12. Complexity Analysis

  • Time Complexity: $O(1)$ to append a product reference to the array list.
  • Space Complexity: $O(1)$ extra space used per element.

13. Best Practices

  • List constraints first: Always clarify constraints (e.g. maximum wishlist capacity) in the empathize phase.
  • Return read-only collections: Protect internal lists from direct external writes.
  • Write test specs: Mock client scenarios to test edge cases.

14. Common Mistakes

  • Returning direct references to mutable internal lists, which bypasses class encapsulation.
  • Failing to validate inputs (e.g. allowing null products to be added to the list).

15. Interview Questions

Q: How do you identify domain entities from a text-based problem statement?
Answer: Read the requirements and perform "noun-verb analysis." Nouns typically map to classes and variables, while verbs map to class methods and interactions.

16. Practice Exercises

  • Easy: Add a method removeProduct(Product product) to the Wishlist class.
  • Medium: Add a constraint to limit the wishlist to a maximum of 10 items. Throw an exception when exceeded.
  • Hard: Build a dynamic sharing mechanism allowing users to share their wishlist with other users in read-only mode.

17. Challenge Problem

Design an encapsulated Shopping Cart class where discounts can be applied dynamically using different coupon structures.

18. Summary

  • Design Thinking centers software development around user needs.
  • Noun-verb analysis translates textual requirements into class blueprints.
  • Encapsulated lists should be wrapped to block external writes.

19. Cheat Sheet

Design Phase Main Focus Key Output
1. Empathize & Define Clarify requirements & nouns/verbs Requirement checklist, constraints
2. Ideate & Prototype UML structures & class drafts Class diagrams, interface skeletons
3. Test Validate code against dry-runs Unit test execution success

20. Quiz

1. What is the first stage in the Design Thinking loop?

A) Test
B) Empathize (Correct)
C) Prototype

2. How are class names and attributes identified from requirements?

A) Analyzing nouns in the specifications (Correct)
B) Analyzing verbs in the specifications
C) Generating random names

3. What is the benefit of returning 'Collections.unmodifiableList()' in Java?

A) It compiles the list faster at runtime
B) It prevents clients from modifying the list directly, keeping variables encapsulated (Correct)
C) It automatically encrypts the database record

4. In the mountain bike analogy, trail testing matches which software stage?

A) Empathize
B) Test (Correct)
C) Define

5. Which of the following is a sign of lack of design planning?

A) Decoupled interface wrappers
B) Tightly coupled code structures that miss user requirements (Correct)
C) Writing unit tests before implementation

6. What type of collection prevents duplicate entries?

A) List
B) Set (Correct)
C) Stack

7. What is the time complexity of adding a pointer reference to an ArrayList?

A) O(log N)
B) O(1) (Correct)
C) O(N)

8. Which exception is thrown in Java if a client tries to modify an unmodifiable list?

A) NullPointerException
B) UnsupportedOperationException (Correct)
C) ClassCastException

9. In noun-verb analysis, what do verbs typically map to?

A) Class names
B) Method names (Correct)
C) Variable types

10. Why is testing placed at the end of the design thinking loop?

A) To validate that the prototype correctly solves the defined problem (Correct)
B) It is the least important step
C) To write CSS styling files

21. Next Lesson Preview

Congratulations! You have completed the LLD Introduction module. In the next module, OOP Fundamentals, we begin with Classes and Objects to explore the core pillars of object-oriented design!