From 87f8eb1983244c1cddf731f6b0ef26c6e1626e66 Mon Sep 17 00:00:00 2001 From: Dominik Liebler Date: Mon, 26 Aug 2019 06:18:51 +0200 Subject: [PATCH] refactored Registry pattern --- Structural/Registry/Registry.php | 25 ++++++--------------- Structural/Registry/Service.php | 9 ++++++++ Structural/Registry/Tests/RegistryTest.php | 24 ++++++++++++-------- Structural/Registry/uml/uml.png | Bin 4658 -> 20675 bytes 4 files changed, 31 insertions(+), 27 deletions(-) create mode 100644 Structural/Registry/Service.php diff --git a/Structural/Registry/Registry.php b/Structural/Registry/Registry.php index b700826..b7c640b 100644 --- a/Structural/Registry/Registry.php +++ b/Structural/Registry/Registry.php @@ -10,9 +10,9 @@ abstract class Registry * 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 array + * @var Service[] */ - private static $storedValues = []; + private static $services = []; /** * @var array @@ -21,32 +21,21 @@ abstract class Registry self::LOGGER, ]; - /** - * @param string $key - * @param mixed $value - * - * @return void - */ - public static function set(string $key, $value) + public static function set(string $key, Service $value) { if (!in_array($key, self::$allowedKeys)) { throw new \InvalidArgumentException('Invalid key given'); } - self::$storedValues[$key] = $value; + self::$services[$key] = $value; } - /** - * @param string $key - * - * @return mixed - */ - public static function get(string $key) + public static function get(string $key): Service { - if (!in_array($key, self::$allowedKeys) || !isset(self::$storedValues[$key])) { + if (!in_array($key, self::$allowedKeys) || !isset(self::$services[$key])) { throw new \InvalidArgumentException('Invalid key given'); } - return self::$storedValues[$key]; + return self::$services[$key]; } } diff --git a/Structural/Registry/Service.php b/Structural/Registry/Service.php new file mode 100644 index 0000000..e4204c8 --- /dev/null +++ b/Structural/Registry/Service.php @@ -0,0 +1,9 @@ +service = $this->getMockBuilder(Service::class)->getMock(); + } + public function testSetAndGetLogger() { - $key = Registry::LOGGER; - $logger = new stdClass(); + Registry::set(Registry::LOGGER, $this->service); - Registry::set($key, $logger); - $storedLogger = Registry::get($key); - - $this->assertSame($logger, $storedLogger); - $this->assertInstanceOf(stdClass::class, $storedLogger); + $this->assertSame($this->service, Registry::get(Registry::LOGGER)); } public function testThrowsExceptionWhenTryingToSetInvalidKey() { $this->expectException(\InvalidArgumentException::class); - Registry::set('foobar', new stdClass()); + Registry::set('foobar', $this->service); } /** diff --git a/Structural/Registry/uml/uml.png b/Structural/Registry/uml/uml.png index 9f92dcb0620313775cf8743aafc87ea6a62b326c..c5576512591d0154152abd491b8ea9567dc45e03 100644 GIT binary patch literal 20675 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 E)Up%-imrI) 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 F{s)tYF^~WN