9.1 不変オブジェクト

作成後に状態を変更できないオブジェクトです。

readonly class UserId
{
    public function __construct(
        public int $value
    ) {
    }
}

状態を変更する代わりに、新しい値を作ります。

旧状態 → 変換 → 新状態

不変性には次の利点があります。

状態変化を追いやすい
複数スレッドで共有しやすい
キャッシュしやすい
テストしやすい
予期しない変更を防げる

9.2 値オブジェクト

識別子ではなく、値そのものによって等価性が決まるオブジェクトです。

金額
メールアドレス
座標
日付範囲
ユーザーID
class Money {
  constructor(
    readonly amount: number,
    readonly currency: string
  ) {}
}

単なる文字列や数値ではなく、業務上の意味と制約を型に閉じ込めます。


9.3 副作用の局所化

理想的には、計算処理と外部作用を分離します。

入力取得
純粋な計算
結果保存

例えば価格計算自体は純粋関数にできます。

def calculate_total(price, quantity, tax_rate):
    subtotal = price * quantity
    return subtotal * (1 + tax_rate)

データベース保存は別にします。

total = calculate_total(price, quantity, tax_rate)
repository.save(total)