Two customers with the same name are different customers; two amounts of 49.00 TRY are the same amount. That distinction decides equality, mutability and whether the thing needs a database row.
// value object: equal by value, immutable, no id
final class Money
{
public function equals(Money $other): bool
{
return $this->cents === $other->cents
&& $this->currency === $other->currency;
}
}
// entity: equal by identity, changes over time
final class Customer
{
public function equals(Customer $other): bool
{
return $this->id->equals($other->id);
}
}
Most things modelled as entities are value objects that were given an id because the ORM wanted one. An address is the common example: two identical addresses are the same address, and treating it as an entity produces update logic where a replacement would do. Value objects being immutable is what makes them safe to share, which is most of their practical benefit.