registry Реестр (англ. 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);
        }
    }