Closed9
DDDの値オブジェクトを説明するのに年齢を例にすると分かりやすいかも
プリミティブな値で実装する問題
- 不正な値を代入できてしまう
- マイナスの値
- 少数
- 不正な値を持たないようにする処理が散在してしまう
- 不要な振る舞いができてしまう
- 四則演算など
- ドメインロジックが散在してしまう
- 例:成年かどうかのロジックはどこに書く?
不正な値を存在させない
コンストラクター内で不正な値を生成しようとする場合にエラーを投げるようにする
これで生成された Age オブジェクトは必ず不正な値ではないことが確立できる
class Age {
public constructor(value: number) {
if (!Number.isInteger(value)) throw new Error();
if (value < Age.MIN_VALUE) throw new Error();
this.value = value;
}
private readonly value: number;
private static readonly MIN_VALUE: number = 0;
}
不要な振る舞いを定義しない
プリミティブな値をクラスでラップしているので、年齢オブジェクトとしては不要な値の操作を禁じることが可能
不要な操作が起きないので、安全に値を扱いやすくなる
const age = new Age(20);
age + 1; // Error
必要なドメインロジックを持たせられる
class Age {
public isAdult(): boolean {
return this.value > 18;
}
}
永続化
ドメインオブジェクトをそのまま永続化する必要はない例として
年齢は生年月日からある特定の日時(大体は現在日時)から計算される
年齢オブジェクトにファクトリーメソッドを生やして、生年月日オブジェクトから計算して生成させる
class Age {
public static valueOf(birthday: Birthday): Age {
// 計算して返す
}
}
永続化する際は生年月日オブジェクトを永続化して、取得する際に再生成させる
バリデーションはどこに書く?
結論としては必要なレイヤーで必要な分だけ
- ドメイン層
- ドメインオブジェクトとして必要な検証
- 前述のコンストラクター内で不正な値を生成させないようにする
- 上限値については(業務領域によって変化しそうだが)、寿命はさておき基本的にはないことがおおい
- アプリケーション層
- アプリケーションとして扱うことができる値かどうか
- 言語使用によって取りえる整数の最大値が上限
- UI 層
- 入力補助としてのバリデーション
- 上限値をもってもいいかもというところ
- 寿命的に200歳以上は入力ミスだろうとしてもいいところ
このスクラップは2024/05/21にクローズされました