Реестр (англ. Registry) - данный шаблон предназначен для хранения записей, которые в него помещают и соответственно
возвращения этих записей (по ключу) если они потребуются.
Как на нормальном предприятии, когда у нас появляется новый работник - в бухгалтерии появляется новая запись с его данными. Журнал работников и есть Реестр, а каждый объект информации работника - запись в реестре. Реестр нередко является Одиночкой, однако это не всегда должно быть именно так. Например, мы можем заводить в бухгалтерии несколько журналов. В одном работники от “А” до “М”. В другом от “Н” до “Я”. Каждый такой журнал будет Реестром, но не Одиночкой, потому как журналов уже 2.
Примечание: Заметим что Реестр очень похож на Мультитон и Пул объектов. Сам шаблон Реестр не являются “порождающим шаблоном” в полном смысле этого термина, однако его удобно рассматривать именно во взаимосвязи с ними. В отличие от Мультитона и Пула, он не умеет порождать новые сущности. Реестр - это хранилище!
-
Registry.php
<?php namespace DesignPatterns\Structural\Registry; use InvalidArgumentException; /** * Class Registry * @package DesignPatterns\Structural\Registry */ class Registry { /** * @var WorkerData[] */ protected $workerDataRegistry = []; /** * @param string $key * @param WorkerData $workerData * * @return void * @throws InvalidArgumentException */ public function addWorker(string $key, WorkerData $workerData) { $key = $this->prepareKey($key); if (!key_exists($key, $this->workerDataRegistry)) { $this->workerDataRegistry[$key] = $workerData; } else { throw new InvalidArgumentException('Worker with key: #' . $key . ' exists.'); } } /** * @param string $key * * @return WorkerData */ public function getWorker(string $key) { $key = $this->prepareKey($key); if (key_exists($key, $this->workerDataRegistry)) { return $this->workerDataRegistry[$key]; } else { throw new \InvalidArgumentException('Worker with key: #' . $key . ' not exists.'); } } /** * @param string $key * * @return string */ private function prepareKey(string $key) { return trim(strtolower($key)); } }
-
WorkerData.php
<?php namespace DesignPatterns\Structural\Registry; /** * Class WorkerData * @package DesignPatterns\Structural\Registry */ class WorkerData { /** * @var string */ protected $firstName; /** * @var string */ protected $lastName; /** * @var string */ protected $fullName; /** * @var int */ protected $age; /** * @var string */ protected $phone; /** * WorkerData constructor. * * @param string $firstName * @param string $lastName * @param int $age * @param int $phone */ public function __construct(string $firstName, string $lastName, int $age, int $phone) { $this->firstName = $this->prepareName($firstName); $this->lastName = $this->prepareName($lastName); $this->fullName = $this->setFullName(); $this->age = $age; $this->phone = $phone; } /** * @return string */ public function getFirstName(): string { return $this->firstName; } /** * @param string $firstName * * @return void */ public function setFirstName(string $firstName) { $this->firstName = $firstName; } /** * @return string */ public function getLastName(): string { return $this->lastName; } /** * @param string $lastName * * @return void */ public function setLastName(string $lastName) { $this->lastName = $lastName; } /** * @return string */ public function getFullName(): string { return $this->fullName; } /** * @return string */ public function setFullName() { return $this->firstName . ' ' . $this->lastName; } /** * @return int */ public function getAge(): int { return $this->age; } /** * @param int $age * * @return void */ public function setAge(int $age) { $this->age = $age; } /** * @return string */ public function getPhone(): string { return $this->phone; } /** * @param string $phone * * @return void */ public function setPhone(string $phone) { $this->phone = $phone; } /** * @param string $name * * @return string */ private function prepareName(string $name) { return ucfirst(strtolower($name)); } }
Test case:
RegistryTest.php
<?php
namespace DesignPatterns\Tests\Structural\Registry;
use DesignPatterns\Structural\Registry\Registry;
use DesignPatterns\Structural\Registry\WorkerData;
use InvalidArgumentException;
class RegistryTest extends \PHPUnit_Framework_TestCase
{
private $ivanDataFixture = [
'firstName' => 'ivan',
'lastName' => 'ivanov',
'age' => 21,
'phone' => 380936547896,
];
private $petrDataFixture = [
'firstName' => 'petr',
'lastName' => 'petrov',
'age' => 18,
'phone' => 380668524785,
];
public function testCanSetUpWorkerToRegistry()
{
$ivanWorkerData = new WorkerData(
$this->ivanDataFixture['firstName'],
$this->ivanDataFixture['lastName'],
$this->ivanDataFixture['age'],
$this->ivanDataFixture['phone']
);
$petrWorkerData = new WorkerData(
$this->petrDataFixture['firstName'],
$this->petrDataFixture['lastName'],
$this->petrDataFixture['age'],
$this->petrDataFixture['phone']
);
$registry = new Registry();
$registry->addWorker('Ivan', $ivanWorkerData);
$registry->addWorker('Petr', $petrWorkerData);
$this->assertInstanceOf('DesignPatterns\Structural\Registry\WorkerData', $registry->getWorker('Ivan'));
$this->assertInstanceOf('DesignPatterns\Structural\Registry\WorkerData', $registry->getWorker('Petr'));
}
public function testException()
{
$this->expectException(InvalidArgumentException::class);
$registry = new Registry();
$ivanWorkerData = new WorkerData(
$this->ivanDataFixture['firstName'],
$this->ivanDataFixture['lastName'],
$this->ivanDataFixture['age'],
$this->ivanDataFixture['phone']
);
$petrWorkerData = new WorkerData(
$this->petrDataFixture['firstName'],
$this->petrDataFixture['lastName'],
$this->petrDataFixture['age'],
$this->petrDataFixture['phone']
);
$registry->addWorker('Ivan', $ivanWorkerData);
$registry->addWorker('Ivan', $petrWorkerData);
}
}