Side-Effect-Free Behavior

If we want to include some additional behavior — like an add method — in our Money class, it feels natural to check that the input fits any preconditions and maintains any invariance. In our case, we only wish to add monies with the same currency:

class Money 
{
// ...

public function add(Money $money)
{
if ($money->currency() !== $this->currency()) {
throw new InvalidArgumentException();
}

$this->amount += $money->amount();
}
}

If the two currencies don't match, an exception is raised. Otherwise, the amounts are added. However, this code has some undesirable pitfalls. Now imagine we have a mysterious method call to otherMethod in our code:

class Banking 
{
public function doSomething()
{
$aMoney = new Money(100, new Currency('USD'));


$this->otherMethod($aMoney);//mysterious call
// ...
}
}

Everything is fine until, for some reason, we start seeing unexpected results when we're returning or finished with otherMethod. Suddenly, $aMoney no longer contains 100 USD. What happened? And what happens if otherMethod internally uses our previously defined add method? Maybe you're unaware that add mutates the state of the Money instance. This is what we call a side effect. You must avoid generating side effects. You must not mutate your arguments. If you do, the developer using your objects may experience strange behaviors. They'll complain, and they'll be correct.

So how can we fix this? Simple — by making sure that the Value Object remains immutable, we avoid this kind of unexpected problem. An easy solution could be returning a new instance for every potentially mutable operation, which the add method does:

class Money 
{
// ...

public function add(Money $money)
{
if (!$money->currency()->equals($this->currency())) {
throw new InvalidArgumentException();
}

return new self(
$money->amount() + $this->amount(),
$this->currency()
);
}
}

With this simple change, immutability is guaranteed. Each time two instances of Money are added together, a new resulting instance is returned. Other classes can perform any number of changes without affecting the original copy. Code free of side effects is easy to understand, easy to test, and less error prone.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset