Hospital System OOD: Stop Modeling IDs—Model Relationships

bugfree.ai is an advanced AI-powered platform designed to help software engineers master system design and behavioral interviews. Whether you’re preparing for your first interview or aiming to elevate your skills, bugfree.ai provides a robust toolkit tailored to your needs. Key Features:
150+ system design questions: Master challenges across all difficulty levels and problem types, including 30+ object-oriented design and 20+ machine learning design problems. Targeted practice: Sharpen your skills with focused exercises tailored to real-world interview scenarios. In-depth feedback: Get instant, detailed evaluations to refine your approach and level up your solutions. Expert guidance: Dive deep into walkthroughs of all system design solutions like design Twitter, TinyURL, and task schedulers. Learning materials: Access comprehensive guides, cheat sheets, and tutorials to deepen your understanding of system design concepts, from beginner to advanced. AI-powered mock interview: Practice in a realistic interview setting with AI-driven feedback to identify your strengths and areas for improvement.
bugfree.ai goes beyond traditional interview prep tools by combining a vast question library, detailed feedback, and interactive AI simulations. It’s the perfect platform to build confidence, hone your skills, and stand out in today’s competitive job market. Suitable for:
New graduates looking to crack their first system design interview. Experienced engineers seeking advanced practice and fine-tuning of skills. Career changers transitioning into technical roles with a need for structured learning and preparation.
Hospital System OOD: Stop Modeling IDs—Model Relationships

Too many designs start by naming fields: patientID, staffID, appointmentID. Those are storage details, not domain concepts. In object-oriented design (OOD) — especially in interviews — model the relationships and business rules first. Let IDs be an implementation detail you add only after you understand ownership, lifecycle, and invariants.
The principle
Design around domain relationships and responsibilities, not around unique identifiers. A relationship-first model forces you to answer important questions:
- Who owns what? (ownership)
- When can something be created/removed? (lifecycle)
- What rules must always hold? (invariants)
Once those are clear, tables and APIs follow trivially.
Common relationships in a hospital system
- Patient has many Appointments
- Staff (doctors, nurses) has many Appointments
- Patient has many MedicalRecords
- Patient has many Bills
- Appointment references exactly one Patient and exactly one Staff
Modeling these explicitly makes you define ownership: e.g., MedicalRecord is conceptually owned by a Patient (who can have multiple records); an Appointment is a relationship between a Patient and Staff with its own lifecycle.
Example invariants and lifecycle rules
- Appointment must reference exactly one Patient and one Staff.
- Appointment status transitions: Scheduled → (Completed | Cancelled). Some transitions may be forbidden (e.g., Completed → Scheduled).
- MedicalRecord entries are append-only; edits require explicit amendment records or versioning.
- A Bill belongs to a Patient; payment state transitions (Unpaid → PartiallyPaid → Paid) should be explicit.
Explicitly listing these invariants helps you reason about validation, transactions, and concurrency.
From relationships to APIs and tables (an approach)
- Draw the domain relationships (boxes + lines). Annotate multiplicities and ownership.
- For each entity, define lifecycle events and allowed state transitions.
- Implement business logic in domain methods that enforce invariants.
- Map to persistence: add IDs and foreign keys to represent relationships.
- Expose REST/GraphQL APIs that mirror domain operations rather than raw CRUD on IDs.
Example pseudo-classes (conceptual):
class Patient
- name
- contactInfo
- appointments: List
- medicalRecords: List
class Staff
- name
- role
- appointments: List
class Appointment
- patient: Patient
- staff: Staff
- scheduledAt
- status // Scheduled, Completed, Cancelled
- reschedule(newTime) { / validate transitions / }
- complete() { / set status and enforce rules / }
And the persistence mapping is straightforward once relationships are clear:
appointments table
- id
- patient_id -- FK to patients
- staff_id -- FK to staff
- scheduled_at
- status
medical_records table
- id
- patient_id
- record_data
- created_at
bills table
- id
- patient_id
- amount
- status
Note: IDs appear here as implementation details (primary keys / foreign keys), but your domain design should have been done before you decide on these columns.
Interview tips
- Start by drawing relationships, not tables. Use boxes for aggregates and arrows for ownership.
- Call out invariants and allowed state transitions on your diagram.
- Describe who owns deletion rights: can a Patient be deleted? What happens to their MedicalRecords and Bills?
- Explain how your domain methods enforce invariants (do not rely solely on DB constraints).
- Only after the model is clear, sketch the APIs and persistence schema.
Benefits of this approach
- Clearer reasoning about business rules, ownership, and consistency.
- Fewer surprises when you implement workflows or enforce validation.
- APIs that reflect real use cases (e.g., cancelAppointment(patient, appointmentId) instead of deleteById).
- Easier to spot transactional boundaries and concurrency issues.
Summary
Stop leading with IDs. Model relationships, lifecycles, and invariants first. Once the domain is explicit, IDs, tables, and APIs are just a straightforward mapping from that model.
#ObjectOrientedDesign #SystemDesign #SoftwareEngineering

