Models that are always valid / invalid
Models that are always valid
Sometimes, you may want to create a model that is always valid. Such model is not a modddel, because the latter by definition should have both a valid and an invalid state.
As an alternative, you can create a dataclass that implements ValidValueObject
or ValidEntity
.
Example 1 : Creating a ValidValueObject
using Freezed
@freezed
class ValidId with _$ValidId implements ValidValueObject {
const factory ValidId(String id) = _ValidId;
}
Example 2 : Creating a ValidEntity
using Freezed
@freezed
class ValidPerson with _$ValidPerson implements ValidEntity {
const factory ValidPerson({
required ValidFullName validFullName,
required bool isAdult,
}) = _ValidPerson;
}
While implementing ValidEntity
or ValidValueObject
doesn't offer any extra functionality to these dataclasses, it is a good practice to do so because it makes your code and intentions clear. It is also a good practice to start the names of these dataclasses with "Valid"
.
NB 1 : You can use whatever approach you want to make these dataclasses (Freezed, Equatable...).
NB 2 : When using the dataclass as a parameter inside an
Entity
, don't forget to annotate the parameter with@validParam
.
Models that are always invalid
Sometimes, you may want to create a model that is always invalid. Such model is not a modddel, because the latter by definition should have both a valid and an invalid state.
As an alternative, you can create a dataclass that implements InvalidValueObject
or InvalidEntity
, and then override the failures
getter.
Example 1 : Creating an InvalidValueObject
using Freezed.
@freezed
class InvalidId with _$InvalidId implements InvalidValueObject {
const factory InvalidId(String id) = _InvalidId;
const InvalidId._();
/// These are the failures that [InvalidId] holds
@override
List<ValueFailure> get failures => [const IdFailure.invalid()];
}
@freezed
class IdFailure extends ValueFailure with _$IdFailure {
const factory IdFailure.invalid() = _Invalid;
}
Example 2 : Creating an InvalidEntity
using Freezed.
In this example, we would like to have an Entity that would always be invalid, because it holds a non-nullable invalid parameter invalidId
.
@freezed
class InvalidPerson with _$InvalidPerson implements InvalidEntity {
const factory InvalidPerson({
required InvalidId invalidId,
required Username username,
}) = _InvalidPerson;
const InvalidPerson._();
/// [InvalidPerson] always holds a ContentFailure. The invalidMembers are :
///
/// - [invalidId] because it's always invalid
/// - [username] only when it's invalid
@override
List<EntityFailure> get failures => [
ContentFailure([
ModddelInvalidMember(member: invalidId, description: 'invalidId'),
if (!username.isValid)
ModddelInvalidMember(
member: username as InvalidUsername, description: 'username'),
])
];
}
As you can see, you have full control over what failures
the invalid model holds. Just make sure the failures
getter never returns an empty list.
NB 1 : You can use whatever approach you want to make these dataclasses (Freezed, Equatable...).
NB 2 : When using the dataclass as a parameter inside an
Entity
, don't forget to annotate the parameter with@invalidParam
.
Last updated