Modddels
HomeGithubPub.dev
v0.2
v0.2
  • Motivation
  • Setup
  • Generalities
    • Modddels Overview
    • Validations & Validation steps
    • Structure of a Modddel
    • Member parameters & Dependency parameters
    • Usage
      • Data equality & toString
      • Pattern matching
      • Reading the fields
      • Reading the failures
      • CopyWith
  • ValueObjects
    • ValueObjects Overview
    • Creating a ValueObject
  • Entities
    • Entities Overview
    • ContentValidation & ContentFailure
    • ValidationSteps in Entities
    • SimpleEntity
      • Creating a SimpleEntity
      • Special Cases
    • IterableEntity & Iterable2Entity
      • IterableEntity / Iterable2Entity kinds
      • The Type Template
      • Creating an IterableEntity / Iterable2Entity
      • InvalidMembers Description
      • Special Cases
      • Creating your own IterableEntity / Iterable2Entity kind
  • Advanced Notions
    • The NullFailure Annotation
    • Using multiple parameters annotations
    • Class Hierarchy of ValueObjects
    • Class Hierarchy of Entities
    • Models that are always valid / invalid
  • Union of Modddels
    • Union of Modddels Overview
    • Basic Usage
    • Case-modddels pattern matching
    • Default Factory Constructor
    • Shared Properties
    • The Validate Methods
    • CopyWith
  • Unit-Testing Of Modddels
    • Unit-Testing Overview
    • Available Tests
    • Customizing Tests
  • Additional Information
    • Using type aliases
    • Re-running the generator
    • All Available Modddels
    • VsCode Snippets
Powered by GitBook
On this page
  • Models that are always valid
  • Models that are always invalid
  1. Advanced Notions

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.

PreviousClass Hierarchy of EntitiesNextUnion of Modddels Overview