Skip to main content

Command Palette

Search for a command to run...

Value Objects in PHP

Published
•3 min read•View as Markdown

Value Objects in PHP

Introduction to Value Objects

In the realm of software development, particularly within the domain-driven design (DDD) paradigm, the concept of value objects plays a pivotal role. Unlike entities, which are defined by their unique identity, value objects are characterized by their attributes. In PHP, a value object is an object that represents a descriptive aspect of the domain with no conceptual identity. They are used to measure, quantify, or describe things in the domain. By treating these aspects as conceptual objects, developers can ensure higher data integrity and business logic consistency.

Why Use Value Objects in PHP

Immutability

One of the core benefits of value objects is their immutability. Once instantiated, value objects cannot be altered. This immutability is a safeguard against unintended side effects, making the code more predictable and easier to debug. In PHP, this is achieved by ensuring that no methods change the internal state of the object but instead return a new instance if a change is needed.

Validation

Value objects enforce validation rules internally, guaranteeing that the object never exists in an invalid state. This encapsulation of validation logic simplifies the code elsewhere, as the validity of the object need not be questioned once it's created.

Readability and Maintainability

By encapsulating related values and their operations within value objects, the code becomes more readable and maintainable. It shifts the focus from how things are implemented to what is being represented, aligning the code more closely with the business domain.

Reduces Primitive Obsession

Primitive obsession is a common anti-pattern where primitive data types are overused to represent domain concepts, leading to type errors and other bugs. Value objects mitigate this by encapsulating these primitives and their related operations, thus providing a more robust abstraction.

Implementing Value Objects in PHP

To illustrate the implementation of value objects in PHP, let's expand on the Money class example:

class Money
{
    private $amount;
    private $currency;

    public function __construct(float $amount, string $currency)
    {
        if ($amount < 0) {
            throw new InvalidArgumentException('Amount cannot be negative.');
        }
        $this->amount = $amount;
        $this->currency = $currency;
    }

    public function getAmount(): float
    {
        return $this->amount;
    }

    public function getCurrency(): string
    {
        return $this->currency;
    }

    public function add(Money $money): Money
    {
        if ($this->currency !== $money->getCurrency()) {
            throw new InvalidArgumentException('Currencies must match.');
        }

        return new Money($this->amount + $money->getAmount(), $this->currency);
    }
}

In this example, the constructor not only sets the properties but also enforces that the amount cannot be negative, ensuring the object is always in a valid state.

Ensuring Immutability

Immutability is crucial for the reliability of value objects. In the Money class, methods that could potentially modify the object, such as add, do not alter the original object. Instead, they produce a new instance with the updated value, preserving the original object's state.

Comparing Value Objects

Comparing value objects goes beyond mere reference equality. Since value objects are defined by their values, two value objects are considered equal if all their fields are equal. Implementing an equals method allows for this deep comparison:

public function equals(Money $other): bool
{
    return $this->amount === $other->getAmount() && $this->currency === $other->getCurrency();
}

Conclusion

Value objects are a powerful pattern in PHP and other object-oriented languages, offering a robust way to model the domain with precision and clarity. They promote immutability, encapsulate validation logic, enhance code readability, and help avoid primitive obsession. By incorporating value objects into your PHP projects, you can achieve more expressive, maintainable, and bug-resistant code.

More from this blog

Khang Nguyen

119 posts