Last active
April 10, 2018 21:09
-
-
Save pwm/6217b8a55467ab10ac2770992acf0d39 to your computer and use it in GitHub Desktop.
Immutable bidirectional reference
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
// https://softwareengineering.stackexchange.com/questions/334305/how-to-model-a-circular-reference-between-immutable-objects-in-c | |
final class Department { | |
/** @var string */ | |
private $name; | |
/** @var Closure|User */ | |
private $user; | |
public function __construct(string $name, Closure $userResolver) { | |
$this->name = $name; | |
$this->user = $userResolver; | |
} | |
public function getName(): string { | |
return $this->name; | |
} | |
public function getUser(): User { | |
return $this->user; | |
} | |
public function resolveUser(User $user): self { | |
if ($this->user instanceof Closure) { | |
$this->user = $this->user->call($this, $user); | |
} | |
return $this; | |
} | |
} | |
final class User { | |
/** @var string */ | |
private $name; | |
/** @var Department */ | |
private $department; | |
public function __construct(string $name, Department $department) { | |
$this->name = $name; | |
$this->department = $department->resolveUser($this); | |
} | |
public function getName(): string { | |
return $this->name; | |
} | |
public function getDepartment(): Department { | |
return $this->department; | |
} | |
} | |
$department = new Department('IT', function (User $user) { | |
return $user; | |
}); | |
$user = new User('John', $department); | |
echo sprintf( | |
'User %s works in the %s department', | |
$department->getUser()->getName(), | |
$user->getDepartment()->getName() | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment