2.11. Registry (Registro)¶
2.11.1. Objetivo¶
Implementar um armazenamento centralizado para objetos frequentemente usados em toda a aplicação, é tipicamente implementado usando uma classe abstrata com apenas métodos estáticos (ou usando o padrão Singleton). Lembre que isto introduz em estado global, o qual deve ser evitado sempre! Em vez disso, implemente isto usando a Injeção de Dependência (Dependency Injection)!
2.11.2. Diagrama UML¶

2.11.3. Código¶
Você também pode encontrar este código no GitHub
Registry.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | <?php
declare(strict_types=1);
namespace DesignPatterns\Structural\Registry;
use InvalidArgumentException;
abstract class Registry
{
public const LOGGER = 'logger';
/**
* this introduces global state in your application which can not be mocked up for testing
* and is therefor considered an anti-pattern! Use dependency injection instead!
*
* @var Service[]
*/
private static array $services = [];
private static array $allowedKeys = [
self::LOGGER,
];
final public static function set(string $key, Service $value)
{
if (!in_array($key, self::$allowedKeys)) {
throw new InvalidArgumentException('Invalid key given');
}
self::$services[$key] = $value;
}
final public static function get(string $key): Service
{
if (!in_array($key, self::$allowedKeys) || !isset(self::$services[$key])) {
throw new InvalidArgumentException('Invalid key given');
}
return self::$services[$key];
}
}
|
Service.php
1 2 3 4 5 6 7 8 | <?php
namespace DesignPatterns\Structural\Registry;
class Service
{
}
|
2.11.4. Teste¶
Tests/RegistryTest.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | <?php
declare(strict_types=1);
namespace DesignPatterns\Structural\Registry\Tests;
use InvalidArgumentException;
use DesignPatterns\Structural\Registry\Registry;
use DesignPatterns\Structural\Registry\Service;
use PHPUnit\Framework\TestCase;
class RegistryTest extends TestCase
{
private Service $service;
protected function setUp(): void
{
$this->service = $this->getMockBuilder(Service::class)->getMock();
}
public function testSetAndGetLogger()
{
Registry::set(Registry::LOGGER, $this->service);
$this->assertSame($this->service, Registry::get(Registry::LOGGER));
}
public function testThrowsExceptionWhenTryingToSetInvalidKey()
{
$this->expectException(InvalidArgumentException::class);
Registry::set('foobar', $this->service);
}
/**
* notice @runInSeparateProcess here: without it, a previous test might have set it already and
* testing would not be possible. That's why you should implement Dependency Injection where an
* injected class may easily be replaced by a mockup
*
* @runInSeparateProcess
*/
public function testThrowsExceptionWhenTryingToGetNotSetKey()
{
$this->expectException(InvalidArgumentException::class);
Registry::get(Registry::LOGGER);
}
}
|