Skip to content

Entity

An Entity is a domain object that has a unique identity that persists over time, even if its attributes change.

✅ Represents core business concepts (e.g., User, Order, Invoice).
✅ Identified by a unique ID (not just its attributes).
✅ Can encapsulate both data and behavior.


Unlike a value object (which is defined only by its value), an entity is defined by:

  • A unique identifier (e.g., UUID, database ID).
  • Its identity remains the same even if its properties change.

Example:

User(id=123, name="John")
User(id=123, name="Jane")

✅ Still the same user, just with updated attributes.


DomusJS provides an abstract Entity base class that helps:

✅ Track entity identity via UniqueEntityId.
✅ Encapsulate properties inside the entity.
✅ Implement rich domain behaviors.

ℹ️ Note:
Entities are core to domain-driven design (DDD) and often combine with Value Objects to express precise domain meaning.


import { Entity, UniqueEntityId } from '@domusjs/core';
import { Email } from './value-objects/email.vo';
interface UserProps {
email: Email;
password: string;
}
export class User extends Entity<UserProps> {
constructor(props: UserProps, id?: UniqueEntityId) {
super(props, id);
}
get email(): Email {
return this.props.email;
}
get password(): string {
return this.props.password;
}
changePassword(newPassword: string) {
this.props.password = newPassword;
}
}

✅ Ensures:

  • The user is always tracked by their unique ID.
  • Attribute changes (like password) do not change the entity’s identity.

export abstract class Entity<T> {
protected readonly _id: UniqueEntityId;
protected readonly props: T;
constructor(props: T, id?: UniqueEntityId) {
this._id = id || new UniqueEntityId();
this.props = props;
}
get id(): UniqueEntityId {
return this._id;
}
}
export class UniqueEntityId {
constructor(id?: string) { /* generates UUID if not provided */ }
toString(): string { /* returns the string representation */ }
}

✅ Use UniqueEntityId to assign or generate entity IDs consistently.


✅ Use entities when identity matters over time.
✅ Use value objects for pure value (e.g., money, email, coordinates).
✅ Avoid changing an entity’s id once set — the identity should be immutable.
✅ Encapsulate behaviors inside the entity (not just data containers).


Example: Relationship Between Entity and Value Object

Section titled “Example: Relationship Between Entity and Value Object”
const user = new User({
email: new Email('test@example.com'),
password: 'securepass',
});

✅ Here, the User entity contains an Email value object, combining identity with precise value modeling.