Mengikuti artikel saya sebelumnya tentang objek nilai,
Kekekalan sering dianggap sebagai aspek inti dari objek nilai. Ada alasan bagus untuk hal ini, namun kekekalan bukanlah hal yang membuat suatu objek menjadi objek nilai. Yang penting adalah kesetaraan berdasarkan nilai, bukan status.
Artinya, dalam banyak kasus, invarian masuk akal untuk konsep domain. Kembali ke contoh takeaway dari artikel terakhir saya dan objek nilai jarak untuk radius DeliveryArea. Jika wilayah pengiriman diperluas, jarak baru akan tercapai, dan jarak itu sendiri tidak akan berubah. Kalau radiusnya 5 kilometer dan bertambah menjadi 8 kilometer maka beda jaraknya, 5 kilometer tetap 5 kilometer, hanya saja radiusnya sekarang menjadi 8 kilometer.
Padahal kalau dipikir-pikir seperti ini, DeliveryArea sendiri merupakan area pengiriman yang berbeda jika kita mengubah jaraknya. Oleh karena itu, masuk akal untuk mengatur properti area pengiriman Takeaway ke DeliveryArea baru daripada mengubah DeliveryArea yang ada.
Jadi bagaimana kita mencapainya? Namun, objek-objek ini tidak dapat diubah. Mereka dibangun dengan nilai-nilai, dan tidak ada cara untuk mengubah nilai-nilai tersebut dari luar. Kita tidak hanya membutuhkan perubahan jarak, namun peningkatan jarak. Misal jaraknya 5 kilometer, kita mau tambah 1 kilometer. Kita bisa melakukan ini di luar objek nilai dengan mendapatkan nilainya saat ini, menambahkan nilai, dan kemudian membuat nilai baru. Kita dapat menyederhanakan proses ini dengan memberi tahu objek apa yang ingin Anda tambahkan, dan objek tersebut akan mengembalikan objek baru dengan total:
class Distance
{
private $quantity;
private $unit;
public function __construct($quantity, $unit)
{
$this->quantity = $quantity;
$this->unit = $unit;
}
public function equals(Distance $toCompare)
{
return $this->quantity == $toCompare->quantity
&& $this->unit == $toCompare->unit;
}
public function add(Distance $toAdd)
{
if ($this->unit != $toAdd->unit) {
throw new \RuntimeException(
'Cannot add distances with different units'
);
}
return new Distance(
$this->quantity + $toAdd->quantity,
$this->unit
);
}
}
Terkadang suatu objek mungkin tidak dapat diubah dari segi domain, namun kendala teknis berarti objek tersebut sebenarnya tidak dapat diubah. Hal ini terjadi ketika konstruksi perlu dilakukan melalui metode setter agar dapat diintegrasikan dengan konten lain, seperti cara kerangka membangun objek dari suatu bentuk. Meskipun kami ingin tetap terpisah dari kerangka kerja, objek nilai masih dapat digunakan pada batas antara model dan kerangka kerja. Dalam hal ini, mungkin masuk akal untuk membuatnya bervariasi untuk menghindari lompatan melewati rintangan. Itu masih dapat dianggap tidak dapat diubah dalam model domain.