Mutating nullable composites

final class User
{
private $emailAddress;
private $name;
public function getEmailAddress(): EmailAddress
{
return $this->emailAddress;
}
public function getName(): Name
{
return $this->name;
}
public function withName(Name $name): User
{
$native = $this->toNative();
$native['name'] = $name->toNative();
return self::fromNative($native);
}
}
$newName = new Name('Ben Sisko');
$user = $user->withName($newName);

Making it nullable

If we wanted to make User nullable, we could follow the null object pattern. First, we use an interface to define the type.

interface User
{
public function getEmailAddress(): EmailAddress;
public function getName(): Name;
}
final class NonNullUser implements User
{
...
final class NullUser implements User
{
public function getEmailAddress(): EmailAddress
{
return new NullEmailAddress;
}

public function getName(): Name
{
return new NullName;
}
}

Mutating the null

To mutate the nullable, we need to add the mutation method to the User public interface.

interface User
{
...
public function withName(Name $name): User;
}
final class NullUser implements User
{
...
public function withName(Name $name): User
{
if ($name instanceof NullName) {
return new self;
}
return NonNullUser(
new NullEmailAddress,
$name
);
}
}

--

--

Software engineer

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store