A Class Diagram Holds Objects, Not IDs

Why a refund is just another payment instead of a new class, and the rule that a class diagram references real objects, leaving IDs to the schema layer.

August 31, 20262 min read13 / 25

Payment picks up its last few attributes here: which gateway handled it, when it happened, a third-party reference ID for that transaction, and a status, arguably the most important field on the whole class. Ticket gets a status too, since a ticket can be cancelled or refunded after the fact.

A Refund Is Just Another Payment, Not a New Class

Here's a clean payoff of Ticket holding a list of payments instead of one: a refund doesn't need its own class at all. It's just another entry in that same list, marked with a type field distinguishing a payment from a refund. Split a booking across a wallet, a coupon, a card, and later refund part of it, and every one of those events lives in the exact same list, told apart only by that one field.

A Class Diagram Holds Objects, Not IDs

Here's a mix-up worth clearing up directly. When Ticket needs to reference the payment made against it, the class diagram shows a Payment object as that attribute, not a paymentId field.

The ID only shows up once persistence enters the picture. An ORM is what turns that object reference into an actual foreign key column when it maps a class to a table.

A class diagram describes relationships between real entities. The ID is a schema-level detail, not something that belongs on the diagram itself.

One Last Reason SeatType Isn't a String

One more angle worth closing the loop on, since the question keeps resurfacing. If SeatType were a string, "VIP" on one show and "VIP" on another are just two pieces of text that happen to match, with nothing actually connecting them.

As a class, both mappings point at the exact same row, so renaming or fixing it happens once, not once per place the string got typed out. It's the same redundancy problem from before, just showing up in a name this time instead of a price.

Language turns out to be a plain enum for the same reason seat features are: the real-world set of languages is closed enough that BookMyShow can safely hardcode it, the way it does for AuditoriumFeature, rather than letting anyone invent one, the way theatres can with SeatType.

That closes out the physical structure and the user journey both. Every entity, every attribute, and every relationship in this design now has a reason behind it, which is exactly what schema design needs to start from.