【Flutter】flutter(dart)でValueObject
はじめに
ドメインを表現するために、ValueObjectを作ることがあります。
ValueObjectについては以前概要についての記事を書いているのですが、実際にFlutterで開発するときにどのようにしてValueObjectを作るのかを紹介していきたいと思います。
ValueObject(値オブジェクト)とは
ValueObjectについては、この記事で書いています。
システム固有のプリミティブ型(数値や文字列など)のようなものがValueObjectです。
ValueObjectは不変なので、オブジェクトの中身の変化を考慮しなくていいようになります。
FlutterでValueObject
FlutterでValueObjectのクラスを作る場合は、プロパティを読み取り専用にして、イミュータブルなクラスになるようにします。また等価性の比較メソッドなどを追加する必要があります。
ただ、freezedパッケージを使用することで、ValueObjectを簡単に作成することができます。
※freezedは不変のデータクラスを簡単に作成できるパッケージです。
以下、「名前(FullName)」のValueObjectになります。
@freezed
class FullName with _$FullName {
@Assert('firstName.isNotEmpty', 'ファーストネームが入力されていません')
@Assert('lastName.isNotEmpty', 'ラストネームが入力されていません')
factory FullName({
required String firstName,
required String lastName,
}) = _FullName;
}
ValueObjectの中には、firstName、 lastNameの値があります。
これらの値が不変になるようにfreezedを使用して不変のデータクラスにしています。
また、FullNameにドメインのルールを追加するために@Assertのアノテーションを使用しています。
@Assertを使用すると、ValueObject生成時に渡された値が不正な場合は、例外を起こすことができます。
例では名前が空白な人はいないので、空文字などが渡された場合は、例外を起こすようにしています。
freezedを使用しているので、等価の比較をするときは以下のように書くことができます。
void execute() {
try {
final fullName1 = FullName(firstName: '太郎', lastName: '田中');
final fullName2 = FullName(firstName: '太郎', lastName: '田中');
print("fullName1 == fullName2");
print(fullName1 == fullName2); // true
} catch (e) {
print(e.toString());
}
}
また、ValueObjectでクラス内に関数を用意したり、拡張関数などを使用して、ドメインの振る舞いを表現します。
@freezed
class Money with _$Money {
factory Money(int value) = _Money;
}
extension MoneyExtension on Money {
Money add(Money money) {
return Money(value + money.value);
}
}
このようにすることで、このValueObjectがどのような動作をするのかわかるようになり、仕様がコードで表現されるようになります。
まとめ
今回は、Flutter(dart)でValueObjectを作ってみました。開発の中で実際に使っていくようなコードや内容を書いていきたいと思います。
この記事が気に入ったらサポートをしてみませんか?