🦓

[Flutter]Freezedでデータクラスを作る

2023/12/24に公開

はじめに

Freezedを使ってデータクラスを作っていきます。
https://pub.dev/packages/freezed

Freezed

freezedは、不変な(immutable)データクラスを簡単に作成するためのDartパッケージです。freezedを使用すると、イミュータブルなデータクラスを生成する際に必要なコードを生成してくれます。

また、データクラスにはこちらのメソッドが含まれています。
toString() メソッド
== 演算子
hasCode ゲッター変数
copyWith() メソッド
toJson() メソッド

Freezedを使わないで手動でクラスとメソッドを実装することもできますが、
ただし、クラスが増えるとミスが発生しやすくなるというデメリットがあります。
freezedを使用することで、これらのメソッドの自動生成が可能になり、コードがより使いやすくなります。

tl;dr

  1. Freezedをインストールする
  2. クラスを定義する
  3. コンストラクターを定義する
  4. フィールドやデコレーターを定義する
  5. JSONデータからクラスオブジェクトを生成する
  6. データクラスをビルドする

Freezedをインストールする

pubspec.yamlファイルにこちらのパッケージ追加します。

dependencies:
  freezed_annotation: ^2.4.1
  
dev_dependencies:
  freezed: ^2.4.6
  build_runner: ^2.4.7
  json_serializable: ^6.7.1

flutter pub getコマンドを実行してインストールします。

クラスを定義する

まずは必要なファイルをインポートします。

lib/model/user.dart
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:flutter/foundation.dart';

// まだ作成されてない
part 'user.freezed.dart';
part 'user.g.dart';

freezedのアノテーションを使用してデータクラスとスーパークラスを定義します。

lib/model/user.dart

class User with _$User {
}

freezed@freezedアノテーションは、このクラスがfreezedであることを示します。

コンストラクターを定義する

constファクトリー・コンストラクタを使い、クラスと同じ名前のクラスを指定する。
唯一の違いは、このクラスがアンダースコアを持っています。

lib/model/user.dart

class User with _$User {
  const factory User ({}) = _User;
}

フィールドやデコレーターを定義する

コンストラクターにフィールドやプロパティを指定します。
この部分はfreezedが処理するので、this.構文を使う必要はないです。

lib/model/user.dart

class User with _$User {
  const factory User ({
    required String id,
    required String name,
    required String email,
    required String password,
    required String profileImage,
    required String createdAt,
    required String updatedAt,
    String? deletedAt,
    (false) bool isAdmin,
  }) = _User;
}

JSONデータからクラスオブジェクトを生成する

lib/model/user.dart

class User with _$User {
  const factory User ({
    required String id,
    required String name,
    required String email,
    required String password,
    required String profileImage,
    required String createdAt,
    required String updatedAt,
    String? deletedAt,
    (false) bool isAdmin,
  }) = _User;
  
  factory User.fromJson(Map<String, Object> json)=> _$UserFromJson(json);
}

JSONデータからUserオブジェクトを生成するためのfromJsonファクトリコンストラクタを使ってます。
通常、ファクトリコンストラクタは同じクラスのインスタンスを返しますが、内部的には任意のロジックを持つことができます。

(Map<String, Object> json): パラメータリスト。JSONデータが渡されることを期待し、その型はMap<String, Object>です。この型は、JSONデータのキーが文字列で、値がどんな型でも良いことを示しています。

_$UserFromJsonは通常、freezedがJSONデータからオブジェクトを生成するために自動生成する関数です。

この行は、JSONとDartのオブジェクト間でデータを変換するために一般的に使用されます。
例えば、ネットワークからのデータの受け取りや、データの永続化などで利用されます。

データクラスをビルドする

ビルドコマンドを実行します。
--delete-conflicting-outputsオプションは、出力ディレクトリの衝突した出力を削除するためのものです。

flutter pub run build_runner build --delete-conflicting-outputs
Deprecated. Use `dart run` instead.
[INFO] Generating build script completed, took 379ms
[INFO] Reading cached asset graph completed, took 113ms
[INFO] Checking for updates since last build completed, took 952ms
[INFO] Running build completed, took 2.7s
[INFO] Caching finalized dependency graph completed, took 71ms
[INFO] Succeeded after 2.8s with 61 outputs (119 actions)

user.freezed.dartuser.g.dartを作成されたことを確認します。
クラスを編集することがあると思いますが、編集するたびにコマンドを再実行すれば大丈夫です。

終わりに

Freezedを使ってデータクラスを作る手順をまとめてみました。

Discussion