Design Patterns in PHP 8: alternative implementations
Tags: php, webdev, programming, oop
Published: 2022-07-22 17:16:00

Hello, fellow developers!🧑🏼‍💻

In the [previous article](https://dev.to/zhukmax/design-patterns-in-php-8-singleton-multiton-5d99), I showed examples of implementing the design patterns Singleton and Multiton using inheritance. This is a fairly convenient approach, provided that we have several simple classes in the project that implement just a few methods and require a single instance in all places where these methods are called.

The php language only allows single inheritance, and this may be the reason why the variant from the last article will complicate or even break the architecture of our application. Therefore, I propose to consider other options for implementing the patterns.

Often, the correct solution is to implement the pattern in every class that requires it.
```php
class Database
{
    private static self|null $instance = null;

    final private function __construct(){}
    final private function __clone(){}
    final private function __wakeup(){}

    public static function getInstance(): self
    {
        if (self::$instance === null) {
            self::$instance = new self;
        }

        return self::$instance;
    }

    public function connect()
    {
        // ...
    }
}

$db = Database::getInstance();
$db->connect();
```

An alternative would be to use traits. This option is suitable if the project has several classes and you want to extract part of the repeating code in order to comply with the DRY principle.
```php
trait MultitonTrait
{
    private static array|null $instance = null;

    public static function getInstance(int|string $key): self
    {
        if (!array_key_exists($key, self::$instance)) {
            self::$instance[$key] = new self;
        }

        return self::$instance[$key];
    }
}

class Database
{
    use MultitonTrait;

    final private function __construct(){}
    final private function __clone(){}
    final private function __wakeup(){}

    public function connect()
    {
        // ...
    }
}

$db = Database::getInstance('mysql');
$db->connect();
```

All options from this article and the previous one have both their pros and cons, so the best solution should be chosen based on the architecture of a particular project.

-----

P.S. Fellow developers, if you've found value in this article and are eager to deepen your understanding of design patterns in PHP and TypeScript, I have thrilling news for you! I am in the midst of crafting a comprehensive book that delves extensively into these topics, filled with practical examples, lucid explanations, and real-world applications of these patterns.

This book is being designed to cater to both novices and seasoned developers, aiming to bolster your understanding and implementation of design patterns in PHP and TypeScript. Whether you are aiming to refresh your existing knowledge or venture into new learning territories, this book is your perfect companion.

Moreover, your subscription will play a pivotal role in supporting the completion of this book, enabling me to continue providing you with quality content that can elevate your coding prowess to unprecedented heights.

I invite you to subscribe to my blog on [dev.to](https://dev.to/zhukmax) for regular updates. I am eager to embark on this journey with you, helping you to escalate your coding skills to the next level!