【Flutter】Entityクラスをfreezedで実装した
カテゴリー:Flutter投稿日:2024-02-04
riverpodやNavigation2.0が難しすぎてfreezedもちょっと敬遠していたけどすご簡単で使いやすかったのでメモ。
freezed使用前
class Task {
int? id;
String title;
String? description;
bool isComplete;
int point;
TaskType taskType;
DateTime? atComplete;
Task({
this.id,
required this.title,
this.description,
required this.isComplete,
required this.point,
required this.taskType,
this.atComplete,
});
Map<String, dynamic> toMap() {
return {
'id': id,
'title': title,
'description': description,
'isComplete': isComplete ? 1 : 0,
'point': point,
'taskType': taskType.index,
'atComplete': atComplete?.toIso8601String(),
};
}
factory Task.fromMap(Map<String, dynamic> map) {
return Task(
id: map['id'] as int?,
title: map['title'] as String,
description: map['description'] as String?,
isComplete: map['isComplete'] == 1,
point: map['point'] as int,
taskType: TaskType.values[map['taskType'] as int],
atComplete: map['atComplete'] == null
? null
: DateTime.parse(map['atComplete'] as String),
);
}
}
freezed使用後
part "task.freezed.dart";
part "task.g.dart";
@freezed
class Task with _$Task {
const factory Task({
int? id,
required String title,
String? description,
@BoolIntConverter() @Default(false) bool isComplete,
required int point,
@TaskTypeConverter() required TaskType taskType,
DateTime? atComplete,
}) = _Task;
factory Task.fromJson(Map<String, dynamic> json) => _$TaskFromJson(json);
}
圧倒的省エネ。やることもpartを使って自動生成されるコードの指定。@freezedをつけるぐらい。enumとかで(デ)シリアライズに特有の処理をしたかったらconverterを実装するだけ。そのconverterも実装はすごい簡単。
class TaskTypeConverter implements JsonConverter<TaskType, int> {
const TaskTypeConverter();
@override
TaskType fromJson(int json) {
return TaskType.values[json];
}
@override
int toJson(TaskType object) {
return object.index;
}
}
class BoolIntConverter implements JsonConverter<bool, int> {
const BoolIntConverter();
@override
bool fromJson(int json) {
return json == 1;
}
@override
int toJson(bool object) {
return object ? 1 : 0;
}
}
最初にriverpodやNavigationに手を出していたせいでfreezedもややこしそうとか思っていたけどなんのことはなく超シンプル。導入していなかった自分を殴りたいぐらい。Flutterでプロジェクト作る時はとりあえず入れとけばいいんじゃないかな?