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);
}
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,
);
}
}