システムに最適な値が必ずしもプリミティブな値とは限らない。システム固有の値を「値オブジェクト」と呼ぶ
class FullName
{
public FullName(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
}
public string FirstName{get;}
public string LastName{get;}
}値の性質
不変である
"こんにちわ".ChangeTo("Hello"); //本来存在しないメソッド
Console.WriteLine("こんにちわ"); // Helloが表示される交換が可能である
「変更」ではなく「交換」する
// NG
var fullName = new FullName("masanobu", "naruse")
fullName.changeName("masanobu", "sato")
// OK
var fullName = new FullName("masanobu", "naruse")
fullName = new FullName("masanobu", "sato")等価性によって比較される
等価性は値オブジェクトの属性で比較するのではなく、値オブジェクト自身で比較する
var nameA = new FullName("masanobu", "naruse");
var nameB = new FullName("masanobu", "sato");
// NG
var compareResult = nameA.FirstName == nameB.FirstName
&& nameA.LastName == nameB.LastName;
// OK
compareResult = nameA.Equals(nameB);ふるまい
値オブジェクトには振る舞いをもたせられる。
ふるまいをもたせると、そのオブジェクトができることがわかる = 仕様がわかる
class Money
{
private readonly decimal amount;
private readonly string currency;
︙
public Money Add(Money arg) {
if (arg == null) throw new ArgumentNullException(nameof (arg));
if (currency != arg.currency) throw new ArgumentException("通貨単位が異なります")
return new Money(amount + arg.amount, currency)
}
}