Design Patterns in PHP 8: Prototype
Tags: php, webdev, programming, oop
Published: 2022-07-31 12:40:00

Hello, fellow developers!🧑🏼‍💻

Design pattern Prototype give us control of making clones of objects. In php syntax, we have a special keyword/command `clone` for making an object's copy. But it does not allow you to clone correctly some parameters that are implementations of other classes.

I propose to consider an example that can be encountered when developing a blog or an online publication. On such resources, one of the main entities is the Page, which, of course, has an author.

Let's implement this. The author will have, of course, a name, as well as the list of pages of this author. In this case, the list will contain not just an id, but a full-fledged page object.
```php
class Author
{
    public function __construct(
        public readonly string $name,
        private array $pages = []
    ) {}

    public function addPage(Page $page): void
    {
        $this->pages[] = $page;
    }

    public function getPages(): array
    {
        return $this->pages;
    }
}
```
Also, each page must have an author property that implements the Author class, in addition to other necessary data.
```php
class Page
{
    public function __construct(
        private string $title,
        private string $body,
        public readonly Author $author,
        private array $comments = [],
        private \DateTime $date = new \DateTime()
    ) {
        $this->author->addPage($this);
    }

    public function getTitle(): string
    {
        return $this->title;
    }

    public function setTitle(string $title): void
    {
        $this->title = $title;
    }

    public function getBody(): string
    {
        return $this->body;
    }

    public function setBody(string $body): void
    {
        $this->body = $body;
    }

    public function getComments(): array
    {
        return $this->comments;
    }

    public function addComment(string $comment): void
    {
        $this->comments[] = $comment;
    }

    public function getDate(): \DateTime
    {
        return $this->date;
    }
}
```
Now, with such a structure, cloning pages becomes not an easy task for PHP. And this may well be necessary if the author wants to make a copy of his article, which in the future will publish a new one based on it. It is for this situation that the Prototype template exists, which allows you to configure exactly how to clone complex objects.

Let's add an implementation of the magic cloning method to the Page class, in which we will describe exactly how we need to clone objects of this class.
```php
public function __clone()
{
    $this->title = "Copy of " . $this->title;
    $this->author->addPage($this);
    $this->comments = [];
    $this->date = new \DateTime();
}
```
Of course, we can implement more complex logic in the method. In practice, the Page can refer to more other objects in its properties. In such a case, the Prototype can be a very useful approach.

-----

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!