SwadhyAI Notes

All Low-Level Design notes

Identity versus value

Entity vs value object

An entity has identity that stays the same as its attributes change. A value object is defined only by its fields — replace it rather than mutate it. Example: ticket T-1042 is still that ticket if the car moves to another spot. Twenty rupees is not “that particular twenty”; any other twenty rupees of the same currency is the same value. Mix those ideas and you get broken equals() and duplicate tickets.

Entity

An has . You track it over time. Ticket, ParkingSpot, Vehicle, Order, User. Two tickets with the same fee are not the same ticket. Compare them by id. The fee can change. The id does not.

  • Survives field changes.
  • Has a life: issued, paid, closed.
  • Usually stored and looked up later.
  • Equality uses a stable id only.

Value object

A is defined by its values. Money, Duration, Email, Coordinates, VehicleType. You can replace one with another that compares equal. They should be immutable. If you need a different amount, you create a new Money. You do not mutate the old one.

  • No life story. Only content.
  • Replace, do not mutate.
  • Validate once in the constructor.
  • Equality uses every field that defines the value.

The survival question

If I change the spot on this ticket, is it still the same ticket? Yes. Entity. If I change the paise on this Money, is it still the same money? No. It is a different value. You throw the old one away. That one question sorts almost every type in a machine-coding round.

Change the plate on Vehicle V?

Still that vehicle. Entity.

Change the hours on a Duration?

Different length. Value.

Change the occupant on a Spot?

Still that rectangle of concrete. Entity.

Change the local-part of an Email?

Different address. Value.

Change the fee on Ticket T-1042?

Same stay, new amount. Entity.

Change latitude on Coordinates?

Different point. Value.

Why the distinction is not academic

Machine-coding problems are full of value objects people store as primitives: double amount, String email, long startMs. That is . Fee bugs and invalid emails then leak into every class. The opposite mistake is treating two similar tickets as the same ticket because the car, the fee, and the spot type match. Same car, same fee, same spot type is still two stays if the ids differ.

Persistence follows the same split. An entity usually has a row and a primary key. A value object is a column, or a few columns, on that row — or a small embedded type. You do not give Money its own table and then wonder why twenty rupees has a foreign key. You also do not give Ticket only a fee field and then wonder why two stays collide in a HashSet.

Identity versus value in Java

TicketId is a tiny value that wraps the identity string so you do not pass raw strings around. Money is a value with rules. Ticket is the entity that holds both. The spot can change. The ticket is still T-1042.

java
final class TicketId {
  private final String value;

  TicketId(String value) {
    this.value = Objects.requireNonNull(value);
    if (value.isBlank()) throw new IllegalArgumentException("ticket id");
  }

  String value() { return value; }

  @Override public boolean equals(Object o) {
    return o instanceof TicketId id && value.equals(id.value);
  }

  @Override public int hashCode() { return value.hashCode(); }
}

final class Money {
  private final long paise;
  private final String currency;

  Money(long paise, String currency) {
    if (paise < 0) throw new IllegalArgumentException("paise");
    this.paise = paise;
    this.currency = Objects.requireNonNull(currency);
  }

  Money plus(Money other) {
    if (!currency.equals(other.currency)) {
      throw new IllegalArgumentException(currency + " vs " + other.currency);
    }
    return new Money(paise + other.paise, currency);
  }
}

class Ticket {
  private final TicketId id;     // entity identity — survives field changes
  private Money fee;             // value object — replace, do not mutate
  private SpotId spot;           // the ticket is still T-1042 if the spot changes

  void reassign(SpotId next) { this.spot = next; }

  void pay(Money amount) { this.fee = amount; }
}

Replace values

fee = fee.plus(tax) creates a new Money. The old one is gone. That is doing its job.

Keep entity ids stable

Never rebuild TicketId on every save. Never hash the spot. Read equality and identity for the HashSet failure.

Freeze the value

Final fields. No setters. Constructor checks. Then every caller can trust Email and Money.

Primitive obsession in the wild

The fee is stored as double. Three hours at 12.50 should be 37.50. The receipt prints 37.499999. The gate rounds the wrong way. The driver argues. The interviewer already knows what you did. The same story happens with String email that nobody validated, and long duration that might be millis or seconds depending on who wrote the caller.

Wrap the idea once. Then common value objects — Money, Duration, Email, Quantity — become the vocabulary of the model. A rich model can protect them. Anemic models leave them as public fields and hope a service remembers the rules.

A short interview table

TypeKindWhy
TicketEntitySame stay after fee and spot change
TicketIdValueThe identity string, validated once
MoneyValuePaise + currency; replace on change
ParkingSpotEntityThat bay exists after occupant leaves
SpotTypeValueCOMPACT is COMPACT; no life story
UserEntitySame person after email change — or Email is a value on the user
DurationValueNinety minutes is ninety minutes
Expense (Splitwise)EntityThat dinner is still that dinner after splits change

When a type sits on the fence

Vehicle is usually an entity: that car, that plate, that stay. In a toy problem where you never look the vehicle up again, some candidates treat plate-plus-size as a value. Either choice is fine if you say it. What is not fine is hashing Vehicle by plate in one class and by reference in another. Pick the story and keep it.

Address is the classic fence. If the user “has an address” and you replace the whole thing when they move, it is a value. If you track that apartment over time — occupancy, meters, complaints — it is an entity. The same words in English. Different jobs in the model. Ask whether you will point at the same one tomorrow after the fields change.

How to explain this in an interview

“Ticket is an entity: identity survives the fee. Money is a value: integer paise, immutable, compared by content. I will not store fee as double.” That sentence is worth more than a UML legend. Then implement equals the way the domain thinks — id for entities, fields for values — and keep values frozen so hash codes do not move.

Identity, equality, comparisonMoney, Duration, EmailRich versus anemicImmutability