こんにちは。
今日はFlutterにて不変クラスを作成するツール「Freezed」についてまとめたいと思います。
まず「不変」って何?ってところからだったんですが、
Flutterでは一度作ったインスタンス(オブジェクト)のプロパティやフィールドが変更されることがないことを指しています。
そうすることで予期せぬ状態になることを防ぐことが出来ます。
仮にオブジェクトの状態を変更する必要がある場合は、新しいインスタンスを作成してその状態を変更します。
そしてFreezedはそんな不変クラスを簡単に作ることのできるDartのパッケージです。
後述するような規則に沿ったコード(設計書)を書き、コマンドを叩くことで、Freezedが不変クラス(プロパティやメソッド込み)を作ってくれます。
Freezedで実際に定義する際のコードが下記になります。
@freezed
class User with _$User {
const factory User({
required String name,
required int age,
}) = _User;
}
この定義ではUserクラスをfreezedで自動生成される_$Userクラスをミックスインしています。
要はUserクラスに自動生成される関数とかを取り込むよって書いてます。
ミックスインはDartのような単一継承しかできないプログラミング言語において、様々なクラスを取り込みたい時に使うキーワードでwithを用いることがその宣言になります。
そして次はfactoryですね。
こちらはファクトリコンストラクタといい、コンストラクタの一種なのですが、
オブジェクトの生成をより柔軟にすることができるツールです。
例えば条件に合う場合はAを返し、合わない場合はオブジェクトを作って返す、みたいなことが出来ます。
今回の場合は必須プロパティとしてnameとageを受け取り、_Userオブジェクトを返しています。
なぜファクトリになっているかというと、実際のインスタンス生成はFreezedで自動生成されるソースコードの方で行うからです。
では実際に定義したUserクラスでコードを自動生成してみます。
$ flutter pub run build_runner build
生成されたコードがとても長いので割愛します。
状態に関するメソッドとして
whenとmapが登場していたのでそちらをまとめますと、
whenはインスタンスのプロパティにアクセスしたいときに使います。
例えば、
user.when(
loading: () => 'ロード中',
data: (name, age) => '名前: $name, 年齢: $age',
error: (message) => 'エラー: $message',
);
みたいな感じです。
そしてmapはインスタンス自体にアクセスしたい時に使います。
user.map(
loading: (loadingState) => 'ロード中',
data: (dataState) => '名前: ${dataState.name}, 年齢: ${dataState.age}',
error: (errorState) => 'エラー: ${errorState.message}',
);
以上、Freezedを使っての不変クラス作成とメソッドのまとめでした。