ValueObjects in DDD

In this example, Money is a Value Object representing an amount of money with a currency. Here's why it's a Value Object:

  
    


public class Money : IEquatable
{
    // Properties
    public decimal Amount { get; }
    public string Currency { get; }

    // Constructor
    public Money(decimal amount, string currency)
    {
        Amount = amount;
        Currency = currency;
    }

    // Equality check
    public bool Equals(Money other)
    {
        if (ReferenceEquals(null, other)) return false;
        if (ReferenceEquals(this, other)) return true;
        return Amount == other.Amount && Currency == other.Currency;
    }

    public override bool Equals(object obj)
    {
        return Equals(obj as Money);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            return (Amount.GetHashCode() * 397) ^ Currency.GetHashCode();
        }
    }
}


 

Immutable: The properties of Money are read-only, and there are no methods to change them after creation. This ensures that once a Money object is created, its state cannot be modified.

Equality: Implementations of Equals and GetHashCode methods are provided to ensure proper value-based equality comparisons. This is crucial because value objects are compared based on their attribute values rather than references.

Self-Contained: A Value Object should be self-contained, meaning it encapsulates all the data it needs to represent its concept. In this case, Money encapsulates both the amount and the currency.

Value Objects are used extensively within DDD to represent concepts such as money, dates, addresses, and other types that are defined by their attributes. They help to make domain models more expressive and maintainable by encapsulating behaviors and enforcing domain rules within the object itself.

Comments