Skip to content

Value Objects

A Value Object is an immutable object that is defined by its value, not by identity.

Example:

  • Two emails "user@example.com" are equal if their value is equal, even if they are different instances.

Think of a €10 bill:

  • It doesn’t matter which specific paper you hold — €10 is €10.
  • The value is what matters, not the individual instance.

In contrast, a person is an entity — they have a unique identity, even if their name or attributes change.


import { ValueObject } from '@domusjs/core';
export class Email extends ValueObject<{ value: string }> {
private static readonly EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
private constructor(props: { value: string }) {
super(props);
}
get value(): string {
return this.props.value;
}
public static create(email: string): Email {
if (!this.EMAIL_REGEX.test(email)) {
throw new Error(`Invalid email format: ${email}`);
}
return new Email({ value: email });
}
}

✅ This ensures:

  • Emails are validated on creation.
  • Comparisons are done by value, not by reference.
  • They cannot be mutated after creation.

  • Encapsulate rules and validation → prevent invalid states.
  • Increase expressivenessEmail or Money is clearer than just string or number.
  • Immutability → once created, they never change.
  • Simpler comparisons → compare by value, not reference.

  • Avoid adding identifiers or mutable fields to value objects — that turns them into entities.
  • Keep them focused on representing a value with meaning, not behavior.