Value Object
A Value Object is an immutable domain concept defined only by its value, not by identity.
✅ Represents small, meaningful concepts (e.g., Email, Address, Money).
✅ Two value objects with the same data are considered equal.
✅ Encapsulates validation and domain logic inside the object.
What is a Value Object?
Section titled “What is a Value Object?”A value object:
- Has no unique ID.
- Is fully defined by its properties.
- Is immutable: once created, its value does not change.
Example:
const email1 = new Email('test@example.com');const email2 = new Email('test@example.com');
email1.equals(email2); // ✅ true
✅ You can safely compare or replace value objects without worrying about identity.
Value Object Setup in DomusJS
Section titled “Value Object Setup in DomusJS”DomusJS provides a generic ValueObject
base class you can extend.
✅ Handles equality checks (equals
).
✅ Enforces immutability.
✅ Lets you encapsulate domain-specific validation.
ℹ️ Note:
Always validate inputs inside the value object to avoid invalid states.
Example Use Case: Email Value Object
Section titled “Example Use Case: Email Value Object”import { ValueObject } from '@domusjs/core';
interface EmailProps { value: string;}
export class Email extends ValueObject<EmailProps> { private constructor(props: EmailProps) { super(props); }
static create(email: string): Email { if (!email.includes('@')) { throw new Error('Invalid email format'); } return new Email({ value: email }); }
get value(): string { return this.props.value; }}
✅ This guarantees every Email
instance is valid by construction.
Core Interfaces
Section titled “Core Interfaces”ValueObject
Section titled “ValueObject”export abstract class ValueObject<T> { protected readonly props: T;
constructor(props: T) { this.props = Object.freeze(props); }
equals(vo?: ValueObject<T>): boolean { if (vo === null || vo === undefined) return false; return JSON.stringify(this.props) === JSON.stringify(vo.props); }}
✅ Provides built-in equality comparison and immutability.
Best Practices
Section titled “Best Practices”✅ Use value objects for concepts where only the value matters.
✅ Always validate inputs inside the value object (not in services or controllers).
✅ Keep value objects small and focused — they should not manage behaviors across multiple entities.
✅ Avoid adding identity (IDs) — that’s the role of entities.