DDDでいうValue ObjectをRubyで実装するときに使えるイディオムを紹介します。
手順
- Structを作り、freezeする
例
class Equipment < Struct.new(:place, :name)
def initialize(*args)
super
freeze
end
end
kagi = Equipment.new('玄関', '鍵')
説明
短い記述ですが、Value Objectに便利な以下の特性が得られます。
- 不変オブジェクトになる。
- Constructorが自動で定義される。
- 各メンバのreaderが自動で定義される。
- ==, hash などの比較関数が、各メンバの値を使った実装として定義される。
比較関数が、各メンバの値の比較として定義されるため、Value Object自体をハッシュのキーにも使えるようになるのがすごく便利です。これと同じことを自前のクラスで実装しようとすると、== と hashを自前で実装する必要があります。
Rubyは変数の型を定義できないので、メンバーに何がセットされるかを制御できないのが残念ですが、不変オブジェクトを使えるだけでも大きなメリットがあります。
以上です。