Freezed
でModel
を自動生成するとイミュータブル(状態を変えることができないオブジェクト)でスッキリしたコードを書くことができます。Model
クラスを作成するのにDartのMap
(Jsonのハッシュ)を単位毎に一つずつ作る必要があり、定義したあとjson_serializable
(コードジェネレータ)を走らせれば、JSON
のデコード処理
(fromJsonメソッド)とエンコード処理
(toJsonメソッド)によって自動生成が行われます。Json
の文字列をDart
のデータ型で扱うためにはただの文字列だと使えないのでデコードしてMap
のクラス型にする必要があります。実際にコードにして試してみたのがこちら!
コンストラクタ(メンバ変数を初期化する作業)やプロパティ(属性)を定義することに加え、
@override で上書きできるメソッド
// オブジェクトを文字列で表現してくれる。静的(parse)な関数int.parseなどが一緒になったクラスを文字列としてテキストに表現する
.toString()
// 二つの値を比較して等しければ「真」(true)を、等しくなければ「偽」(false)を返す
operator(演算子) == (等価演算子)
// オブジェクト毎に存在し、== で比較して同じであればtrueを返す
.hashCode
// nullを割り当てれるオブジェクトを複製できるメソッド
.copyWith
// Mapクラス内のjsonを解析してデコード処理
.fromJson
// Mapへのエンコード処理
.toJson
などのメソッドも一緒に定義できるので慣れてしまえばとても役に立つと思います。
必要なパッケージ
dependencies:
flutter:
sdk: flutter
freezed_annotation: ^X.X.X (freezedのアノテーション)
freezed: ^X.X.X
build_runner: ^X.X.X (コードジェネレーターの実行)
json_annotation: ^X.X.X
json_serializable: ^X.X.X (デコード・エンコードの処理)
生成したファイルと同じディレクトリに内に作成し警告を無くす処理
analyzer:
exclude:
- "**/*.g.dart"
- "**/*.freezed.dart"
errors:
invalid_annotation_target: ignore
コードジェネレーターでビルドするコマンド
Flutterプロジェクト
flutter pub run build_runner build
生成されたファイルが既に存在し、コンフリクトエラーになってしまう場合は
flutter pub run build_runner build --delete-conflicting-outputs
Dartプロジェクト
dart pub run build_runner build
ドキュメントにあるコードで検証
// This file is "main.dart"
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:flutter/foundation.dart';
// required: associates our `main.dart` with the code generated by Freezed
part 'test.freezed.dart';
// optional: Since our Person class is serializable, we must add this line.
// But if Person was not serializable, we could skip it.
part 'test.g.dart';
@freezed
class Person with _$Person {
const factory Person({
required String firstName,
required String lastName,
required int age,
}) = _Person;
factory Person.fromJson(Map<String, Object?> json)
=> _$PersonFromJson(json);
}
詳細
-
test.dart
ファイルを作成しPerson
クラスをコーディング -
part 'test.freezed.dart';
とpart 'test.g.dart';
のファイルを作成 -
インスタンス化(初期値の設定)する際に、新しいインスタンスを必ずしも返えさなくて良い
factory
コンストラクタを採用 -
プロパティを必須項目にする場合は型の前に
required
を置く(null非許容) -
fromJson
でJSON相互変換用のfactory
コンストラクタを作成
ジェネレーターを実行↓
test.dart
ファイルの並びにtest.freezed.dart
ファイルとtest.g.dart
ファイルが生成されました。
その他機能
- モデルで変更可能なプロパティを定義したい場合
@freezed
注釈を@unfreezed
に変える
@unfreezed
class Person with _$Person {
factory Person({
required String firstName,
required String lastName,
required final int age,
}) = _Person;
factory Person.fromJson(Map<String, Object?> json)
=> _$PersonFromJson(json);
}
- null許容型(元の型の値の変わりにnullの値を取れる型)
String? firstName,
- デフォルト値を設定
@Default('ume') String firstName,
-
@JsonKey
でメンバ変数名を変更する
@JsonKey(name: "first_name") String firstName,
- 非推奨で定義したい場合
@deprecated bool isName,
-
Assert
(メソッド外に定義されているメンバ変数"{"X"}"
の条件を定義)を利用し入ってきた値が空の場合はエラーを出す
abstract class Person with _$Person {
@Assert('firstName.isNotEmpty', 'firstNameプロパティはnullを引数に渡せません')
@Assert('lastName.isNotEmpty', 'lastName cannot be empty')
@Assert('age >= 0')
factory Person({
String? firstName,
String? lastName,
int? age,
}) = _Person;
}