Skip to content

From requirements to classes, with just enough UML

How to turn a problem statement into classes: find the nouns and verbs, give each rule an owner, draw a class diagram and a sequence diagram in five minutes, and handle a changed requirement with a small edit.

  • Lesson 109 of 125
  • 23 min read
  • Core
  • Free to read, no account
On this page
  1. Why interviewers ask this
  2. The idea in plain words
  3. Pause and predict
  4. Worked example
  5. Trade-offs
  6. Common misconceptions
  7. How to say it in the interview
  8. Check your understanding
  9. Answers
  10. Sources

What you need first

This lesson uses ideas from these earlier lessons. Read them first if any idea is new to you.

01Why interviewers ask this

In a machine-coding round (lesson 105) you get a short problem statement. The first 15 minutes go to class design. In Tradeoff's round, object design is worth 25 of 100 points, and extensibility is worth 20. Extensibility means how easily a new rule fits in.

A weak candidate starts to type code at once, and one big class grows. Another weak candidate makes a class for every word in the statement. A strong candidate finds the few classes that matter, says where each rule lives, and shows it in a small picture. When the new requirement comes, the strong candidate changes one place.

At SDE-1 level you should find sensible classes. At SDE-2 level you should also place each rule and handle the new requirement with a small change. At SDE-3 level you should say what you left out, and why.

02The idea in plain words

Before a shop is built, someone draws a floor plan. The plan lists the things in the shop: shelves, a counter and a cash box. It says who does what. Then someone walks one customer from the door to the exit, to check that nothing is missing. A class design is the same. You list the things, you say who does what, and you walk one use through it.

A class is a blueprint. It holds data and has actions. An object is one thing made from a class. An attribute is a piece of data that a class holds. A method is an action that a class can do. We use this statement for the whole lesson:

A library lends books to members. A member can hold at most 3 books at a time. A book must come back within 14 days of the day it is borrowed. A late return costs Rs 2 for each late day. The librarian adds books and members, and asks which books are out.

Assumption: each book id is one physical copy. The code is Python, as in lesson 106.

Step 1: nouns become classes, verbs become methods

Underline the nouns and the verbs. Then test each noun with five questions.

  1. Does it have its own data and its own rules? Then it is probably a class.
  2. Is it only a number or a piece of text, with no rules of its own? Then it is an attribute of another class.
  3. Is it a person or a system that uses your code? Then it is outside. It is not a class. Its actions become methods.
  4. Do two nouns have the same data and the same actions? Then they are one class.
  5. Is there a verb that carries its own data? It is a hidden noun, and it needs a class.
WordDecisionWhy
libraryclassthe front door. The caller talks to it. It holds the books and members
bookclasshas its own data: an id, a title, and whether it is out
memberclasshas its own data: the books held. It knows the limit
dayattributeonly a number
librarianoutsidea person who calls your code
late day, Rs 2a rulea number and a calculation, not a thing
loan (not in the text)class"borrow" carries data: which book, which member, which day, and the due day

The verbs are: lend (borrow), come back (return), add, and ask. They become methods.

Step 2: give each rule an owner

A rule belongs in the class that has the data the rule needs. If a rule needs data from two classes, it goes in the class that coordinates them.

RuleData it needsOwner
At most 3 books at a timethe books the member holdsMember
Due 14 days after borrowingthe borrow dayLoan
Rs 2 for each late daythe due day and the return dayLoan
Lend only if the book is in and the member is under the limitthe book's status, and the member's loansLibrary

Put each number in one place. If 14 appears in two methods and you change only one, the two methods disagree. In the code below, the numbers are constants at the top of the file.

Step 3: choose the relationships

Two kinds of link are common. Has-a: one object holds others. A library has members and books. A member has loans. Is-a: one class is a special kind of another class, which is inheritance. Use is-a only when lesson 106's substitution rule holds: a child works wherever its parent works. Most of the time, has-a is the safer choice.

Links also have numbers. One library has many members. One member has many loans. One loan has one book.

Step 4: a class diagram

The Unified Modeling Language (UML) is a standard way to draw a design. You need only two of its pictures. A class diagram shows the classes and the links between them. Each class is a box with three parts: the name, what it holds, and what it does. A plain line between two boxes means "knows about", with a number at each end: 1 for one and * for many. A line with a hollow triangle at one end means "is a".

On paper, you draw boxes. In this lesson, a table has the same three parts:

ClassHoldsDoes
Librarybooks, membersadd_book, add_member, borrow, give_back
Membermember_id, name, loanscan_borrow
Loanbook, due_dayfine
Bookbook_id, title, is_outnone

The lines are:

  • Library 1 to * Member
  • Library 1 to * Book
  • Member 1 to * Loan
  • Loan * to 1 Book

Keep the diagram rough, and finish it in about five minutes. Do not draw every small method. The interviewer will run your code, not read your picture.

Step 5: a sequence diagram

A sequence diagram shows one use, step by step, as messages from one object to another in time order. Draw only the uses that carry rules. Here is borrow, on day 10:

  1. Caller to Library: borrow member M1, book B1, day 10.
  2. Library to Book: is_out? The answer is no.
  3. Library to Member: can_borrow? The answer is yes.
  4. Library to Loan: create a loan with due day 10 + 14 = 24.
  5. Library to Book: mark it out. Library to Member: add the loan.
  6. Library to Caller: here is the loan.

Each arrow must be a method or a field that exists. If an arrow goes to the wrong class, a rule is misplaced. If one class sends or receives most arrows, it is doing too much.

Step 6: handle a changed requirement

The interviewer now adds a new requirement. Do five things:

  1. Say it in one sentence.
  2. Use the diagram to find which classes own the rules that change.
  3. If the change is only a number, change it in its one place.
  4. If the rule now depends on a kind, turn the numbers into a small class and pass it in (lesson 106, dependency inversion). Do not copy the code for each kind.
  5. Update the diagram and run the tests again.

Stuck on something? The AI tutor has read this lesson. Ask it with a free account

03Pause and predict

Pause. Guess first.

The interviewer adds a new requirement to the library statement: "Premium members can hold 5 books for 21 days." Look at the table of rule owners above. Which rules change, and which class owns each one? Does the fine rule change?

Write your guess before you read on. The answer is in the worked example.

04Worked example

The table in Step 1 chose four classes: library, book, member, and the hidden noun, the loan. Day is an attribute, and the librarian is outside. Here is the first version. The numbers are constants, each in one place.

python
MAX_BOOKS = 3
LOAN_DAYS = 14
FINE_PER_DAY = 2

class Book:
    def __init__(self, book_id, title):
        self.book_id, self.title, self.is_out = book_id, title, False

class Loan:
    def __init__(self, book, borrowed_day):
        self.book = book
        self.due_day = borrowed_day + LOAN_DAYS

    def fine(self, return_day):
        late_days = max(0, return_day - self.due_day)
        return late_days * FINE_PER_DAY
python
class Member:
    def __init__(self, member_id, name):
        self.member_id, self.name, self.loans = member_id, name, []

    def can_borrow(self):
        return len(self.loans) < MAX_BOOKS

class Library:
    def __init__(self):
        self.books, self.members = {}, {}

    def add_book(self, book):
        self.books[book.book_id] = book

    def add_member(self, member):
        self.members[member.member_id] = member
python
    # more methods of Library
    def borrow(self, member_id, book_id, day):
        member, book = self.members[member_id], self.books[book_id]
        if book.is_out or not member.can_borrow():
            return None
        loan = Loan(book, day)
        book.is_out = True
        member.loans.append(loan)
        return loan

    def give_back(self, member_id, book_id, day):
        member = self.members[member_id]
        loan = next(l for l in member.loans if l.book.book_id == book_id)
        member.loans.remove(loan)
        loan.book.is_out = False
        return loan.fine(day)

A run. Asha is member M1. She borrows book B1 on day 10. The due day is 10 + 14 = 24. She returns it on day 30. She is 30 - 24 = 6 days late, so the fine is 6 x 2 = Rs 12. Now she tries to borrow four books on day 10. The first three work, because the member holds fewer than 3 books each time. The fourth returns None.

The new requirement. The interviewer says: "Premium members can hold 5 books for 21 days." We follow the five steps.

  1. In one sentence: the limit and the days now depend on the member's plan.
  2. In the diagram, the limit is in Member.can_borrow and the days are in Loan. The fine rule stays the same, because it still uses only the due day and the return day, at Rs 2 for each late day. This answers the predict box: two rules change, owned by Member and Loan, and the fine rule does not change.
  3. Both are numbers that now depend on a kind, so we turn them into a small class and pass it in.
python
class Plan:
    def __init__(self, max_books, loan_days):
        self.max_books, self.loan_days = max_books, loan_days

STANDARD = Plan(3, 14)
PREMIUM = Plan(5, 21)

The member holds a plan. The loan receives its days. These are all the changes:

  • Loan.__init__ takes loan_days, and due_day uses it: 2 changed lines.
  • Member.__init__ takes and stores plan: 2 changed lines.
  • can_borrow returns len(self.loans) < self.plan.max_books: 1 changed line.
  • In Library.borrow, the line becomes loan = Loan(book, day, member.plan.loan_days): 1 changed line.
  • The constants MAX_BOOKS and LOAN_DAYS are removed: 2 removed lines. Plan and the two plans are 5 new lines.

That is 6 changed lines in total. Book, fine, add_book, add_member and give_back do not change. The diagram gets one new box, Plan, with a line from Member.

The same run, now with a premium member. Asha borrows on day 10. The due day is 10 + 21 = 31. She returns on day 30, which is before the due day, so the fine is Rs 0. She can borrow 5 books in a row, and the sixth returns None.

05Trade-offs

  • Planning classes first solves the risk of a code shape that cannot change. It costs minutes: about 15 of the 75 in lesson 105. I would start with code when the problem is very small, or when the interviewer asks to see code first.
  • A diagram solves a shared picture, and it shows a misplaced rule before you write code. It costs time. I would keep it rough, and draw only the class diagram and the one or two uses that carry rules.
  • Many small classes solve change. They cost reading time, because each class is one more place to look. I would stop when a class would hold only one number and have no rule of its own.

06Common misconceptions

"Every noun in the statement becomes a class." Day is only a number. The librarian is a person who uses the code. Late day and Rs 2 are a rule. A class for each of them adds files and teaches the reader nothing.

"Standard and premium members look alike, so I make two child classes of Member." They differ only in two numbers. Numbers are data, so one Member that holds a Plan is enough. A new kind of member is then a new Plan value, not a new class. Use is-a only when a child can stand in for its parent everywhere (lesson 106).

"The UML diagram is what gets scored, so it must be complete and exact." The round runs your code. In Tradeoff's scoring, object design and working code are worth 25 points each. The diagram is a thinking tool. A rough diagram that finds the right owner for each rule is enough.

07How to say it in the interview

Say it like this

I underline the nouns and verbs, keep as classes only things with their own data and rules, and put each rule in the class that owns its data. When a requirement changes, I find the class that owns that rule and change only that.

08Check your understanding

  1. Name three kinds of noun that should not become a class. Give one example of each from the library statement.
  2. In the library code, a member borrows a book on day 3 and returns it on day 30. What is the fine for a standard member (14 days) and for a premium member (21 days)? The fine is Rs 2 for each late day.
  3. A candidate designs snake and ladder with the classes Board, Cell, Player, Dice, Snake and Ladder. Snake and Ladder are two child classes, and each holds a start cell and an end cell. Cell holds only a number. The interviewer then adds a crocodile that sends a player back 3 cells. What is wrong with the design, and how do you add the crocodile?

09Answers

Show the answers
  1. A noun that is only a number or text: day. A person or system outside your code: librarian. A rule or calculation: late day and Rs 2 (the fine rule belongs in Loan).
  2. Standard: the due day is 3 + 14 = 17. Late days are 30 - 17 = 13. The fine is 13 x 2 = Rs 26. Premium: the due day is 3 + 21 = 24. Late days are 30 - 24 = 6. The fine is 6 x 2 = Rs 12.
  3. Snake and Ladder have the same data, a start and an end. They have the same action: move the player from the start to the end. So they are one class, for example Jump. A snake is a Jump whose end is lower than its start, and a ladder is a Jump whose end is higher. Cell holds only a number, so it should be an attribute, not a class. The crocodile is a new Jump object. For a crocodile on cell 40, the start is 40 and the end is 37. No new class and no change to old code are needed.

10Sources

  • The Unified Modeling Language, with its class diagrams and sequence diagrams: Object Management Group, UML 2.5.1, December 2017, https://www.omg.org/spec/UML/2.5.1/About-UML (opens in a new tab) (checked 20 Oct 2026).
  • The 15-minute class design step, the 75-minute round and the weights of 25 for object design and 20 for extensibility come from Tradeoff's own round (lesson 105). Other companies use other rules.
  • The library statement, the numbers and the plans are made up for teaching. The code was run with Python 3.

Try it now, no sign-up

More practice, in the app (free account)

Ask the AI tutor about this lesson

The tutor has read this lesson. Ask in your own words, any time. Free account, 20 questions a day.

Reading never needs an account. The account is for the tutor, the quiz, your notes and your progress.

All lessons in Module 17: Low-level design and machine coding