0

Entity — an object with identity that persists over time

Intermediate5 min read·eng-16-015
interviewcompare

Concept

Entity — in Domain-Driven Design (DDD), an object that has a distinct identity that persists over time and across different representations.

Defined by identity, not attributes: If I rename "Alice" to "Alicia," she's still the same person — same identity, different attributes. If I copy her profile and make a new account with the same details, it's a DIFFERENT person — same attributes, different identity.

Entity vs Value Object:

  • Entity: Identity matters. Two entities with the same attributes are still different entities if they have different IDs. User(id=1, name='Alice')User(id=2, name='Alice').
  • Value Object: Identity doesn't matter. Two value objects with the same attributes ARE the same thing. Money(100, 'USD') == Money(100, 'USD') — they're equal.

Entity lifecycle: Entities are created, change over time, and are eventually deleted. They have a continuous identity through all those changes.

In PHP (Eloquent model as Entity): An Eloquent model with a primary key id is an entity in the DDD sense. The id is the identity. Two User models with the same id represent the same entity.

Aggregate root: In DDD, an entity that serves as the single entry point for a cluster of objects. Order is an aggregate root. OrderItem entities live inside the Order aggregate — you don't manipulate OrderItems directly, only through the Order.

Entity identity in PHP: Entities are compared by their identity (ID), not by value. $user1->is($user2) in Eloquent — checks if two models represent the same row.

Code Example

php
<?php
// ENTITY — identity matters
class User
{
    public function __construct(
        public readonly int    $id,    // THE identity
        public string $name,
        public string $email,
    ) {}

    // Entities are equal when they have the SAME ID
    public function equals(self $other): bool
    {
        return $this->id === $other->id;
    }
}

$alice1 = new User(1, 'Alice', 'alice@example.com');
$alice2 = new User(1, 'Alice Smith', 'alice@work.com'); // different attributes, same ID
var_dump($alice1->equals($alice2)); // true — same identity

$alice3 = new User(2, 'Alice', 'alice@example.com'); // same attributes, different ID
var_dump($alice1->equals($alice3)); // false — different identity

// AGGREGATE ROOT — entry point for a cluster of entities
class Order // aggregate root
{
    private array $items = [];

    public function __construct(
        public readonly int $id,
        public readonly int $userId,
        private string      $status = 'pending',
    ) {}

    // ONLY manipulate items through the aggregate root
    public function addItem(int $productId, int $quantity, float $price): void
    {
        if ($this->status !== 'pending') {
            throw new \DomainException('Cannot add items to a non-pending order');
        }
        $this->items[] = new OrderItem($productId, $quantity, $price); // creates a child entity
    }

    public function total(): float
    {
        return array_sum(array_map(fn($i) => $i->subtotal(), $this->items));
    }

    public function confirm(): void
    {
        if (empty($this->items)) throw new \DomainException('Cannot confirm empty order');
        $this->status = 'confirmed';
    }
}

class OrderItem // child entity — exists within the Order aggregate
{
    public readonly int $id;
    public function __construct(
        public readonly int   $productId,
        public readonly int   $quantity,
        public readonly float $price,
    ) {}

    public function subtotal(): float { return $this->quantity * $this->price; }
}

// ELOQUENT ENTITY — Eloquent model is an entity
class User extends \Illuminate\Database\Eloquent\Model
{
    // $user->id is the identity
}

$user1 = User::find(1);
$user2 = User::find(1); // same row, different PHP object
$user1->is($user2); // true — same identity (same primary key)
$user1 === $user2;  // false — different PHP object references
// Eloquent's is() method is the correct way to compare entities