DateTimeImmutable
. Below, we will see that if you make simple objects immutable, this will help avoid certain errors and save a lot of time.final
so that it cannot be overridden when adding methods that change the internal state.private
so that they cannot be changed again. <?php final class Address { private $city; private $house; private $flat; public function __construct($city, $house, $flat) { $this->city = (string)$city; $this->house = (string)$house; $this->flat = (string)$flat; } public function getCity() { return $this->city; } public function getHouse() { return $this->house; } public function getFlat() { return $this->flat; } }
Money
, which represents a certain amount of money. <?php class Money { private $amount; public function getAmount() { return $this->amount; } public function add($amount) { $this->amount += $amount; return $this; } }
<?php $userAmount = Money::USD(2); /** * 2 . 3%, * . */ $processedAmount = $userAmount->add($userAmount->getAmount() * 0.03); /** * 2 + 3% */ $markCard->withdraw($processedAmount); /** * 2 */ $alexCard->deposit($userAmount);
Money
class is changeable, instead of two dollars, Alex will receive $ 2 and 6 cents (3% commission). The reason is that $userAmount
and $processedAmount
refer to the same object. In this case, it is recommended to use an immutable object. <?php final class Money { private $amount; public function getAmount() { return $this->amount; } }
<?php $userAmount = Money::USD(2); $commission = $userAmount->val() * 3 / 100; $processedAmount = Money::USD($userAmount->getAmount() + $commission); $markCard->withdraw($processedAmount); $alexCard->deposit($userAmount);
<?php final class Money { private $amount; public function getAmount() { return $this->amount; } public function add($amount) { return new self($this->amount + $amount, $this->currency); } }
<?php $userAmount = Money::USD(2); /** * 2 . 3%, * . */ $processedAmount = $userAmount->add($userAmount->val() * 0.03); /** * 2 + 3% */ $markCard->withdraw($processedAmount); /** * 2 */ $alexCard->deposit($userAmount);
<?php class MutableX { protected $y; public function setY($y) { $this->y = $y; } } class Immutable { protected $x; public function __construct($x) { $this->x = $x; } public function getX() { return $this->x; } }
<?php $immutable = new Immutable(new MutableX()); var_dump(md5(serialize($immutable))); // f48ac85e653586b6a972251a85dd6268 $immutable->getX(); var_dump(md5(serialize($immutable))); // f48ac85e653586b6a972251a85dd6268
<?php $immutable->getX()->setY(5); var_dump(md5(serialize($immutable))); // 8d390a0505c85aea084c8c0026c1621e
<?php class Collection { protected $elements = []; public function __construct(array $elements) { $this->elements = $elements; } public function add($element) { $this->elements[] = $element; } public function get($key) { return isset($this->elements[$key]) ? $this->elements[$key] : null ; } }
<?php $immutable = new Immutable(new Collection([new XMutable(), new XMutable()])); var_dump(md5(serialize($immutable))); // 9d095d565a96740e175ae07f1192930f $immutable->getX(); var_dump(md5(serialize($immutable))); // 9d095d565a96740e175ae07f1192930f $immutable->getX()->get(0)->setY(5); var_dump(md5(serialize($immutable))); // 803b801abfa2a9882073eed4efe72fa0
<?php $immutable = new Immutable(new Collection([1, 2])); var_dump(md5(serialize($immutable))); // 24f1de7dc42cfa14ff46239b0274d54d $immutable->getX(); var_dump(md5(serialize($immutable))); // 24f1de7dc42cfa14ff46239b0274d54d $immutable->getX()->add(10); var_dump(md5(serialize($immutable))); // 70c0a32d7c82a9f52f9f2b2731fdbd7f
Immutable
class to accept only Immutable
objects. <?php class Immutable { protected $x; public function __construct(Immutable $x) { $this->x = $x; } public function getX() { return $this->x; } }
<?php class Mutant extends Immutable { public function __construct() { } public function getX() { return rand(1, 1000000); } public function setX($x) { $this->x = $x; } }
<?php $mutant = new Mutant(); $immutable = new Immutable($mutant); var_dump(md5(serialize($immutable->getX()->getX()))); // c52903b4f0d531b34390c281c400abad var_dump(md5(serialize($immutable->getX()->getX()))); // 6c0538892dc1010ba9b7458622c2d21d var_dump(md5(serialize($immutable->getX()->getX()))); // ef2c2964dbc2f378bd4802813756fa7d var_dump(md5(serialize($immutable->getX()->getX()))); // 143ecd4d85771ee134409fd62490f295
final
so that they cannot be expanded.final
so that it cannot be overridden when adding methods that change the internal state.private
so that they cannot be changed again.Source: https://habr.com/ru/post/301004/
All Articles