Skip to main content

Value Object : All fields should be final/read-only

Medium
DDD

Value Objects are classes annotated with [ValueObject].

If your fields are not read-only and you update the fields, maybe it's an entity.

If your fields are not read-only and you don't update the fields, your fields have to be read-only.

Violations are raised on class fields that are not readonly but are never written, excepting in Constructors.

Examples

Example 1:

Negative

Incorrect implementation that violates the practice.

namespace Practices.DDD.ValueObject.AllReadOnly
{
[ValueObject]
public class ValueObject
{
private int _someProperty;
private readonly int _anotherProperty;

public ValueObject(int someProperty, int anotherProperty)
{
_someProperty = someProperty;
_anotherProperty = anotherProperty;
}


public int SomeProperty
{
get => _someProperty;
set => _someProperty = value;
}

public int AnotherProperty => _anotherProperty;
}
}

Example 2:

Positive

Correct implementation following the practice.

namespace Practices.DDD.ValueObject.AllReadOnly
{
[ValueObject]
public class ValueObject
{
private readonly int _someProperty;
private readonly int _anotherProperty;

public ValueObject(int someProperty, int anotherProperty)
{
_someProperty = someProperty;
_anotherProperty = anotherProperty;
}

public int SomeProperty => _someProperty;
public int AnotherProperty => _anotherProperty;
}
}

Negative

Incorrect implementation that violates the practice.

namespace Practices.DDD.ValueObject.AllReadOnly
{
[ValueObject]
public class ValueObject
{
private int _someProperty;
private readonly int _anotherProperty;

public ValueObject(int someProperty, int anotherProperty)
{
_someProperty = someProperty;
_anotherProperty = anotherProperty;
}

public int SomeProperty => _someProperty;
public int AnotherProperty => _anotherProperty;
}
}