From f6e0fe38bcb61bfd3ff5d84133969479df89c79d Mon Sep 17 00:00:00 2001 From: Peter Gribanov Date: Tue, 29 Aug 2017 19:41:38 +0300 Subject: [PATCH 1/3] Singleton is a anti-pattern --- README.md | 65 ++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index eb072e6..24da54d 100644 --- a/README.md +++ b/README.md @@ -512,35 +512,64 @@ Polluting globals is a bad practice in very languages because you could clash wi library and the user of your API would be none-the-wiser until they get an exception in production. Let's think about an example: what if you wanted to have configuration array. You could write global function like `config()`, but it could clash with another library -that tried to do the same thing. This is why it -would be much better to use singleton design pattern and simple set configuration. +that tried to do the same thing. **Bad:** ```php -function config() { +function config() +{ return [ - 'foo': 'bar', + 'foo' => 'bar', ] } ``` **Good:** -```php -class Configuration { - private static $instance; - private function __construct($configuration) {/* */} - public static function getInstance() { - if (self::$instance === null) { - self::$instance = new Configuration(); - } - return self::$instance; - } - public function get($key) {/* */} - public function getAll() {/* */} -} -$singleton = Configuration::getInstance(); +Create configuration file + +```php +// config.php +return [ + 'foo' => 'bar', +]; ``` + +Or a [YAML](https://en.wikipedia.org/wiki/YAML) configuration file + +```php +// config.yml +configuration: + foo: 'bar' +``` + +Or something else + +```php +class Configuration +{ + private $configuration = []; + + public function __construct(array $configuration) + { + $this->configuration = $configuration; + } + + public function get($key) + { + return isset($this->configuration[$key]) ? $this->configuration[$key] : null; + } +} +``` + +Load configuration from file and create instance of `Configuration` class + +```php +$configuration = new Configuration($configuration); +``` + +And now you must use instance of `Configuration` in your application. + **[⬆ back to top](#table-of-contents)** ### Encapsulate conditionals From 3c0c05e032c3194ec87a5dce46e637d078a52d54 Mon Sep 17 00:00:00 2001 From: Peter Gribanov Date: Wed, 30 Aug 2017 10:45:54 +0300 Subject: [PATCH 2/3] add bad singleton example and remove YAML config --- README.md | 45 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 24da54d..e029953 100644 --- a/README.md +++ b/README.md @@ -515,6 +515,7 @@ You could write global function like `config()`, but it could clash with another that tried to do the same thing. **Bad:** + ```php function config() { @@ -524,9 +525,41 @@ function config() } ``` +**Bad too:** + +Singleton is a [anti-pattern](https://en.wikipedia.org/wiki/Singleton_pattern). + +```php +class Configuration +{ + private static $instance; + + private function __construct($configuration) + { + // ... + } + + public static function getInstance() + { + if (self::$instance === null) { + self::$instance = new Configuration(); + } + + return self::$instance; + } + + public function get($key) + { + // ... + } +} + +$singleton = Configuration::getInstance(); +``` + **Good:** -Create configuration file +Create PHP configuration file or something else ```php // config.php @@ -535,16 +568,6 @@ return [ ]; ``` -Or a [YAML](https://en.wikipedia.org/wiki/YAML) configuration file - -```php -// config.yml -configuration: - foo: 'bar' -``` - -Or something else - ```php class Configuration { From 19b95ac77d9a726b52fc04d4e48671d3f7195d62 Mon Sep 17 00:00:00 2001 From: Peter Gribanov Date: Wed, 30 Aug 2017 18:47:04 +0300 Subject: [PATCH 3/3] add section: Don't use a Singleton pattern --- README.md | 86 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 54 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index e029953..95e2244 100644 --- a/README.md +++ b/README.md @@ -525,38 +525,6 @@ function config() } ``` -**Bad too:** - -Singleton is a [anti-pattern](https://en.wikipedia.org/wiki/Singleton_pattern). - -```php -class Configuration -{ - private static $instance; - - private function __construct($configuration) - { - // ... - } - - public static function getInstance() - { - if (self::$instance === null) { - self::$instance = new Configuration(); - } - - return self::$instance; - } - - public function get($key) - { - // ... - } -} - -$singleton = Configuration::getInstance(); -``` - **Good:** Create PHP configuration file or something else @@ -595,6 +563,60 @@ And now you must use instance of `Configuration` in your application. **[⬆ back to top](#table-of-contents)** +### Don't use a Singleton pattern +Singleton is a [anti-pattern](https://en.wikipedia.org/wiki/Singleton_pattern). + +**Bad:** + +```php +class DBConnection +{ + private static $instance; + + private function __construct($dsn) + { + // ... + } + + public static function getInstance() + { + if (self::$instance === null) { + self::$instance = new self(); + } + + return self::$instance; + } + + // ... +} + +$singleton = DBConnection::getInstance(); +``` + +**Good:** + +```php +class DBConnection +{ + public function __construct(array $dsn) + { + // ... + } + + // ... +} +``` + +Create instance of `DBConnection` class and configure it with [DSN](http://php.net/manual/en/pdo.construct.php#refsect1-pdo.construct-parameters). + +```php +$connection = new DBConnection($dsn); +``` + +And now you must use instance of `DBConnection` in your application. + +**[⬆ back to top](#table-of-contents)** + ### Encapsulate conditionals **Bad:**