0
0
LLDsystem_design~7 mins

User, Group, Expense classes in LLD - System Design Guide

Choose your learning style9 modes available
Problem Statement
When managing shared expenses among multiple people, tracking who owes what and how expenses are split can become confusing and error-prone. Without clear organization, users may miscalculate balances, and groups may lack proper structure to manage shared costs.
Solution
Create clear classes to represent Users, Groups, and Expenses. Users represent individuals, Groups organize users together, and Expenses record costs shared among group members. This structure helps track who paid, who owes, and how much, making expense management clear and maintainable.
Architecture
┌────────┐       ┌────────┐       ┌───────────┐
│  User  │──────▶│  Group │──────▶│  Expense  │
└────────┘       └────────┘       └───────────┘
     ▲               │                ▲
     │               │                │
     └───────────────┴────────────────┘

This diagram shows Users belonging to Groups, and Groups having multiple Expenses associated with them.

Trade-offs
✓ Pros
Clear separation of concerns: Users, Groups, and Expenses have distinct responsibilities.
Easy to extend: New features like expense splitting rules can be added without major changes.
Improves maintainability by organizing data logically.
✗ Cons
Initial setup requires careful design to handle relationships correctly.
May introduce complexity if groups or expenses have many edge cases.
Without proper validation, data inconsistencies can occur (e.g., user not in group but assigned expense).
Use when building applications that manage shared expenses among multiple users, especially when groups and multiple expenses need tracking.
Avoid if the system only involves single users with no grouping or shared expenses, as the added complexity is unnecessary.
Real World Examples
Splitwise
Uses User, Group, and Expense models to track shared bills and balances among friends and roommates.
Venmo
Manages users and groups to facilitate peer-to-peer payments and shared expense tracking.
Airbnb
Tracks users and groups for splitting rental costs and expenses among travelers.
Code Example
The before code mixes all data in dictionaries without clear structure, making it hard to manage. The after code defines User, Group, and Expense classes to organize data clearly. Group ensures only members can pay or participate in expenses, improving data integrity and maintainability.
LLD
### Before: No clear structure, all data mixed

expenses = [
    {"payer": "Alice", "amount": 100, "participants": ["Bob", "Charlie"]},
    {"payer": "Bob", "amount": 50, "participants": ["Alice"]}
]

# No clear user or group representation


### After: Using User, Group, Expense classes

from typing import List

class User:
    def __init__(self, user_id: int, name: str):
        self.user_id = user_id
        self.name = name

class Expense:
    def __init__(self, expense_id: int, amount: float, paid_by: User, participants: List[User]):
        self.expense_id = expense_id
        self.amount = amount
        self.paid_by = paid_by
        self.participants = participants

class Group:
    def __init__(self, group_id: int, name: str, members: List[User]):
        self.group_id = group_id
        self.name = name
        self.members = members
        self.expenses: List[Expense] = []

    def add_expense(self, expense: Expense):
        if expense.paid_by not in self.members:
            raise ValueError("Payer must be a group member")
        for participant in expense.participants:
            if participant not in self.members:
                raise ValueError("All participants must be group members")
        self.expenses.append(expense)

# Example usage
alice = User(1, "Alice")
bob = User(2, "Bob")
charlie = User(3, "Charlie")

friends = Group(1, "Friends", [alice, bob, charlie])

expense1 = Expense(1, 100.0, alice, [bob, charlie])
expense2 = Expense(2, 50.0, bob, [alice])

friends.add_expense(expense1)
friends.add_expense(expense2)
OutputSuccess
Alternatives
Flat Expense List
Stores all expenses in a single list without grouping users or organizing by groups.
Use when: Choose when the application is very simple with no need for grouping or complex user relationships.
Event-based Expense Tracking
Tracks expenses as events with participants instead of fixed groups and users.
Use when: Choose when expenses are tied to specific events rather than ongoing groups.
Summary
Organizing Users, Groups, and Expenses into classes helps manage shared costs clearly and reliably.
This structure supports tracking who paid and who owes within groups, improving data integrity.
Proper class design makes the system easier to extend and maintain as features grow.