Skip to content

Instantly share code, notes, and snippets.

@pwm
Last active April 10, 2018 21:09
Show Gist options
  • Save pwm/6217b8a55467ab10ac2770992acf0d39 to your computer and use it in GitHub Desktop.
Save pwm/6217b8a55467ab10ac2770992acf0d39 to your computer and use it in GitHub Desktop.
Immutable bidirectional reference
<?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