Search code examples
flutterfreezedflutter-freezed

when to implements an abstract class in freezed?


I need to understand this code, resoCoder did it on DDD Playlist. why does he implements IEntity inside freezed?

The code is:

@freezed
abstract class TodoItem with _$TodoItem implements IEntity {
  const factory TodoItem({
    @required UniqueId id,
    @required TodoName name,
    @required bool done,
  }) = _TodoItem;

  factory TodoItem.empty() => TodoItem(
        id: UniqueId(),
        name: TodoName(''),
        done: false,
      );
}
}

IEntity code is:

abstract class IEntity {
  UniqueId get id;
}

UniqueId Code is:

class UniqueId extends ValueObject<String> {
  @override
  final Either<ValueFailure<String>, String> value;

  // We cannot let a simple String be passed in. This would allow for possible non-unique IDs.
  factory UniqueId() {
    return UniqueId._(
      right(Uuid().v1()),
    );
  }

  /// Used with strings we trust are unique, such as database IDs.
  factory UniqueId.fromUniqueString(String uniqueIdStr) {
    assert(uniqueIdStr != null);
    return UniqueId._(
      right(uniqueIdStr),
    );
  }

  const UniqueId._(this.value);
}

Solution

  • It ensures consistency; TodoItem must implement everything as per IEntity.

    Let's imagine one day you want to add an attribute "createdAt" to IEntity: in this case, you will have to add "createdAt" to every class that implements IEntity across the project, otherwise the compiler will let you know you're missing something :D


    Some code now.

    The result would be

    abstract class IEntity {
      UniqueId get id;
      int get createdAt; // let's keep it "int" for the example purpose
    }
    

    then you would have to update the freezed class too

    @freezed
    abstract class TodoItem with _$TodoItem implements IEntity {
      const factory TodoItem({
        @required UniqueId id,
        @required int createdAt,
        @required TodoName name,
        @required bool done,
      }) = _TodoItem;
    
      factory TodoItem.empty() => TodoItem(
            id: UniqueId(),
            createdAt: 1234,
            name: TodoName(''),
            done: false,
          );
    }
    }